hatch icon indicating copy to clipboard operation
hatch copied to clipboard

fix(version): exec code with lazy type in dataclass

Open kiyoon opened this issue 1 year ago • 4 comments

Fixes #1863

kiyoon avatar Dec 25 '24 06:12 kiyoon

Test is very simple.

As in the issue,

from __future__ import annotations

from dataclasses import dataclass

@dataclass
class VersionConfig:
    test_dir: str | None = None
    verbose: bool = False

__version__ = "0.0.0"
from dataclasses import dataclass

@dataclass
class VersionConfig:
    test_dir: "str | None" = None
    verbose: bool = False

__version__ = "0.0.0"

These two files won't be executed with this code:

import sys
from importlib.util import module_from_spec, spec_from_file_location

spec = spec_from_file_location(
    "src/my_project/_version", "src/my_project/_version.py"
)
module = module_from_spec(spec)  # type: ignore[arg-type]
# sys.modules["src/my_project/_version"] = module
spec.loader.exec_module(module)  # type: ignore[union-attr]
version = eval("__version__", vars(module))
print(version)

but without the lazy type evaluation,

# NO IMPORT __future__ annotations
from dataclasses import dataclass

@dataclass
class VersionConfig:
    test_dir: str | None = None    # HERE
    verbose: bool = False

__version__ = "0.0.0"

or, with the added line sys.modules["src/my_project/_version"] = module, it works.

kiyoon avatar Dec 25 '24 06:12 kiyoon

Thanks! Can you please add a code comment explaining what this does?

Done!

After that then we can work on adding a test together!

Sure, let's add the example _version.py in the tests!

kiyoon avatar Dec 25 '24 06:12 kiyoon

Tests have been added. You may run the test with and without the change and see what happens!

kiyoon avatar Dec 25 '24 06:12 kiyoon

@ofek When will this be reviewed?

kiyoon avatar May 26 '25 01:05 kiyoon