@@ -19,6 +19,68 @@ class CAPITest(unittest.TestCase):
1919
2020 maxDiff = None
2121
22+ @unittest .skipIf (_testlimitedcapi is None , 'need _testlimitedcapi module' )
23+ def test_sys_getattr (self ):
24+ # Test PySys_GetAttr()
25+ sys_getattr = _testlimitedcapi .sys_getattr
26+
27+ self .assertIs (sys_getattr ('stdout' ), sys .stdout )
28+ with support .swap_attr (sys , '\U0001f40d ' , 42 ):
29+ self .assertEqual (sys_getattr ('\U0001f40d ' ), 42 )
30+
31+ with self .assertRaisesRegex (RuntimeError , r'lost sys\.nonexistent' ):
32+ sys_getattr ('nonexistent' )
33+ with self .assertRaisesRegex (RuntimeError , r'lost sys\.\U0001f40d' ):
34+ sys_getattr ('\U0001f40d ' )
35+ self .assertRaises (TypeError , sys_getattr , 1 )
36+ self .assertRaises (TypeError , sys_getattr , [])
37+ # CRASHES sys_getattr(NULL)
38+
39+ @unittest .skipIf (_testlimitedcapi is None , 'need _testlimitedcapi module' )
40+ def test_sys_getattrstring (self ):
41+ # Test PySys_GetAttrString()
42+ getattrstring = _testlimitedcapi .sys_getattrstring
43+
44+ self .assertIs (getattrstring (b'stdout' ), sys .stdout )
45+ with support .swap_attr (sys , '\U0001f40d ' , 42 ):
46+ self .assertEqual (getattrstring ('\U0001f40d ' .encode ()), 42 )
47+
48+ with self .assertRaisesRegex (RuntimeError , r'lost sys\.nonexistent' ):
49+ getattrstring (b'nonexistent' )
50+ with self .assertRaisesRegex (RuntimeError , r'lost sys\.\U0001f40d' ):
51+ getattrstring ('\U0001f40d ' .encode ())
52+ self .assertRaises (UnicodeDecodeError , getattrstring , b'\xff ' )
53+ # CRASHES getattrstring(NULL)
54+
55+ @unittest .skipIf (_testlimitedcapi is None , 'need _testlimitedcapi module' )
56+ def test_sys_getoptionalattr (self ):
57+ # Test PySys_GetOptionalAttr()
58+ getoptionalattr = _testlimitedcapi .sys_getoptionalattr
59+
60+ self .assertIs (getoptionalattr ('stdout' ), sys .stdout )
61+ with support .swap_attr (sys , '\U0001f40d ' , 42 ):
62+ self .assertEqual (getoptionalattr ('\U0001f40d ' ), 42 )
63+
64+ self .assertIs (getoptionalattr ('nonexistent' ), AttributeError )
65+ self .assertIs (getoptionalattr ('\U0001f40d ' ), AttributeError )
66+ self .assertRaises (TypeError , getoptionalattr , 1 )
67+ self .assertRaises (TypeError , getoptionalattr , [])
68+ # CRASHES getoptionalattr(NULL)
69+
70+ @unittest .skipIf (_testlimitedcapi is None , 'need _testlimitedcapi module' )
71+ def test_sys_getoptionalattrstring (self ):
72+ # Test PySys_GetOptionalAttrString()
73+ getoptionalattrstring = _testlimitedcapi .sys_getoptionalattrstring
74+
75+ self .assertIs (getoptionalattrstring (b'stdout' ), sys .stdout )
76+ with support .swap_attr (sys , '\U0001f40d ' , 42 ):
77+ self .assertEqual (getoptionalattrstring ('\U0001f40d ' .encode ()), 42 )
78+
79+ self .assertIs (getoptionalattrstring (b'nonexistent' ), AttributeError )
80+ self .assertIs (getoptionalattrstring ('\U0001f40d ' .encode ()), AttributeError )
81+ self .assertRaises (UnicodeDecodeError , getoptionalattrstring , b'\xff ' )
82+ # CRASHES getoptionalattrstring(NULL)
83+
2284 @support .cpython_only
2385 @unittest .skipIf (_testlimitedcapi is None , 'need _testlimitedcapi module' )
2486 def test_sys_getobject (self ):
@@ -29,7 +91,7 @@ def test_sys_getobject(self):
2991 with support .swap_attr (sys , '\U0001f40d ' , 42 ):
3092 self .assertEqual (getobject ('\U0001f40d ' .encode ()), 42 )
3193
32- self .assertIs (getobject (b'nonexisting ' ), AttributeError )
94+ self .assertIs (getobject (b'nonexistent ' ), AttributeError )
3395 with support .catch_unraisable_exception () as cm :
3496 self .assertIs (getobject (b'\xff ' ), AttributeError )
3597 self .assertEqual (cm .unraisable .exc_type , UnicodeDecodeError )
0 commit comments