This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: inspect.signature does not work for datetime classes
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.10, Python 3.9, Python 3.8, Python 3.7, Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: gvanrossum, hongweipeng, mauvilsa
Priority: normal Keywords: patch

Created on 2021-07-13 07:41 by mauvilsa, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 27177 hongweipeng, 2021-07-16 10:59
Messages (6)
msg397387 - (view) Author: Mauricio Villegas (mauvilsa) Date: 2021-07-13 07:41
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'>
msg397481 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-07-14 14:03
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.
msg397484 - (view) Author: Mauricio Villegas (mauvilsa) Date: 2021-07-14 15:24
> 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.
msg397488 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-07-14 15:50
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. :-(
msg397713 - (view) Author: Mauricio Villegas (mauvilsa) Date: 2021-07-17 09:42
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'>
msg397715 - (view) Author: Mauricio Villegas (mauvilsa) Date: 2021-07-17 09:51
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)
History
Date User Action Args
2022-04-11 14:59:47adminsetgithub: 88784
2021-07-17 09:51:41mauvilsasetmessages: + msg397715
2021-07-17 09:42:40mauvilsasetmessages: + msg397713
versions: + Python 3.10
2021-07-16 10:59:48hongweipengsetkeywords: + patch
nosy: + hongweipeng

pull_requests: + pull_request25721
stage: patch review
2021-07-14 15:50:43gvanrossumsetmessages: + msg397488
2021-07-14 15:24:08mauvilsasetmessages: + msg397484
2021-07-14 14:03:49gvanrossumsetnosy: + gvanrossum
messages: + msg397481
2021-07-13 07:54:15mauvilsasettype: behavior
components: + Library (Lib)
2021-07-13 07:41:18mauvilsacreate