Skip to content

repr(TzInfo(0)) returns invalid python code #1691

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

Open
15r10nk opened this issue Apr 14, 2025 · 2 comments · May be fixed by #1701
Open

repr(TzInfo(0)) returns invalid python code #1691

15r10nk opened this issue Apr 14, 2025 · 2 comments · May be fixed by #1701
Assignees

Comments

@15r10nk
Copy link

15r10nk commented Apr 14, 2025

Hi, I'm the author of inline-snapshot and have a problem with the way TzInfo.__repr__ is implemented.

TzInfo has currently the following repr:

from pydantic_core import TzInfo

def test_TzInfo():
    assert repr(TzInfo(0)) == 'TzInfo(UTC)'
    assert repr(TzInfo(1)) == 'TzInfo(+00:00:01)'
    assert repr(TzInfo(5000)) == 'TzInfo(+01:23:20)'

The problem is that inline-snapshot uses by default repr() to generate the python code for the snapshots.

from pydantic_core import TzInfo
import datetime
from inline_snapshot import snapshot


def test_TzInfo():
    assert datetime.datetime(1, 2, 3, tzinfo=TzInfo(0)) == snapshot(
        datetime.datetime(1, 2, 3, 0, 0, tzinfo=TzInfo(UTC))
    )

inline-snapshot users then try to import UTC from somewhere which causes other problems.

Is it possible to change the repr() result of TzInfo to the following (add "").

from pydantic_core import TzInfo

def test_TzInfo():
    assert repr(TzInfo(0)) == 'TzInfo("UTC")'
    assert repr(TzInfo(1)) == 'TzInfo("+00:00:01")'
    assert repr(TzInfo(5000)) == 'TzInfo("+01:23:20")'

And to provide the possibility for TzInfo to be constructed from a string?

This should make

assert eval(repr(tzinfo)) == tzinfo

work for all TzInfo objects.

@Viicos Viicos linked a pull request Apr 23, 2025 that will close this issue
4 tasks
@Viicos
Copy link
Member

Viicos commented Apr 23, 2025

I think it makes sense to add quotes in the repr so I went and created #1701. However, I'm not sure inline-snapshot is taking a robust approach here by assuming eval(repr(obj)) works for any obj. In the case of TzInfo, TzInfo("UTC") (or any kind of non-integer argument) fails, and there's no unspoken rule that I know of stating that the evaluation of Python objects representations should result in the same object being re-created.

@alexmojaki
Copy link
Contributor

there's no unspoken rule that I know of stating that the evaluation of Python objects representations should result in the same object being re-created.

From https://docs.python.org/3/library/functions.html#repr:

For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval()

From https://docs.python.org/3/reference/datamodel.html#object.__repr__:

If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants