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
Attribute always has first type in Union [bug] #2079
Comments
Hello @InnovativeInventor |
@PrettyWood thanks for letting me know! Keep up the good work in this project! Also, just to double check, even when accessing the attribute, I get: print("Most certainly should be Bar:", type(Test(test=Bar()).test)) to be: Most certainly should be Bar: <class '__main__.Foo'> Perhaps I missed this, but I couldn't find an example of this happening in the issues that you linked (although I think the problems they describe are mostly the same as the issue that I reported). |
Also, here are a few more examples: print("Should be true:", isinstance(Test(test=Bar()).test, Bar))
print("Should be false:", isinstance(Test(test=Bar()).test, Foo)) Output:
|
Hey @InnovativeInventor |
Awesome, thanks for clarifying! |
I've done a quick POC of what could be done to make it work from types import new_class
from typing import *
from typingx import isinstancex
from pydantic import BaseModel
T = TypeVar("T")
def _display_type(v: Any) -> str:
try:
return v.__name__
except AttributeError:
# happens with typing objects
return str(v).replace("typing.", "")
class Strict(Generic[T]):
__typelike__: T
@classmethod
def __class_getitem__(cls, typelike: T) -> T:
new_cls = new_class(
f"Strict[{_display_type(typelike)}]",
(cls,),
{},
lambda ns: ns.update({"__typelike__": typelike}),
)
return cast(T, new_cls)
@classmethod
def __get_validators__(cls) -> Generator[Callable[..., Any], None, None]:
yield cls.validate
@classmethod
def validate(cls, value: Any) -> T:
if not isinstancex(value, cls.__typelike__):
raise TypeError(f"{value!r} is not of valid type")
return value
class Foo(BaseModel):
pass
class Bar(BaseModel):
pass
class Test(BaseModel):
test: Strict[Union[Foo, Bar]]
class Pika(BaseModel):
x: Strict[Union[Dict[str, str], List[Tuple[str, str]]]]
assert type(Test(test=Foo()).test) is Foo
assert type(Test(test=Bar()).test) is Bar
assert isinstance(Test(test=Bar()).test, Bar) is True
assert isinstance(Test(test=Bar()).test, Foo) is False
assert Pika(x={"a": "b"}).x == {"a": "b"}
assert Pika(x=[("a", "b")]).x == [("a", "b")] Cheers |
Wow @PrettyWood, thanks so much! Seriously thanks a lot! |
An easier solution will be set Config withing the Pydantic Model. Refere to this. |
The easiest solution now is to set |
Checks
Bug
Output of
python -c "import pydantic.utils; print(pydantic.utils.version_info())"
:Reproduction steps
Result:
The text was updated successfully, but these errors were encountered: