测试类型与 issubclass returns 不一致的结果
Testing types with issubclass returns inconsistent results
我有一个 class A
没有属性,我测试它是否是 typing.Container
的子类。正如预期的那样,该测试失败了。
在单独的测试中,我将 __contains(self, k)__
属性添加到 A,并测试它是否是 typing.Container
的子类,并且测试通过。
现在奇怪的是,如果我测试 A
是否是 typing.Conainer
的子类,然后添加 __contains(self, k)__
属性,然后再次测试 A
是否是 typing.Container
的子类,该测试失败。
发生了什么导致最后一个测试失败,即使 A
确实具有属性 __contains__(self, k)__
?
import pytest
from typing import Container
@pytest.fixture
def A():
class A:...
return A
def test_notsubclass(A):
# passes
assert not issubclass(A, Container)
def test_addcontains(A):
# passes
def __contains__(self, k): ...
setattr(A, '__contains__', __contains__)
assert issubclass(A, Container)
def test_first_then_add_contains(A):
# passes
assert not issubclass(A, Container)
def __contains__(self, k): ...
setattr(A, '__contains__', __contains__)
# fails
assert issubclass(A, Container)
许多 typing
类型的运行时表示是相应 collections.abc
类型的包装器。 For example, typing.Container
is a generic "alias" of collections.abc.Container
:
Container = _alias(collections.abc.Container, 1)
顾名思义,collections.abc
成员派生自 abc.ABC
/abc.ABCMeta
。由于 ABC subclass/instance 检查可能很昂贵,abc.ABCMeta
has an optimisation to cache subclass checks.
我有一个 class A
没有属性,我测试它是否是 typing.Container
的子类。正如预期的那样,该测试失败了。
在单独的测试中,我将 __contains(self, k)__
属性添加到 A,并测试它是否是 typing.Container
的子类,并且测试通过。
现在奇怪的是,如果我测试 A
是否是 typing.Conainer
的子类,然后添加 __contains(self, k)__
属性,然后再次测试 A
是否是 typing.Container
的子类,该测试失败。
发生了什么导致最后一个测试失败,即使 A
确实具有属性 __contains__(self, k)__
?
import pytest
from typing import Container
@pytest.fixture
def A():
class A:...
return A
def test_notsubclass(A):
# passes
assert not issubclass(A, Container)
def test_addcontains(A):
# passes
def __contains__(self, k): ...
setattr(A, '__contains__', __contains__)
assert issubclass(A, Container)
def test_first_then_add_contains(A):
# passes
assert not issubclass(A, Container)
def __contains__(self, k): ...
setattr(A, '__contains__', __contains__)
# fails
assert issubclass(A, Container)
许多 typing
类型的运行时表示是相应 collections.abc
类型的包装器。 For example, typing.Container
is a generic "alias" of collections.abc.Container
:
Container = _alias(collections.abc.Container, 1)
顾名思义,collections.abc
成员派生自 abc.ABC
/abc.ABCMeta
。由于 ABC subclass/instance 检查可能很昂贵,abc.ABCMeta
has an optimisation to cache subclass checks.