|
1 | 1 | import _ctypes_test
|
2 |
| -import platform |
| 2 | +from platform import architecture as _architecture |
3 | 3 | import struct
|
4 | 4 | import sys
|
5 | 5 | import unittest
|
|
8 | 8 | c_uint8, c_uint16, c_uint32,
|
9 | 9 | c_short, c_ushort, c_int, c_uint,
|
10 | 10 | c_long, c_ulong, c_longlong, c_ulonglong, c_float, c_double)
|
| 11 | +from ctypes.util import find_library |
11 | 12 | from struct import calcsize
|
12 | 13 | from collections import namedtuple
|
13 | 14 | from test import support
|
@@ -472,6 +473,66 @@ class X(Structure):
|
472 | 473 | self.assertEqual(s.first, got.first)
|
473 | 474 | self.assertEqual(s.second, got.second)
|
474 | 475 |
|
| 476 | + def _test_issue18060(self, Vector): |
| 477 | + # The call to atan2() should succeed if the |
| 478 | + # class fields were correctly cloned in the |
| 479 | + # subclasses. Otherwise, it will segfault. |
| 480 | + if sys.platform == 'win32': |
| 481 | + libm = CDLL(find_library('msvcrt.dll')) |
| 482 | + else: |
| 483 | + libm = CDLL(find_library('m')) |
| 484 | + |
| 485 | + libm.atan2.argtypes = [Vector] |
| 486 | + libm.atan2.restype = c_double |
| 487 | + |
| 488 | + arg = Vector(y=0.0, x=-1.0) |
| 489 | + self.assertAlmostEqual(libm.atan2(arg), 3.141592653589793) |
| 490 | + |
| 491 | + @unittest.skipIf(_architecture() == ('64bit', 'WindowsPE'), "can't test Windows x64 build") |
| 492 | + @unittest.skipUnless(sys.byteorder == 'little', "can't test on this platform") |
| 493 | + def test_issue18060_a(self): |
| 494 | + # This test case calls |
| 495 | + # PyCStructUnionType_update_stgdict() for each |
| 496 | + # _fields_ assignment, and PyCStgDict_clone() |
| 497 | + # for the Mid and Vector class definitions. |
| 498 | + class Base(Structure): |
| 499 | + _fields_ = [('y', c_double), |
| 500 | + ('x', c_double)] |
| 501 | + class Mid(Base): |
| 502 | + pass |
| 503 | + Mid._fields_ = [] |
| 504 | + class Vector(Mid): pass |
| 505 | + self._test_issue18060(Vector) |
| 506 | + |
| 507 | + @unittest.skipIf(_architecture() == ('64bit', 'WindowsPE'), "can't test Windows x64 build") |
| 508 | + @unittest.skipUnless(sys.byteorder == 'little', "can't test on this platform") |
| 509 | + def test_issue18060_b(self): |
| 510 | + # This test case calls |
| 511 | + # PyCStructUnionType_update_stgdict() for each |
| 512 | + # _fields_ assignment. |
| 513 | + class Base(Structure): |
| 514 | + _fields_ = [('y', c_double), |
| 515 | + ('x', c_double)] |
| 516 | + class Mid(Base): |
| 517 | + _fields_ = [] |
| 518 | + class Vector(Mid): |
| 519 | + _fields_ = [] |
| 520 | + self._test_issue18060(Vector) |
| 521 | + |
| 522 | + @unittest.skipIf(_architecture() == ('64bit', 'WindowsPE'), "can't test Windows x64 build") |
| 523 | + @unittest.skipUnless(sys.byteorder == 'little', "can't test on this platform") |
| 524 | + def test_issue18060_c(self): |
| 525 | + # This test case calls |
| 526 | + # PyCStructUnionType_update_stgdict() for each |
| 527 | + # _fields_ assignment. |
| 528 | + class Base(Structure): |
| 529 | + _fields_ = [('y', c_double)] |
| 530 | + class Mid(Base): |
| 531 | + _fields_ = [] |
| 532 | + class Vector(Mid): |
| 533 | + _fields_ = [('x', c_double)] |
| 534 | + self._test_issue18060(Vector) |
| 535 | + |
475 | 536 | def test_array_in_struct(self):
|
476 | 537 | # See bpo-22273
|
477 | 538 |
|
|
0 commit comments