Skip to content
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

Simplify parsing of complex numbers and make complex('inf') valid. #50066

Closed
mdickinson opened this issue Apr 22, 2009 · 7 comments
Closed

Simplify parsing of complex numbers and make complex('inf') valid. #50066

mdickinson opened this issue Apr 22, 2009 · 7 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@mdickinson
Copy link
Member

BPO 5816
Nosy @mdickinson, @ericvsmith
Files
  • simplify_complex_parsing.patch
  • simplify_complex_parsing_v2.patch
  • 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 = 'https://github.com/mdickinson'
    closed_at = <Date 2009-04-24.13:28:37.294>
    created_at = <Date 2009-04-22.20:27:18.641>
    labels = ['interpreter-core', 'type-bug']
    title = "Simplify parsing of complex numbers and make\tcomplex('inf') valid."
    updated_at = <Date 2009-04-24.13:28:37.293>
    user = 'https://github.com/mdickinson'

    bugs.python.org fields:

    activity = <Date 2009-04-24.13:28:37.293>
    actor = 'mark.dickinson'
    assignee = 'mark.dickinson'
    closed = True
    closed_date = <Date 2009-04-24.13:28:37.294>
    closer = 'mark.dickinson'
    components = ['Interpreter Core']
    creation = <Date 2009-04-22.20:27:18.641>
    creator = 'mark.dickinson'
    dependencies = []
    files = ['13738', '13746']
    hgrepos = []
    issue_num = 5816
    keywords = ['patch']
    message_count = 7.0
    messages = ['86328', '86354', '86359', '86360', '86374', '86404', '86407']
    nosy_count = 2.0
    nosy_names = ['mark.dickinson', 'eric.smith']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'patch review'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue5816'
    versions = ['Python 2.7']

    @mdickinson
    Copy link
    Member Author

    Here's a patch that:

    1. greatly simplifies the complex parsing code in Objects/complexobject.c
    2. allows nans and infinities in constructing a complex number from
      a string
    3. fixes missing out-of-memory checks (PyOS_ascii_strtod can fail due to
      lack of memory).

    Note that part 2. comes entirely for free with the parsing simplification.

    But it seems to me that if float('inf') is valid, then complex('inf')
    should be valid too. There are potential uses for being able to create a
    complex infinity when working with the complex projective plane (a natural
    domain for rational functions over the complex numbers).

    @mdickinson mdickinson added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Apr 22, 2009
    @mdickinson mdickinson self-assigned this Apr 22, 2009
    @mdickinson mdickinson added the type-bug An unexpected behavior, bug, or error label Apr 22, 2009
    @mdickinson
    Copy link
    Member Author

    Updated patch:

    1. also simplify complex printing: no special handling for nans or
      infinities. This means that e.g. complex(1, inf) prints as

      "1 + infj" instead of "1+inf*j".

      This might look ugly, but I think it's better than what was there
      before. Complex reprs are now more uniform and easier to parse
      by external code. And the expression "1 + inf*j" doesn't give
      the right thing anyway, even if you replace j by 1j and inf by
      float(inf):

    >>> inf = float('inf')
    >>> 1 + inf*j
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'j' is not defined
    >>> 1 + inf*1j  # expect (1+infj), but get nan in real part:
    (nan+infj)

    Furthermore, with these simplifications to printing and
    parsing, roundtripping now works: the output of repr(z)
    is valid input to

    1. Print real part if it's negative zero: z =complex(-0.0, 0.0)
      now prints as -0 + 0j instead of just 0j, so again roundtripping
      works: complex(repr(z)) recovers z exactly.

    2. Change PyOS_ascii_strtod to always output a sign when requested,
      even for nans. As far as I can tell, the complex formatting is
      the only place that's affected by this. Eric?

    @ericvsmith
    Copy link
    Member

    Wow, that does greatly simplify printing. One nit: the variable named
    'im' isn't needed any more, you could just use 'pim'. Not sure if the
    asymmetry with 're' and 'pre' is worthwhile, though.

    Mark Dickinson wrote:

    1. Change PyOS_ascii_strtod to always output a sign when requested,
      even for nans. As far as I can tell, the complex formatting is
      the only place that's affected by this. Eric?

    That's correct. It might make a difference when fixing bpo-4482,
    though, at least for the %-formatting case. So if you're going to check
    this in, sooner is better than later for me.

    Also, could this be backported to 2.7, so that 4482 can be fixed the
    same way in both versions?

    @ericvsmith ericvsmith changed the title Simplify parsing of complex numbers and make complex('inf') valid. Simplify parsing of complex numbers and make complex('inf') valid. Apr 23, 2009
    @ericvsmith
    Copy link
    Member

    The fallback code, around line 633 in the patched version of pystrtod.c,
    probably also needs to be modified. It's this code that would need
    backporting to 2.7.

    @mdickinson
    Copy link
    Member Author

    Committed to py3k, r71818, with the changes Eric suggested. I ran build
    and tests both with and without the -DPY_NO_SHORT_FLOAT_REPR compiler
    option.

    Will backport.

    @mdickinson
    Copy link
    Member Author

    Backported to trunk in r71824.

    Leaving open, as I now need forward port some bits of r71824 which
    weren't in the r71818 checkin.

    Note that with this change, some strings which were previously accepted
    by the complex constructor are no longer accepted. Examples are:

    '1..1j'
    '1.11.1j'
    '1e1.1j'

    I consider this to be a bugfix: I can't imagine that acceptance of
    those strings was intentional. However, strings like:

    'j'
    '-j'
    '4-j'

    continue to be accepted.

    @mdickinson
    Copy link
    Member Author

    Extra bits forward ported in r71829. Python 3.1 and 2.7 now both accept
    the same strings for the complex constructor.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants