Skip to content

inspect.signature does not work for datetime classes #88784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
mauvilsa mannequin opened this issue Jul 13, 2021 · 8 comments
Open

inspect.signature does not work for datetime classes #88784

mauvilsa mannequin opened this issue Jul 13, 2021 · 8 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@mauvilsa
Copy link
Mannequin

mauvilsa mannequin commented Jul 13, 2021

BPO 44618
Nosy @gvanrossum, @hongweipeng, @mauvilsa
PRs
  • bpo-40897:Give priority to using the current class constructor in inspect.signature #27177
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2021-07-13.07:41:18.210>
    labels = ['type-bug', '3.8', '3.9', '3.10', '3.7', 'library']
    title = 'inspect.signature does not work for datetime classes'
    updated_at = <Date 2021-07-17.09:51:41.720>
    user = 'https://github.com/mauvilsa'

    bugs.python.org fields:

    activity = <Date 2021-07-17.09:51:41.720>
    actor = 'mauvilsa'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2021-07-13.07:41:18.210>
    creator = 'mauvilsa'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 44618
    keywords = ['patch']
    message_count = 6.0
    messages = ['397387', '397481', '397484', '397488', '397713', '397715']
    nosy_count = 3.0
    nosy_names = ['gvanrossum', 'hongweipeng', 'mauvilsa']
    pr_nums = ['27177']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue44618'
    versions = ['Python 3.6', 'Python 3.7', 'Python 3.8', 'Python 3.9', 'Python 3.10']

    @mauvilsa
    Copy link
    Mannequin Author

    mauvilsa mannequin commented Jul 13, 2021

    Classes in the datetime module are implemented using __new__ with some named parameters. I want to be able to inspect their signature to know which are the names of the parameters it accepts like it works for most classes. However, this does not work for classes in the datetime module. I already mentioned this in https://bugs.python.org/issue40897 but now I am thinking this should be a separate issue so I am creating this one.

    An example is the class timedelta. It has as parameters days, seconds, microseconds, milliseconds, minutes, hours and weeks. If I run the following script trying different python versions

    for py in 36 37 38 39; do
    source py${py}/bin/activate
    echo "=== $(python3 --version) ==="
    python3 -c "
    from datetime import timedelta
    import inspect
    print(inspect.signature(timedelta.__new__))
    print(inspect.signature(timedelta.__init__))
    inspect.signature(timedelta)
    "
    deactivate
    done

    What I get is

    === Python 3.6.9 ===

    (*args, **kwargs)
    (self, /, *args, **kwargs)
    Traceback (most recent call last):
    ...
    ValueError: no signature found for builtin type <class 'datetime.timedelta'>
    === Python 3.7.11 ===
    (*args, **kwargs)
    (self, /, *args, **kwargs)
    Traceback (most recent call last):
    ...
    ValueError: no signature found for builtin type <class 'datetime.timedelta'>
    === Python 3.8.11 ===
    (*args, **kwargs)
    (self, /, *args, **kwargs)
    Traceback (most recent call last):
    ...
    ValueError: no signature found for builtin type <class 'datetime.timedelta'>
    === Python 3.9.6 ===
    (*args, **kwargs)
    (self, /, *args, **kwargs)
    Traceback (most recent call last):
    ...
    ValueError: no signature found for builtin type <class 'datetime.timedelta'>

    @mauvilsa mauvilsa mannequin added 3.7 (EOL) end of life 3.8 (EOL) end of life 3.9 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Jul 13, 2021
    @gvanrossum
    Copy link
    Member

    Doesn’t it do that with any built in function? Try Len or open, for example. I think that’s a feature, at least not a bug specific to date time.

    @mauvilsa
    Copy link
    Mannequin Author

    mauvilsa mannequin commented Jul 14, 2021

    Doesn’t it do that with any built in function?

    Sorry. I did not include what is the behavior for other classes. An example could be calendar.Calendar. In this case the signature gives:

    >>> from calendar import Calendar
    >>> import inspect
    >>> print(inspect.signature(Calendar.__init__))
    (self, firstweekday=0)
    >>> print(inspect.signature(Calendar))
    (firstweekday=0)

    Note that the signature gives firstweekday which is the only init parameter. Calendar is not implemented with __new__ so getting the signature would be for object, that does not include named parameters.

    It also works fine when you implement a class with __new__. For example:

    >>> class MyClass:
        def __new__(cls, paramA, paramB=1):
            obj = object.__new__(cls)
            obj.paramA = paramA
            obj.paramB = paramB
            return obj
    >>> print(inspect.signature(MyClass.__new__))
    (cls, paramA, paramB=1)
    >>> print(inspect.signature(MyClass))
    (paramA, paramB=1)

    I do think it is a bug specific to the datetime classes.

    @gvanrossum
    Copy link
    Member

    You're right, it seems specific to built-in *classes* like those in datetime. We get the same with inspect.signature(int), since int is also a built-in class.

    I don't know who maintains inspect, but it's not me. :-(

    @mauvilsa
    Copy link
    Mannequin Author

    mauvilsa mannequin commented Jul 17, 2021

    Also happens in python 3.10.

    === Python 3.10.0b4 ===

    (*args, **kwargs)
    (self, /, *args, **kwargs)
    Traceback (most recent call last):
    ...
    ValueError: no signature found for builtin type <class 'datetime.timedelta'>

    @mauvilsa mauvilsa mannequin added 3.10 only security fixes labels Jul 17, 2021
    @mauvilsa
    Copy link
    Mannequin Author

    mauvilsa mannequin commented Jul 17, 2021

    I am not sure if this affects all built-in classes, assuming that by built-in it means that SOMEOBJECT.__class__.__module__ == 'builtins'. For example I have C++ library that is compiled into a python module using swig. It is available as a docker image docker pull mauvilsa/pagexml:runtime-ubuntu20.04-py38. For a class in that module it can be observed:

    >>> import inspect
    >>> import pagexml
    >>> pagexml.swigPageXML.PageXML.__class__.__module__
    'builtins'
    >>> print(inspect.signature(pagexml.swigPageXML.PageXML.__init__))
    (self, pagexml_path=None, schema_path=None)

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @furkanonder
    Copy link
    Contributor

    Reproduced in Python 3.12.0a7.

    Python 3.12.0a7+ (heads/main:8d95012c95, May 13 2023, 14:05:03) [GCC 13.1.1 20230429] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from datetime import timedelta
    >>> import inspect
    >>> print(inspect.signature(timedelta.__new__))
    (*args, **kwargs)
    >>> print(inspect.signature(timedelta.__init__))
    (self, /, *args, **kwargs)
    >>> inspect.signature(timedelta)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/abc/cpython/Lib/inspect.py", line 3316, in signature
        return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/abc/cpython/Lib/inspect.py", line 3060, in from_callable
        return _signature_from_callable(obj, sigcls=cls,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/abc/cpython/Lib/inspect.py", line 2622, in _signature_from_callable
        raise ValueError(
    ValueError: no signature found for builtin type <class 'datetime.timedelta'>
    >>> 
    

    @arhadthedev arhadthedev added 3.11 only security fixes 3.12 only security fixes and removed 3.10 only security fixes 3.9 only security fixes 3.8 (EOL) end of life 3.7 (EOL) end of life labels May 13, 2023
    @StanFromIreland
    Copy link
    Contributor

    StanFromIreland commented Mar 12, 2025

    Since this is a problem with how the C extension is configured, maybe we could make some workaround where it calls the python implementation signature? Or encode it by hand?

    >>> from _pydatetime import timedelta
    ... import inspect
    ... print(inspect.signature(timedelta.__new__))
    ... print(inspect.signature(timedelta.__init__))
    ... inspect.signature(timedelta)
    ... 
    (cls, days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
    (self, /, *args, **kwargs)
    <Signature (days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)>
    
    

    @picnixz picnixz removed 3.11 only security fixes 3.12 only security fixes labels Mar 12, 2025
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    Development

    No branches or pull requests

    5 participants