|
1 | 1 | import enum |
| 2 | +import os |
2 | 3 | import sys |
3 | 4 | import textwrap |
4 | 5 | import unittest |
|
13 | 14 | _testcapi = import_helper.import_module('_testcapi') |
14 | 15 | _testinternalcapi = import_helper.import_module('_testinternalcapi') |
15 | 16 |
|
| 17 | +NULL = None |
| 18 | +STDERR_FD = 2 |
| 19 | + |
16 | 20 |
|
17 | 21 | class Constant(enum.IntEnum): |
18 | 22 | Py_CONSTANT_NONE = 0 |
@@ -247,5 +251,53 @@ def func(x): |
247 | 251 |
|
248 | 252 | func(object()) |
249 | 253 |
|
| 254 | + def pyobject_dump(self, obj, release_gil=False): |
| 255 | + pyobject_dump = _testcapi.pyobject_dump |
| 256 | + |
| 257 | + try: |
| 258 | + old_stderr = os.dup(STDERR_FD) |
| 259 | + except OSError as exc: |
| 260 | + # os.dup(STDERR_FD) is not supported on WASI |
| 261 | + self.skipTest(f"os.dup() failed with {exc!r}") |
| 262 | + |
| 263 | + filename = os_helper.TESTFN |
| 264 | + try: |
| 265 | + try: |
| 266 | + with open(filename, "wb") as fp: |
| 267 | + fd = fp.fileno() |
| 268 | + os.dup2(fd, STDERR_FD) |
| 269 | + pyobject_dump(obj, release_gil) |
| 270 | + finally: |
| 271 | + os.dup2(old_stderr, STDERR_FD) |
| 272 | + os.close(old_stderr) |
| 273 | + |
| 274 | + with open(filename) as fp: |
| 275 | + return fp.read().rstrip() |
| 276 | + finally: |
| 277 | + os_helper.unlink(filename) |
| 278 | + |
| 279 | + def test_pyobject_dump(self): |
| 280 | + # test string object |
| 281 | + str_obj = 'test string' |
| 282 | + output = self.pyobject_dump(str_obj) |
| 283 | + hex_regex = r'(0x)?[0-9a-fA-F]+' |
| 284 | + regex = ( |
| 285 | + fr"object address : {hex_regex}\n" |
| 286 | + r"object refcount : [0-9]+\n" |
| 287 | + fr"object type : {hex_regex}\n" |
| 288 | + r"object type name: str\n" |
| 289 | + r"object repr : 'test string'" |
| 290 | + ) |
| 291 | + self.assertRegex(output, regex) |
| 292 | + |
| 293 | + # release the GIL |
| 294 | + output = self.pyobject_dump(str_obj, release_gil=True) |
| 295 | + self.assertRegex(output, regex) |
| 296 | + |
| 297 | + # test NULL object |
| 298 | + output = self.pyobject_dump(NULL) |
| 299 | + self.assertRegex(output, r'<object at .* is freed>') |
| 300 | + |
| 301 | + |
250 | 302 | if __name__ == "__main__": |
251 | 303 | unittest.main() |
0 commit comments