Skip to content

cmath.log has an invalid signature (ditto math.log) #89381

Description

@mdickinson
BPO 45218
Nosy @mdickinson, @vstinner, @corona10

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-09-16.09:09:00.708>
labels = ['extension-modules', 'type-bug', '3.9', '3.10', '3.11']
title = 'cmath.log has an invalid signature'
updated_at = <Date 2021-09-24.15:55:05.789>
user = 'https://github.com/mdickinson'

bugs.python.org fields:

activity = <Date 2021-09-24.15:55:05.789>
actor = 'corona10'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Extension Modules']
creation = <Date 2021-09-16.09:09:00.708>
creator = 'mark.dickinson'
dependencies = []
files = []
hgrepos = []
issue_num = 45218
keywords = []
message_count = 5.0
messages = ['401933', '401937', '401938', '401939', '401940']
nosy_count = 3.0
nosy_names = ['mark.dickinson', 'vstinner', 'corona10']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue45218'
versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

Linked PRs

Activity

  1. mdickinson commented on Sep 16, 2021

    @mdickinson
    MemberAuthor

    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
  2. mdickinson commented on Sep 16, 2021

    @mdickinson
    MemberAuthor

    Issue bpo-43067 is similar. I'm not sure what the best solution is in this case:

    • un-argument-clinic cmath.log, and document the signature using two lines (similar to range):
         log(z)
         log(z, base)
    • change the behaviour of cmath.log so that the second argument is allowed be None (and defaults to None)
  3. mdickinson commented on Sep 16, 2021

    @mdickinson
    MemberAuthor

    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.)

  4. mdickinson commented on Sep 16, 2021

    @mdickinson
    MemberAuthor

    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.

  5. vstinner commented on Sep 16, 2021

    @vstinner
    Member

    The current Argument Clinic syntax for math.log() is:

    --------------
    /*[clinic input]
    math.log

    x:    object
    [
    base: object(c_default="NULL") = math.e
    ]
    /
    

    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.

  6. 29 remaining items

  7. arhadthedev commented on Feb 5, 2023

    @arhadthedev
    Member

    discuss.org

    discuss.python.org?

  8. mdickinson commented on Feb 5, 2023

    @mdickinson
    MemberAuthor
  9. added a commit that references this issue on Feb 5, 2023
  10. added a commit that references this issue on Feb 6, 2023
  11. mdickinson commented on Mar 4, 2023

    @mdickinson
    MemberAuthor

    Closing as "won't fix".

  12. self-assigned this
    on May 14, 2026
  13. changed the title [-]cmath.log has an invalid signature[/-] [+]cmath.log has an invalid signature (ditto math.log)[/+] on May 14, 2026
  14. skirpichev commented on May 14, 2026

    @skirpichev
    Member

    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:

    >>> inspect.signature(cmath.log)
    <Signature (z, base=cmath.e, /)>
    

    or

    >>> inspect.signature(cmath.log)
    <Signature (z, base=e, /)>
    

    PS: For completeness, now we have the PEP 661. Sentinel could be used as an alternative to None. See functools.reduce().

  15. mdickinson commented on May 14, 2026

    @mdickinson
    MemberAuthor

    @skirpichev Please could you unassign me from this issue? (I don't have the permissions to do that myself.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions