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

Incorrect default for constrained type variables #358

Open
decorator-factory opened this issue Jan 14, 2025 · 0 comments
Open

Incorrect default for constrained type variables #358

decorator-factory opened this issue Jan 14, 2025 · 0 comments

Comments

@decorator-factory
Copy link
Contributor

decorator-factory commented Jan 14, 2025

From the docs:

https://adaptix.readthedocs.io/en/latest/loading-and-dumping/extended-usage.html

TypeVar Derived implicit parameter
T = TypeVar('T') Any
B = TypeVar('B', bound=Book) Book
C = TypeVar('C', str, bytes) Union[str, bytes]

The behaviour for the third case is wrong: Union[str, bytes] is not a valid value for C.

A constrained type variable can only be resolved to one of the options, so Thing[int] is valid, Thing[str] is valid, but Thing[str | int], Thing[Literal[0]], Thing[str | Literal[0]], and Thing[bool] are all invalid. (see the specification on TypeVars)

In other words, TypeVar("S", str, int) is not the same as TypeVar("S", bound=str | int).


Example code:

from dataclasses import dataclass
from typing import Generic, TypeVar

import adaptix

S = TypeVar("S", str, int)

@dataclass
class Thing(Generic[S]):
    first: S
    second: S

    def should_always_be_true(self) -> bool:
        return (
            isinstance(self.first, str) and isinstance(self.second, str)
            or
            isinstance(self.first, int) and isinstance(self.second, int)
        )


thing = adaptix.load({"first": "hmm", "second": 42}, Thing)
print(thing)  # Thing(first='hmm', second=42)
print(thing.should_always_be_true())  # False

Possible solutions:

  • ban unqualified constrained typevars (i.e. Thing[str] is legal as the second argument to load, Thing is not)
  • change Thing with no parameter to mean Thing[str] | Thing[int]
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

No branches or pull requests

1 participant