8000 Update the tests · python/cpython@cee51f5 · GitHub
[go: up one dir, main page]

Skip to content

Commit cee51f5

Browse files
Update the tests
1 parent 3958c51 commit cee51f5

File tree

3 files changed

+303
-98
lines changed

3 files changed

+303
-98
lines changed

Include/internal/pycore_interp.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,11 @@ _PyInterpreterState_SetFinalizing(PyInterpreterState *interp, PyThreadState *tst
295295
}
296296

297297

298-
extern int64_t _PyInterpreterState_ObjectToID(PyObject *);
299298

300-
// Export for the _xxinterpchannels module.
299+
// Exports for the _testinternalcapi module.
300+
PyAPI_FUNC(int64_t) _PyInterpreterState_ObjectToID(PyObject *);
301301
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(int64_t);
302302
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpIDObject(PyObject *);
303-
304303
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *);
305304
PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *);
306305
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *);

Lib/test/test_capi/test_misc.py

Lines changed: 182 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,132 +2089,219 @@ def test_module_state_shared_in_global(self):
20892089
@requires_subinterpreters
20902090
class InterpreterIDTests(unittest.TestCase):
20912091

2092-
InterpreterID = _testcapi.get_interpreterid_type()
2092+
# InterpreterID = _testcapi.get_interpreterid_type()
20932093

2094-
def new_interpreter(self):
2095-
def ensure_destroyed(interpid):
2094+
def check_id(self, interpid, *, force=False):
2095+
if force:
2096+
return
2097+
2098+
def add_interp_cleanup(self, interpid):
2099+
def ensure_destroyed():
20962100
try:
20972101
_interpreters.destroy(interpid)
20982102
except _interpreters.InterpreterNotFoundError:
20992103
pass
2104+
self.addCleanup(ensure_destroyed)
2105+
2106+
def new_interpreter(self):
21002107
id = _interpreters.create()
2101-
self.addCleanup(lambda: ensure_destroyed(id))
2108+
self.add_interp_cleanup(id)
21022109
return id
21032110

2104-
def test_with_int(self):
2105-
id = self.InterpreterID(10, force=True)
2111+
def test_conversion(self):
2112+
convert = _testinternalcapi.normalize_interp_id
21062113

2107-
self.assertEqual(int(id), 10)
2114+
with self.subTest('int'):
2115+
interpid = convert(10)
2116+
self.assertEqual(interpid, 10)
21082117

2109-
def test_coerce_id(self):
2110-
class Int(str):
2111-
def __index__(self):
2112-
return 10
2118+
with self.subTest('coerced'):
2119+
class MyInt(str):
2120+
def __index__(self):
2121+
return 10
21132122

2114-
id = self.InterpreterID(Int(), force=True)
2115-
self.assertEqual(int(id), 10)
2123+
interpid = convert(MyInt())
2124+
self.assertEqual(interpid, 10)
21162125

2117-
def test_bad_id(self):
21182126
for badid in [
21192127
object(),
21202128
10.0,
21212129
'10',
21222130
b'10',
21232131
]:
2124-
with self.subTest(badid):
2132+
with self.subTest(f'bad: {badid}'):
21252133
with self.assertRaises(TypeError):
2126-
self.InterpreterID(badid)
2134+
convert(badid)
21272135

21282136
badid = -1
2129-
with self.subTest(badid):
2137+
with self.subTest(f'bad: {badid}'):
21302138
with self.assertRaises(ValueError):
2131-
self.InterpreterID(badid)
2139+
convert(badid)
21322140

21332141
badid = 2**64
2134-
with self.subTest(badid):
2142+
with self.subTest(f'bad: {badid}'):
21352143
with self.assertRaises(OverflowError):
2136-
self.InterpreterID(badid)
2144+
convert(badid)
21372145

2138-
def test_exists(self):
2139-
id = self.new_interpreter()
2140-
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2141-
self.InterpreterID(int(id) + 1) # unforced
2146+
def test_lookup(self):
2147+
with self.subTest('exists'):
2148+
interpid = self.new_interpreter()
2149+
self.assertTrue(
2150+
_testinternalcapi.interpreter_exists(interpid))
21422151

