seandstewart / typical

Typical: Fast, simple, & correct data-validation using Python 3 typing.
https://python-typical.org
MIT License
183 stars 9 forks source link

Still not working with PEP 604 Union Operators #162

Closed songzhi closed 3 years ago

songzhi commented 3 years ago
import typic

@typic.al
def foo(bar: str | int):
    pass

Would raise these errors:

Traceback (most recent call last):
  File "/home/lsongzhi/code/python/pydemo/main.py", line 4, in <module>
    def foo(bar: str | int):
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/api.py", line 384, in typed
    return _typed(_cls_or_callable) if _cls_or_callable is not None else _typed
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/api.py", line 378, in _typed
    return wrap(obj, delay=delay, strict=strict)  # type: ignore
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/api.py", line 172, in wrap
    protocols(func)
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/serde/resolver.py", line 782, in protocols
    resolved = self.resolve(
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/serde/resolver.py", line 709, in resolve
    resolved = self._resolve_from_annotation(anno, namespace=namespace)
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/serde/resolver.py", line 524, in _resolve_from_annotation
    deserializer, validator = self.des.factory(
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/serde/des.py", line 866, in factory
    deserializer = self._build_des(annotation, key, namespace)
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/serde/des.py", line 709, in _build_des
    anno_name = get_unique_name(origin)
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/util.py", line 255, in get_unique_name
    return f"{get_name(obj)}_{id(obj)}".replace("-", "_")
  File "/home/lsongzhi/.pyenv/versions/3.10.0b2/lib/python3.10/site-packages/typic/util.py", line 236, in get_name
    return obj.__name__
AttributeError: 'types.Union' object has no attribute '__name__'. Did you mean: '__ne__'?
seandstewart commented 3 years ago

Hey @songzhi -

Can you try with branch sean/162/fix-get-name-for-py310?

songzhi commented 3 years ago

Seems the same problem:

❯ /home/lsongzhi/.pyenv/versions/3.10.0b2/bin/python /home/lsongzhi/code/python/typical/main.py
Traceback (most recent call last):
  File "/home/lsongzhi/code/python/typical/main.py", line 4, in <module>
    def foo(bar: str | int):
  File "/home/lsongzhi/code/python/typical/typic/api.py", line 384, in typed
    return _typed(_cls_or_callable) if _cls_or_callable is not None else _typed
  File "/home/lsongzhi/code/python/typical/typic/api.py", line 378, in _typed
    return wrap(obj, delay=delay, strict=strict)  # type: ignore
  File "/home/lsongzhi/code/python/typical/typic/api.py", line 172, in wrap
    protocols(func)
  File "/home/lsongzhi/code/python/typical/typic/serde/resolver.py", line 796, in protocols
    resolved = self.resolve(
  File "/home/lsongzhi/code/python/typical/typic/serde/resolver.py", line 723, in resolve
    resolved = self._resolve_from_annotation(anno, namespace=namespace)
  File "/home/lsongzhi/code/python/typical/typic/serde/resolver.py", line 532, in _resolve_from_annotation
    deserializer, validator = self.des.factory(
  File "/home/lsongzhi/code/python/typical/typic/serde/des.py", line 866, in factory
    deserializer = self._build_des(annotation, key, namespace)
  File "/home/lsongzhi/code/python/typical/typic/serde/des.py", line 709, in _build_des
    anno_name = get_unique_name(origin)
  File "/home/lsongzhi/code/python/typical/typic/util.py", line 259, in get_unique_name
    return f"{get_name(obj)}_{id(obj)}".replace("-", "_")
  File "/home/lsongzhi/code/python/typical/typic/util.py", line 238, in get_name
    return obj.__name__
AttributeError: 'types.Union' object has no attribute '__name__'. Did you mean: '__ne__'?
seandstewart commented 3 years ago

Hey @songzhi -

I was able to implement a change that seems to work for fetching names on py3.10, but there are other issues I need to resolve.

Note: py3.10 is sill in beta, so there are still kinks to work out. I'm also having issues initializing a working virtualenv in py3.10 for development work, so I'm effectively blocked until that is resolved.

For now, I'd recommend using the latest stable Python (3.9 as of this writing). I'll continue to work on py3.10 support.

seandstewart commented 3 years ago

@songzhi -

Please give this branch another try - I have all tests green on CI for Python 3.10, but I'd like to make sure it works for you before merging/releasing.

Hey @songzhi -

Can you try with branch sean/162/fix-get-name-for-py310?

songzhi commented 3 years ago

From my point, it works fine now.

But I encountered another problem, using VSCode 1.58.2, Pylance language server, both on the main and sean/162/fix-get-name-for-py310 branch. It runs fine but Pylance reports fake errors: image The same code run with typical2.4.2 wouldn't raise this error.