在 Python 3.6 数据类上使用 enforce_types 时出错:没有属性 _SpecialForm
Error using enforce_types on a Python 3.6 dataclass: no attribute _SpecialForm
我正在使用 enforce_typing
和 dataclasses
创建一个简单的 - 希望是健壮的 - 对象来配置模型。我正在使用 Travis 测试项目的代码,并在 3.6、3.7 和 3.8 上构建。
在 3.6 上构建失败并出现错误:
AttributeError: module 'typing' has no attribute '_SpecialForm'
我在下面放了一个简单的 reprex 来显示实践中的错误。我能做些什么来解决这个问题?可能我只是应该停止尝试支持 3.6!
Python 3.6.7 (default, Aug 12 2021, 12:48:47)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import enforce_typing
In [3]: import dataclasses
In [5]: @enforce_typing.enforce_types
...: @dataclasses.dataclass
...: class Test():
...: x: str = 'a'
...:
In [6]: Test()
Out[6]: Test(x='a')
In [7]: Test(x='c')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-54c6f8c04751> in <module>
----> 1 Test(x='c')
~/.pyenv/versions/3.6.7/lib/python3.6/site-packages/enforce_typing/decorator.py in wrapper(*args, **kwargs)
26 @wraps(func)
27 def wrapper(*args, **kwargs):
---> 28 check_types(*args, **kwargs)
29 return func(*args, **kwargs)
30
~/.pyenv/versions/3.6.7/lib/python3.6/site-packages/enforce_typing/decorator.py in check_types(*args, **kwargs)
14 with suppress(KeyError):
15 type_hint = spec.annotations[name]
---> 16 if isinstance(type_hint, typing._SpecialForm):
17 continue
18 actual_type = getattr(type_hint, "__origin__", type_hint)
AttributeError: module 'typing' has no attribute '_SpecialForm'
错误消息清楚地表明 enforce_typing
库假定 Python 的 typing
模块中有一个 _SpecialForm
class。对于该库来说,这是一个非常不明智的假设,因为 class 的名称以单个下划线开头,因此 _SpecialForm
被明确标记为模块的实现细节。对于 typing
模块尤其如此,它仍然是新的并且正在非常积极的开发中,许多实现细节在 python.
的每个版本中都发生了重大变化
顺便说一句,我实际上并没有在此处批评 enforce_typing
图书馆。不幸的是,由于 typing
模块中的很多东西都被标记为实现细节,因此(目前)没有一种特别安全的方法来概括这种运行时类型检查。
我正在使用 enforce_typing
和 dataclasses
创建一个简单的 - 希望是健壮的 - 对象来配置模型。我正在使用 Travis 测试项目的代码,并在 3.6、3.7 和 3.8 上构建。
在 3.6 上构建失败并出现错误:
AttributeError: module 'typing' has no attribute '_SpecialForm'
我在下面放了一个简单的 reprex 来显示实践中的错误。我能做些什么来解决这个问题?可能我只是应该停止尝试支持 3.6!
Python 3.6.7 (default, Aug 12 2021, 12:48:47)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import enforce_typing
In [3]: import dataclasses
In [5]: @enforce_typing.enforce_types
...: @dataclasses.dataclass
...: class Test():
...: x: str = 'a'
...:
In [6]: Test()
Out[6]: Test(x='a')
In [7]: Test(x='c')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-54c6f8c04751> in <module>
----> 1 Test(x='c')
~/.pyenv/versions/3.6.7/lib/python3.6/site-packages/enforce_typing/decorator.py in wrapper(*args, **kwargs)
26 @wraps(func)
27 def wrapper(*args, **kwargs):
---> 28 check_types(*args, **kwargs)
29 return func(*args, **kwargs)
30
~/.pyenv/versions/3.6.7/lib/python3.6/site-packages/enforce_typing/decorator.py in check_types(*args, **kwargs)
14 with suppress(KeyError):
15 type_hint = spec.annotations[name]
---> 16 if isinstance(type_hint, typing._SpecialForm):
17 continue
18 actual_type = getattr(type_hint, "__origin__", type_hint)
AttributeError: module 'typing' has no attribute '_SpecialForm'
错误消息清楚地表明 enforce_typing
库假定 Python 的 typing
模块中有一个 _SpecialForm
class。对于该库来说,这是一个非常不明智的假设,因为 class 的名称以单个下划线开头,因此 _SpecialForm
被明确标记为模块的实现细节。对于 typing
模块尤其如此,它仍然是新的并且正在非常积极的开发中,许多实现细节在 python.
顺便说一句,我实际上并没有在此处批评 enforce_typing
图书馆。不幸的是,由于 typing
模块中的很多东西都被标记为实现细节,因此(目前)没有一种特别安全的方法来概括这种运行时类型检查。