inspect.signature reports that the cmath.log function has an invalid signature:
Python 3.11.0a0 (heads/fix-44954:d0ea569eb5, Aug 19 2021, 14:59:04) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath
>>> import inspect
>>> inspect.signature(cmath.log)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mdickinson/Python/cpython/Lib/inspect.py", line 3215, in signature
return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/mdickinson/Python/cpython/Lib/inspect.py", line 2963, in from_callable
return _signature_from_callable(obj, sigcls=cls,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/mdickinson/Python/cpython/Lib/inspect.py", line 2432, in _signature_from_callable
return _signature_from_builtin(sigcls, obj,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/mdickinson/Python/cpython/Lib/inspect.py", line 2244, in _signature_from_builtin
return _signature_fromstr(cls, func, s, skip_bound_arg)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/mdickinson/Python/cpython/Lib/inspect.py", line 2114, in _signature_fromstr
raise ValueError("{!r} builtin has invalid signature".format(obj))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: <built-in function log> builtin has invalid signature
See also bpo-36306 and bpo-29299. There may be nothing to be done here, but it would be nice if math.log and cmath.log at least behaved in the same way. A default of None doesn't seem like a terrible option.
(BTW, just to forestall the suggestion, a default of math.e or cmath.e is definitely not the right thing to use as a default: math.e is not exactly Euler's value for e, and log base math.e is likely to be less accurate than plain natural log.)
and log base math.e is likely to be less accurate than plain natural log
Nope, that's nonsense, since the two-argument form simply divides by log(base), and while log(math.e) is mathematically not exactly 1 (its exact value, assuming IEEE 754 binary64, starts 0.9999999999999999468176229339410862948..., which is off from 1.0 by around 0.48 ulps), it's *just* close enough that with a well-behaved libm log implementation it's exactly 1.0 after rounding.
I still don't like the idea of math.e as a default value here, but I'd have to work harder to identify why it makes me uneasy.
Activity
mdickinson commented on Sep 16, 2021
inspect.signature reports that the cmath.log function has an invalid signature:
mdickinson commented on Sep 16, 2021
Issue bpo-43067 is similar. I'm not sure what the best solution is in this case:
mdickinson commented on Sep 16, 2021
See also bpo-36306 and bpo-29299. There may be nothing to be done here, but it would be nice if math.log and cmath.log at least behaved in the same way. A default of None doesn't seem like a terrible option.
(BTW, just to forestall the suggestion, a default of math.e or cmath.e is definitely not the right thing to use as a default: math.e is not exactly Euler's value for e, and log base math.e is likely to be less accurate than plain natural log.)
mdickinson commented on Sep 16, 2021
Nope, that's nonsense, since the two-argument form simply divides by log(base), and while log(math.e) is mathematically not exactly 1 (its exact value, assuming IEEE 754 binary64, starts 0.9999999999999999468176229339410862948..., which is off from 1.0 by around 0.48 ulps), it's *just* close enough that with a well-behaved libm log implementation it's exactly 1.0 after rounding.
I still don't like the idea of math.e as a default value here, but I'd have to work harder to identify why it makes me uneasy.
vstinner commented on Sep 16, 2021
The current Argument Clinic syntax for math.log() is:
--------------
/*[clinic input]
math.log
Return the logarithm of x to the given base.
(...)
--------------
math.log.__text_signature__ is None. __text_signature__ is used by inspect.signature().
I guess that it's a bug in Argument Clinic.
29 remaining items
arhadthedev commented on Feb 5, 2023
discuss.python.org?
mdickinson commented on Feb 5, 2023
@arhadthedev discuss.python.org indeed! Thank you.
Discussion opened at https://discuss.python.org/t/should-none-defaults-for-optional-arguments-be-discouraged/23554
Revert "gh-89381: Fix invalid signatures of math/cmath.log (#101404)" (…
pythongh-89381: Fix invalid signatures of math/cmath.log (python#101404)
mdickinson commented on Mar 4, 2023
Closing as "won't fix".
skirpichev commented on May 14, 2026
Lets reopen this.
This issue still valid. We have much generic one, #73536, but no progress for years. Though, this case seems to be more specific and simple.
I suggest solution along sketch, presented above, i.e. using symbolic constant for the default. (I.e. cmath.e rather than 2.718281828459045.)
Other builtins and/or parts of the stdlib also could benefit from this change. For example, this is how list.index() signature now looks like:
>>> inspect.signature(list.index) <Signature (self, value, start=0, stop=9223372036854775807, /)>Wouldn't this be clearer
>>> inspect.signature(list.index) <Signature (self, value, start=0, stop=sys.maxsize, /)>?
Respectively, proposed signature will look like:
or
PS: For completeness, now we have the PEP 661. Sentinel could be used as an alternative to None. See functools.reduce().
mdickinson commented on May 14, 2026
@skirpichev Please could you unassign me from this issue? (I don't have the permissions to do that myself.)