-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathtest_modules.py
More file actions
155 lines (117 loc) · 4.87 KB
/
test_modules.py
File metadata and controls
155 lines (117 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
from __future__ import annotations
import builtins
import pytest
import env
from pybind11_tests import ConstructorStats
from pybind11_tests import modules as m
from pybind11_tests.modules import submodule_string as mstr
from pybind11_tests.modules import subsubmodule as ms
def test_nested_modules():
import pybind11_tests
assert pybind11_tests.__name__ == "pybind11_tests"
assert pybind11_tests.modules.__name__ == "pybind11_tests.modules"
assert (
pybind11_tests.modules.subsubmodule.__name__
== "pybind11_tests.modules.subsubmodule"
)
assert m.__name__ == "pybind11_tests.modules"
assert ms.__name__ == "pybind11_tests.modules.subsubmodule"
assert m.__file__ == ms.__file__
assert ms.submodule_func() == "submodule_func()"
assert (
pybind11_tests.modules.submodule_string.__name__
== "pybind11_tests.modules.submodule_string"
)
assert mstr.submodule_string_func() == "submodule_string_func()"
assert mstr.submodule_string_func_with_arg(x=2) == 3
def test_reference_internal():
b = ms.B()
assert str(b.get_a1()) == "A[1]"
assert str(b.a1) == "A[1]"
assert str(b.get_a2()) == "A[2]"
assert str(b.a2) == "A[2]"
b.a1 = ms.A(42)
b.a2 = ms.A(43)
assert str(b.get_a1()) == "A[42]"
assert str(b.a1) == "A[42]"
assert str(b.get_a2()) == "A[43]"
assert str(b.a2) == "A[43]"
if env.GRAALPY:
pytest.skip("ConstructorStats is incompatible with GraalPy.")
astats, bstats = ConstructorStats.get(ms.A), ConstructorStats.get(ms.B)
assert astats.alive() == 2
assert bstats.alive() == 1
del b
assert astats.alive() == 0
assert bstats.alive() == 0
assert astats.values() == ["1", "2", "42", "43"]
assert bstats.values() == []
assert astats.default_constructions == 0
assert bstats.default_constructions == 1
assert astats.copy_constructions == 0
assert bstats.copy_constructions == 0
# assert astats.move_constructions >= 0 # Don't invoke any
# assert bstats.move_constructions >= 0 # Don't invoke any
assert astats.copy_assignments == 2
assert bstats.copy_assignments == 0
assert astats.move_assignments == 0
assert bstats.move_assignments == 0
def test_importing():
from collections import OrderedDict
from pybind11_tests.modules import OD
assert OD is OrderedDict
def test_reimport():
import sys
import pybind11_tests as x
del sys.modules["pybind11_tests"]
# exercise pybind11::detail::get_cached_module()
import pybind11_tests as y
assert x is y
@pytest.mark.xfail(
"env.GRAALPY",
reason="TODO should be fixed on GraalPy side (failure was introduced by pr #5782)",
)
def test_pydoc():
"""Pydoc needs to be able to provide help() for everything inside a pybind11 module"""
import pydoc
import pybind11_tests
assert pybind11_tests.__name__ == "pybind11_tests"
assert pybind11_tests.__doc__ == "pybind11 test module"
assert pydoc.text.docmodule(pybind11_tests)
def test_module_handle_type_name():
assert (
m.def_submodule.__doc__
== "def_submodule(arg0: types.ModuleType, arg1: str) -> types.ModuleType\n"
)
def test_duplicate_registration():
"""Registering two things with the same name"""
assert m.duplicate_registration() == []
def test_builtin_key_type():
"""Test that all the keys in the builtin modules have type str.
Previous versions of pybind11 would add a unicode key in python 2.
"""
assert all(type(k) == str for k in dir(builtins))
@pytest.mark.xfail("env.PYPY", reason="PyModule_GetName()")
def test_def_submodule_failures():
sm = m.def_submodule(m, b"ScratchSubModuleName") # Using bytes to show it works.
assert sm.__name__ == m.__name__ + "." + "ScratchSubModuleName"
malformed_utf8 = b"\x80"
if env.PYPY or env.GRAALPY:
# It is not worth the effort finding a trigger for a failure when running with PyPy.
pytest.skip("Sufficiently exercised on platforms other than PyPy/GraalPy.")
else:
# Meant to trigger PyModule_GetName() failure:
sm_name_orig = sm.__name__
sm.__name__ = malformed_utf8
try:
# We want to assert that a bad __name__ causes some kind of failure, although we do not want to exercise
# the internals of PyModule_GetName(). Currently all supported Python versions raise SystemError. If that
# changes in future Python versions, simply add the new expected exception types here.
with pytest.raises(SystemError):
m.def_submodule(sm, b"SubSubModuleName")
finally:
# Clean up to ensure nothing gets upset by a module with an invalid __name__.
sm.__name__ = sm_name_orig # Purely precautionary.
# Meant to trigger PyImport_AddModule() failure:
with pytest.raises(UnicodeDecodeError):
m.def_submodule(sm, malformed_utf8)