2143-
def test_does_not_exist(self):
2144-
id = self.new_interpreter()
2145-
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2146-
self.InterpreterID(int(id) + 1) # unforced
2152+
with self.subTest('does not exist'):
2153+
interpid = _testinternalcapi.unused_interpreter_id()
2154+
self.assertFalse(
2155+
_testinternalcapi.interpreter_exists(interpid))
21472156

2148-
def test_destroyed(self):
2149-
id = _interpreters.create()
2150-
_interpreters.destroy(id)
2151-
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2152-
self.InterpreterID(id) # unforced
2153-
2154-
def test_str(self):
2155-
id = self.InterpreterID(10, force=True)
2156-
self.assertEqual(str(id), '10')
2157-
2158-
def test_repr(self):
2159-
id = self.InterpreterID(10, force=True)
2160-
self.assertEqual(repr(id), 'InterpreterID(10)')
2161-
2162-
def test_equality(self):
2163-
id1 = self.new_interpreter()
2164-
id2 = self.InterpreterID(id1)
2165-
id3 = self.InterpreterID(
2166-
self.new_interpreter())
2167-
2168-
self.assertTrue(id2 == id2) # identity
2169-
self.assertTrue(id2 == id1) # int-equivalent
2170-
self.assertTrue(id1 == id2) # reversed
2171-
self.assertTrue(id2 == int(id2))
2172-
self.assertTrue(id2 == float(int(id2)))
2173-
self.assertTrue(float(int(id2)) == id2)
2174-
self.assertFalse(id2 == float(int(id2)) + 0.1)
2175-
self.assertFalse(id2 == str(int(id2)))
2176-
self.assertFalse(id2 == 2**1000)
2177-
self.assertFalse(id2 == float('inf'))
2178-
self.assertFalse(id2 == 'spam')
2179-
self.assertFalse(id2 == id3)
2180-
2181-
self.assertFalse(id2 != id2)
2182-
self.assertFalse(id2 != id1)
2183-
self.assertFalse(id1 != id2)
2184-
self.assertTrue(id2 != id3)
2157+
with self.subTest('destroyed'):
2158+
interpid = _interpreters.create()
2159+
_interpreters.destroy(interpid)
2160+
self.assertFalse(
2161+
_testinternalcapi.interpreter_exists(interpid))
21852162

