diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index 349044116b9d18..cccfe3565db6e0 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -525,8 +525,13 @@ struct _py_func_state { /****** type state *********/ /* For now we hard-code this to a value for which we are confident - all the static builtin types will fit (for all builds). */ -#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 203 + all the static builtin types will fit (for all builds). + If you add a new static type to the standard library, you may have to + update one of these numbers. + */ +#define _Py_NUM_MANAGED_PREINITIALIZED_TYPES 120 +#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES \ + (_Py_NUM_MANAGED_PREINITIALIZED_TYPES + 83) #define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10 #define _Py_MAX_MANAGED_STATIC_TYPES \ (_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES + _Py_MAX_MANAGED_STATIC_EXT_TYPES) diff --git a/InternalDocs/parser.md b/InternalDocs/parser.md index 1d0ffe6d40d078..1bb4cdea5439f1 100644 --- a/InternalDocs/parser.md +++ b/InternalDocs/parser.md @@ -819,6 +819,13 @@ directory on the CPython repository and manually call the parser generator by ex $ python -m pegen python ``` +> [!CAUTION] +> Python's grammar (the `Grammar/python.gram` file) is written for the +> C backend. To experiment, you will need to write a grammar +> without C-specific parts like actions and the trailer. +> See [#133560](https://github.com/python/cpython/issues/133560) +> and [#96424](https://github.com/python/cpython/issues/96424) for more information. + This will generate a file called `parse.py` in the same directory that you can use to parse some input: diff --git a/Lib/pdb.py b/Lib/pdb.py index c4bc0020646b0d..4dd974b375c259 100644 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -376,7 +376,7 @@ def get_default_backend(): def _pyrepl_available(): """return whether pdb should use _pyrepl for input""" - if not os.getenv("PYTHON_BASIC_REPL"): + if os.getenv("PYTHON_BASIC_REPL"): CAN_USE_PYREPL = False else: try: diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index c5171f3388c965..db90019975521e 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -4753,6 +4753,16 @@ def foo(self): stdout, stderr = self.run_pdb_script(script, commands) self.assertIn("The specified object 'C.foo' is not a function", stdout) + def test_pyrepl_available(self): + with patch.dict(os.environ, {"PYTHON_BASIC_REPL": "1"}): + self.assertFalse(pdb._pyrepl_available()) + + with patch.dict(os.environ, {}, clear=True): + mod = types.ModuleType("_pyrepl.main") + mod.CAN_USE_PYREPL = True + with patch.dict("sys.modules", {"_pyrepl.main": mod}): + self.assertTrue(pdb._pyrepl_available()) + class ChecklineTests(unittest.TestCase): def setUp(self): diff --git a/Misc/NEWS.d/next/Library/2026-04-30-14-21-26.gh-issue-149173.KJqZm0.rst b/Misc/NEWS.d/next/Library/2026-04-30-14-21-26.gh-issue-149173.KJqZm0.rst new file mode 100644 index 00000000000000..019ab76b863577 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-30-14-21-26.gh-issue-149173.KJqZm0.rst @@ -0,0 +1,2 @@ +Fix inverted :envvar:`PYTHON_BASIC_REPL` environment check in +``pdb._pyrepl_available``. diff --git a/Objects/object.c b/Objects/object.c index e6a764435bc292..e0e26bb50d3653 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2526,7 +2526,7 @@ extern PyTypeObject _PyMemoryIter_Type; extern PyTypeObject _PyPositionsIterator; extern PyTypeObject _Py_GenericAliasIterType; -static PyTypeObject* static_types[] = { +static PyTypeObject* static_types[_Py_NUM_MANAGED_PREINITIALIZED_TYPES] = { // The two most important base types: must be initialized first and // deallocated last. &PyBaseObject_Type, @@ -2644,6 +2644,9 @@ static PyTypeObject* static_types[] = { &_PyUnion_Type, #ifdef _Py_TIER2 &_PyUOpExecutor_Type, +#else + // The array should have the same size on all builds; see gh-149139 + NULL, #endif &_PyWeakref_CallableProxyType, &_PyWeakref_ProxyType, @@ -2668,6 +2671,9 @@ _PyTypes_InitTypes(PyInterpreterState *interp) // All other static types (unless initialized elsewhere) for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { PyTypeObject *type = static_types[i]; + if (type == NULL) { + continue; + } if (_PyStaticType_InitBuiltin(interp, type) < 0) { return _PyStatus_ERR("Can't initialize builtin type"); } @@ -2708,6 +2714,9 @@ _PyTypes_FiniTypes(PyInterpreterState *interp) // their base classes. for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) { PyTypeObject *type = static_types[i]; + if (type == NULL) { + continue; + } _PyStaticType_FiniBuiltin(interp, type); } }