|  | 
| 3 | 3 | 
 | 
| 4 | 4 | from collections import OrderedDict | 
| 5 | 5 | import _thread | 
|  | 6 | +import contextlib | 
| 6 | 7 | import importlib.machinery | 
| 7 | 8 | import importlib.util | 
| 8 | 9 | import os | 
|  | 
| 40 | 41 | Py_DEBUG = hasattr(sys, 'gettotalrefcount') | 
| 41 | 42 | 
 | 
| 42 | 43 | 
 | 
|  | 44 | +NULL = None | 
|  | 45 | + | 
| 43 | 46 | def decode_stderr(err): | 
| 44 | 47 |     return err.decode('utf-8', 'replace').replace('\r', '') | 
| 45 | 48 | 
 | 
| @@ -910,6 +913,46 @@ def some(): | 
| 910 | 913 |         with self.assertRaises(SystemError): | 
| 911 | 914 |             _testcapi.function_get_module(None)  # not a function | 
| 912 | 915 | 
 | 
|  | 916 | +    def test_sys_getobject(self): | 
|  | 917 | +        getobject = _testcapi.sys_getobject | 
|  | 918 | + | 
|  | 919 | +        self.assertIs(getobject(b'stdout'), sys.stdout) | 
|  | 920 | +        with support.swap_attr(sys, '\U0001f40d', 42): | 
|  | 921 | +            self.assertEqual(getobject('\U0001f40d'.encode()), 42) | 
|  | 922 | + | 
|  | 923 | +        self.assertIs(getobject(b'nonexisting'), AttributeError) | 
|  | 924 | +        self.assertIs(getobject(b'\xff'), AttributeError) | 
|  | 925 | +        # CRASHES getobject(NULL) | 
|  | 926 | + | 
|  | 927 | +    def test_sys_setobject(self): | 
|  | 928 | +        setobject = _testcapi.sys_setobject | 
|  | 929 | + | 
|  | 930 | +        value = ['value'] | 
|  | 931 | +        value2 = ['value2'] | 
|  | 932 | +        try: | 
|  | 933 | +            self.assertEqual(setobject(b'newattr', value), 0) | 
|  | 934 | +            self.assertIs(sys.newattr, value) | 
|  | 935 | +            self.assertEqual(setobject(b'newattr', value2), 0) | 
|  | 936 | +            self.assertIs(sys.newattr, value2) | 
|  | 937 | +            self.assertEqual(setobject(b'newattr', NULL), 0) | 
|  | 938 | +            self.assertFalse(hasattr(sys, 'newattr')) | 
|  | 939 | +            self.assertEqual(setobject(b'newattr', NULL), 0) | 
|  | 940 | +        finally: | 
|  | 941 | +            with contextlib.suppress(AttributeError): | 
|  | 942 | +                del sys.newattr | 
|  | 943 | +        try: | 
|  | 944 | +            self.assertEqual(setobject('\U0001f40d'.encode(), value), 0) | 
|  | 945 | +            self.assertIs(getattr(sys, '\U0001f40d'), value) | 
|  | 946 | +            self.assertEqual(setobject('\U0001f40d'.encode(), NULL), 0) | 
|  | 947 | +            self.assertFalse(hasattr(sys, '\U0001f40d')) | 
|  | 948 | +        finally: | 
|  | 949 | +            with contextlib.suppress(AttributeError): | 
|  | 950 | +                delattr(sys, '\U0001f40d') | 
|  | 951 | + | 
|  | 952 | +        with self.assertRaises(UnicodeDecodeError): | 
|  | 953 | +            setobject(b'\xff', value) | 
|  | 954 | +        # CRASHES setobject(NULL, value) | 
|  | 955 | + | 
| 913 | 956 | 
 | 
| 914 | 957 | class TestPendingCalls(unittest.TestCase): | 
| 915 | 958 | 
 | 
|  | 
0 commit comments