21862163
def test_linked_lifecycle(self):
2187-
id1 = _interpreters.create()
2188-
_testinternalcapi.unlink_interpreter_refcount(id1)
2189-
self.assertEqual(
2190-
_testinternalcapi.get_interpreter_refcount(id1),
2191-
0)
2192-
2193-
id2 = self.InterpreterID(id1)
2164+
def create():
2165+
interpid = _testinternalcapi.new_interpreter()
2166+
self.add_interp_cleanup(interpid)
2167+
return interpid
2168+
2169+
exists = _testinternalcapi.interpreter_exists
2170+
is_linked = _testinternalcapi.interpreter_refcount_linked
2171+
link = _testinternalcapi.link_interpreter_refcount
2172+
unlink = _testinternalcapi.unlink_interpreter_refcount
2173+
get_refcount = _testinternalcapi.get_interpreter_refcount
2174+
incref = _testinternalcapi.interpreter_incref
2175+
decref = _testinternalcapi.interpreter_decref
2176+
2177+
with self.subTest('does not exist'):
2178+
interpid = _testinternalcapi.unused_interpreter_id()
2179+
self.assertFalse(
2180+
exists(interpid))
2181+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2182+
is_linked(interpid)
2183+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2184+
link(interpid)
2185+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2186+
unlink(interpid)
2187+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2188+
get_refcount(interpid)
2189+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2190+
incref(interpid)
2191+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2192+
decref(interpid)
2193+
2194+
with self.subTest('destroyed'):
2195+
interpid = _interpreters.create()
2196+
_interpreters.destroy(interpid)
2197+
self.assertFalse(
2198+
exists(interpid))
2199+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2200+
is_linked(interpid)
2201+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2202+
link(interpid)
2203+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2204+
unlink(interpid)
2205+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2206+
get_refcount(interpid)
2207+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2208+
incref(interpid)
2209+
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2210+
decref(interpid)
2211+
2212+
# A new interpreter will start out not linked, with a refcount of 0.
2213+
interpid = create()
2214+
self.assertFalse(
2215+
is_linked(interpid))
21942216
self.assertEqual(
2195-
_testinternalcapi.get_interpreter_refcount(id1),
2196-
1)
2197-
2198-
# The interpreter isn't linked to ID objects, so it isn't destroyed.
2199-
del id2
2200-
self.assertEqual(
2201-
_testinternalcapi.get_interpreter_refcount(id1),
2202-
0)
2203-
2204-
_testinternalcapi.link_interpreter_refcount(id1)
2205-
self.assertEqual(
2206-
_testinternalcapi.get_interpreter_refcount(id1),
2207-
0)
2208-
2209-
id3 = self.InterpreterID(id1)
2210-
self.assertEqual(
2211-
_testinternalcapi.get_interpreter_refcount(id1),
2212-
1)
2213-
2214-
# The interpreter is linked now so is destroyed.
2215-
del id3
2216-
with self.assertRaises(_interpreters.InterpreterNotFoundError):
2217-
_testinternalcapi.get_interpreter_refcount(id1)
2217+
0, get_refcount(interpid))
2218+
2219+
with self.subTest('never linked'):
2220+
interpid = create()
2221+
2222+
# Incref will not automatically link it.
2223+
incref(interpid)
2224+
self.assertFalse(
2225+
is_linked(interpid))
2226+
self.assertEqual(
2227+
1, get_refcount(interpid))
2228+
2229+
# It isn't linked so it isn't destroyed.
2230+
decref(interpid)
2231+
self.assertTrue(
2232+
exists(interpid))
2233+
self.assertFalse(
2234+
is_linked(interpid))
2235+
self.assertEqual(
2236+
0, get_refcount(interpid))
2237+
2238+
with self.subTest('linking/unlinking at refcount 0 does not destroy'):
2239+
interpid = create()
2240+
2241+
link(interpid)
2242+
self.assertTrue(
2243+
exists(interpid))
2244+
2245+
unlink(interpid)
2246+
self.assertTrue(
2247+
exists(interpid))
2248+
2249+
with self.subTest('link -> incref -> decref => destroyed'):
2250+
interpid = create()
2251+
2252+
# Linking it will not change the refcount.
2253+
link(interpid)
2254+
self.assertTrue(
2255+
is_linked(interpid))
2256+
self.assertEqual(
2257+
0, get_refcount(interpid))
2258+
2259+
# Decref with a refcount of 0 is not allowed.
2260+
incref(interpid)
2261+
self.assertEqual(
2262+
1, get_refcount(interpid))
2263+
2264+
# When linked, decref back to 0 destroys the interpreter.
2265+
decref(interpid)
2266+
self.assertFalse(
2267+
exists(interpid))
2268+
2269+
with self.subTest('linked after incref'):
2270+
interpid = create()
2271+
2272+
incref(interpid)
2273+
self.assertEqual(
2274+
1, get_refcount(interpid))
2275+
2276+
# Linking it will not reset the refcount.
2277+
link(interpid)
2278+
self.assertEqual(
2279+
1, get_refcount(interpid))
2280+
2281+
with self.subTest('decref to 0 after unlink does not destroy'):
2282+
interpid = create()
2283+
2284+
link(interpid)
2285+
self.assertTrue(
2286+
is_linked(interpid))
2287+
2288+
incref(interpid)
2289+
self.assertEqual(
2290+
1, get_refcount(interpid))
2291+
2292+
# Unlinking it will not change the refcount.
2293+
unlink(interpid)
2294+
self.assertFalse(
2295+
is_linked(interpid))
2296+
self.assertEqual(
2297+
1, get_refcount(interpid))
2298+
2299+
# When linked, decref back to 0 destroys the interpreter.
2300+
decref(interpid)
2301+
self.assertTrue(
2302+
exists(interpid))
2303+
self.assertEqual(
2304+
0, get_refcount(interpid))
22182305

22192306

22202307
class BuiltinStaticTypesTests(unittest.TestCase):

0 commit comments

Comments
 (0)
0