Skip to content

Sign change when doing math gives invalid number #341

Closed

Description

@michi12321

Bug:

>>> d = tomlkit.parse('x=-3.1415')
>>> d['x'] *= -1
>>> print(tomlkit.dumps(d))

returns:

a=+3.1415

>>> d['x'] *= -1
>>> print(tomlkit.dumps(d))

returns:

a=--3.1415

Subsequent parsing raises tomlkit.exceptions.InvalidNumberError.

Of course there is an easy workaround using type conversion: d['x'] = float(d['x'])*-1.

Activity

  1. JamesParrott commented on May 2, 2024

    @JamesParrott

    I'mm not sure where the "a" is coming from in your example when everything is done on the "x" key. Nor how it is possible to get Python to print a float as "--3.1415" at all.

    Suffice to say I could not reproduce the output posted (on Windows 11, Python 3.11, Tomlkit 0.11.8):

    >>> d=tomlkit.parse('x=-3.1415')
    >>> d['x'] *= -1
    >>> print(tomlkit.dumps(d))
    x=3.1415
    >>> d['x'] *= -1
    >>> print(tomlkit.dumps(d))
    x=-3.1415
    

    Please provide a minimal reproducible example and details of the environment. Until then I suggest this issue be closed.

  2. michi12321 commented on May 5, 2024

    @michi12321
    Author

    Hi James, thanks for your time! The 'a' is of course supposed to be a 'x'...
    I can confirm that this issue doesn't appear in tomlkit 0.11.8 .
    I was using tomlkit 0.12 on different versions of python (3.11+3.12) and different OS (Win10, Linux)
    Minimal reproducible example below:

    >>> import tomlkit
    >>> d = tomlkit.parse('x=-3.14')
    >>> d['x'] *= -1
    >>> print(tomlkit.dumps(d))
    x=+3.14
    >>> d['x'] *= -1
    >>> print(tomlkit.dumps(d))
    x=--3.14
    >>> tomlkit.parse(tomlkit.dumps(d))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/michi/.virtualenvs/tk/lib/python3.11/site-packages/tomlkit/api.py", line 86, in parse
        return Parser(string).parse()
               ^^^^^^^^^^^^^^^^^^^^^^
      File "/home/michi/.virtualenvs/tk/lib/python3.11/site-packages/tomlkit/parser.py", line 139, in parse
        item = self._parse_item()
               ^^^^^^^^^^^^^^^^^^
      File "/home/michi/.virtualenvs/tk/lib/python3.11/site-packages/tomlkit/parser.py", line 238, in _parse_item
        return self._parse_key_value(True)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/michi/.virtualenvs/tk/lib/python3.11/site-packages/tomlkit/parser.py", line 331, in _parse_key_value
        val = self._parse_value()
              ^^^^^^^^^^^^^^^^^^^
      File "/home/michi/.virtualenvs/tk/lib/python3.11/site-packages/tomlkit/parser.py", line 456, in _parse_value
        raise self.parse_error(InvalidNumberError)
    tomlkit.exceptions.InvalidNumberError: Invalid number at line 1 col 8
    
  3. JamesParrott commented on May 6, 2024

    @JamesParrott

    You're welcome. Sorry I thought it was Python producing the --, whereas it's in the string from tomlkit.dumps. I can reproduce it now:

    Python 3.12.1 (tags/v3.12.1:2305ca5, Dec  7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import tomlkit
    >>> d = tomlkit.parse('x=-3.14')
    >>> d
    {'x': -3.14}
    >>> print(tomlkit.dumps(d))
    x=-3.14
    >>> d['x'] *= -1
    >>> print(tomlkit.dumps(d))
    x=+3.14
    >>> d['x'] *= -1
    >>> print(tomlkit.dumps(d))
    x=--3.14
    >>> tomlkit.__version__
    '0.12.0'
    

    Anyway, note that tomlkit.loads returns a tomlkit.toml_document.TOMLDocument, which has the same __repr__ as a dict but is at best, a subclass. A normal Python dict can be formed from its .items(). But tomlkit will still remember its starting state and render it as --1.

    But you're quite right. Integer values in tables seem to cycle through +, +, +, -, ... when multiplied by -1 (i.e. not just +,-,+,-,...):

    python -ic "import tomlkit as tk"
    >>> d =  tk.parse('x=-3')
    >>> for __ in range(12):
    ...   d['x'] *= -1; print(tk.dumps(d))
    ...
    x=+3
    x=--3
    x=3
    x=-3
    x=+3
    x=--3
    x=3
    x=-3
    x=+3
    x=--3
    x=3
    x=-3
    

    And Float values can never be negative at all:

    >>> d =  tk.parse('x=-3.14')
    >>> for __ in range(6):
    ...   d['x'] *= -1; print(tk.dumps(d))
    ...
    x=+3.14
    x=--3.14
    x=+3.14
    x=--3.14
    x=+3.14
    x=--3.14
    
  4. self-assigned this
    on May 7, 2024
  5. added a commit that references this issue on May 7, 2024
    f1c2d96
  6. added a commit that references this issue on May 7, 2024
    bf01a25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions