diff --git a/pep-0679.rst b/pep-0679.rst new file mode 100644 index 00000000000..87fe85202e1 --- /dev/null +++ b/pep-0679.rst @@ -0,0 +1,694 @@ +PEP: 679 +Title: A Per-Interpreter GIL +Author: Eric Snow +PEP-Delegate: +Discussions-To: python-dev@python.org +Status: Draft +Type: Informational +Created: 01-01-2022 +Python-Version: 3.11 +Post-History: 01-01-2022 +Resolution: + + +Abstract +======== + +CPython has supported multiple interpreters in the same process (AKA +"subinterpreters") since version 1.5 (1997). The feature has been +available via the C-API. [c-api]_ :pep:`554` discusses some of the value +of subinterpreters and the merits of exposing them to Python code. +However, that PEP purposefully avoids discussion about isolation, +especially related to the GIL. This PEP fills that gap. + +Currently subinterpreters operate in +`relative isolation from one another `_. +However, there is a substantial amount of CPython's runtime state that +is shared. Improving isolation by mostly eliminating that shared state +provides a number of benefits. Most notably, interpreters could +fully operate in parallel on multi-core hosts, +where currently the GIL prevents this. + +This proposal identifies a path forward to reach maximum practical +isolation between interpreters. Notably, this includes the GIL. + + +Proposal +======== + +The specific objective here is to make the GIL per-interpreter. +At a high level, we'll accomplish that with the following steps: + +1. consolidate global state (including objects) into ``_PyRuntimeState`` +2. move it all down into ``PyInterpreterState`` +3. finally, move the GIL down into ``PyInterpreterState`` + +Some of the moves in (2) can be done independently, in parallel. +Some must be done in a particular order. +Some must be done all at once. + +Per-Interpreter State +--------------------- + +The GIL protects concurrent access of most of CPython's runtime state. +So all that GIL-protected global state must move to each interpreter +before the GIL can. + +(In some cases, other mechanisms can be used to ensure thread-safe +sharing instead, such as locks or "immortal" objects.) + +CPython's runtime state is currently stored in the following places: + +* static/global C variables + + immutable, often ``const`` + + treated as immutable + + set during runtime init, then treated as immutable + + mutable, protected by the GIL + + mutable, protected by some other lock + + mutable, atomic +* ``_PyRuntime`` (``_PyRuntimeState``) +* ``PyInterpreterState``, held by ``_PyRuntime`` +* ``PyThreadState``, held by ``PyInterpreterState`` +* thread-specific storage (TSS) +* passed through the C stack (starting in ``main()``) +* process-global resources that must be shared + +(See `State To Be Moved`_ for a detailed list.) + +To get a per-interpreter GIL, the mutable globals protected by the GIL +must move to ``PyInterpreterState``, along with any similar parts of +``_PyRuntimeState``. This basically includes all Python objects. +All other state can remain global. + +Scale of Work +------------- + +The number of global variables to be moved is large, but most +are Python objects that can be dealt with in large groups (like +``Py_IDENTIFIER``). In nearly all cases, dealing with all these +globals is highly mechanical. That doesn't require cleverness +but instead requires someone to put in the time. + +(Note that at the time this PEP was written, many globals had +already been moved into ``_PyRuntimeState`` +or into ``PyInterpreterState`` or the equivalent.) + +This PEP also addresses several less trivial issues: + +* impact on extension module maintainers +* global objects directly exposed in the C-API +* memory allocators +* how to prevent new global variables? (See `Tooling`_.) + + +Motivation +========== + +The fundamental problem we're solving here is a lack of true multi-core +parallelism (for Python code) in CPython's interpreter. The GIL is the +cause. While it usually isn't a problem in practice, at the very least +it make Python's multi-core story murky, which makes the GIL +a consistent distraction. + +Isolated interpreters are also an effective mechanism to support +certain concurrency models. :pep:`554` discusses this in more detail. + +Other Benefits +-------------- + +Most of the effort needed for a per-interpreter GIL has benefits that +make it worth doing anyway: + +* greatly reduces the number of C globals (best practice for C code) +* makes subinterpreter behavior more reliable +* fixes long-standing runtime bugs that otherwise haven't been prioritized +* exposes (and fix) previously unknown runtime bugs +* cleaner runtime initialization (:pep:`432`, :pep:`587`) +* cleaner and more complete runtime finalization +* makes it easier to identify runtime state (in one place rather than many files) +* makes it easier to statically allocate runtime state in a consistent way +* makes objects created via C and Python objects more consistent +* better memory locality for runtime state +* structural layering of the C-API (header files) +* more... + +Furthermore, much of the work here benefits other CPython-related +projects: + +* performance improvements ("faster-cpython") +* pre-fork application deployment +* extension module isolation (see :pep:`384`, :pep:`489`, :pep:`630`, etc.) +* embedding + +Existing Use of Subinterpreters +------------------------------- + +Subinterpreters have been used (via the C-API) for many years. However, +until recently the feature wasn't widely known, not extensively used. +One notable public project has been using them a long time: mod_wsgi. +In the last few years they have been gaining traction. + +Here are some of the public projects using subinterpreters currently: + +.. XXX +* mod_wsgi +* ... + +Note that, with :pep:`554`, subinterpreters usage would likely grow +significantly (via Python code rather than the C-API). + + +Rationale +========= + +[Describe why particular design decisions were made.] + +During initial investigations in 2014, a variety of possible solutions +for multi-core Python were explored, including: + +* release the GIL in extension modules +* other Python implementations (e.g. Jython, IronPython) +* remove the GIL (e.g. gilectomy, "no-gil") +* ``multiprocessing`` +* other parallelism tools (e.g. dask, ray, MPI) +* give up on multi-core (e.g. async, do nothing) + +Each had drawbacks without simple solutions: + +* extensions: doesn't help with Python code +* alt. implementations: CPython dominates +* get rid of the GIL: too much technical risk (at the time) +* multiprocessing: too much work to make it more accessible; high penalties in some situations (at large scale, Windows) +* new tools: not a fit for the stdlib +* give up: this can only end in tears + +Even in 2014 it was fairly clear that a solution using subinterpreters +did not have a high level of technical risk and that most of the work +was worth doing anyway. +(The downside was the volume of work to be done.) + +The "no-gil" Project +-------------------- + +Note that the "no-gil" project is currently active and may be successful +in removing the GIL. There isn't any real conflict with this PEP +and it is unlikely that one would prevent the other from succeeding. +Furthermore, they face a number of similar challenges. In fact +there is a fair amount of overlap in necessary work, which +would benefit both projects. + +At worst, one project might seem to make the other unnecessary. +However, they both have distinct value. Each supports a different +concurrency model to take advantage of multi-core. "no-gil" makes +the existing "threading" module support multi-core. This PEP does +so with an isolated "process" model (see :pep:`554`) using the +existing "subinterpreters" feature. Also, both the "threading" +module and subinterpreters are already used by enough people +that we couldn't remove them anyway. + +Objects in the C-API +-------------------- + +One non-trivial problem to be solved was what to do about Python objects +exposed in the public C-API (and stable ABI). There were only a few +valid options: + +* turn the symbols into lookup function calls +* only use the symbols as markers +* "immortal" objects + +.. XXX + +... + +Other Design Decisions +---------------------- + +.. XXX + +* per-interpreter allocators +* preventing new global variables + + +Impact +====== + +Backwards Compatibility +----------------------- + +[Describe potential impact and severity on pre-existing code.] + +Alternate Python Implementations +-------------------------------- + +(not affected? this is CPython-only) + +Security Implications +--------------------- + +[How could a malicious user take advantage of this new feature?] + +Maintainability +--------------- + +... + +Performance +----------- + +... + + +Concerns +======== + +TBD + + +Specification +============= + +[Describe the syntax and semantics of any new language feature.] + +State To Be Moved +----------------- + +catalog variables + +* ... + +Tooling +------- + +... + +Completed Work +-------------- + +At the time this PEP was written, the following work had already been +completed: + +* cleanup of runtime initialization (see :pep:`432` / :pep:`587`) +* isolation for stdlib extension modules (see :pep:`384` / :pep:`3121` / :pep:`489`) +* addition of ``_PyRuntimeState`` +* ... + +Documentation +------------- + +TBD + + +How to Teach This +================= + +[How to teach users, new and experienced, how to apply the PEP to their work.] + + +About Subinterpreters +===================== + +(copied from PEP 554, needs editing) + +Concurrency +----------- + +Concurrency is a challenging area of software development. Decades of +research and practice have led to a wide variety of concurrency models, +each with different goals. Most center on correctness and usability. + +One class of concurrency models focuses on isolated threads of +execution that interoperate through some message passing scheme. A +notable example is `Communicating Sequential Processes`_ (CSP) (upon +which Go's concurrency is roughly based). The isolation inherent to +subinterpreters makes them well-suited to this approach. + +Shared data +----------- + +Subinterpreters are inherently isolated (with caveats explained below), +in contrast to threads. So the same communicate-via-shared-memory +approach doesn't work. Without an alternative, effective use of +concurrency via subinterpreters is significantly limited. + +The key challenge here is that sharing objects between interpreters +faces complexity due to various constraints on object ownership, +visibility, and mutability. At a conceptual level it's easier to +reason about concurrency when objects only exist in one interpreter +at a time. At a technical level, CPython's current memory model +limits how Python *objects* may be shared safely between interpreters; +effectively objects are bound to the interpreter in which they were +created. Furthermore, the complexity of *object* sharing increases as +subinterpreters become more isolated, e.g. after GIL removal. + +Consequently,the mechanism for sharing needs to be carefully considered. +There are a number of valid solutions, several of which may be +appropriate to support in Python. This proposal provides a single basic +solution: "channels". Ultimately, any other solution will look similar +to the proposed one, which will set the precedent. Note that the +implementation of ``Interpreter.run()`` will be done in a way that +allows for multiple solutions to coexist, but doing so is not +technically a part of the proposal here. + +Regarding the proposed solution, "channels", it is a basic, opt-in data +sharing mechanism that draws inspiration from pipes, queues, and CSP's +channels. [fifo]_ + +As simply described earlier by the API summary, +channels have two operations: send and receive. A key characteristic +of those operations is that channels transmit data derived from Python +objects rather than the objects themselves. When objects are sent, +their data is extracted. When the "object" is received in the other +interpreter, the data is converted back into an object owned by that +interpreter. + +To make this work, the mutable shared state will be managed by the +Python runtime, not by any of the interpreters. Initially we will +support only one type of objects for shared state: the channels provided +by ``create_channel()``. Channels, in turn, will carefully manage +passing objects between interpreters. + +This approach, including keeping the API minimal, helps us avoid further +exposing any underlying complexity to Python users. Along those same +lines, we will initially restrict the types that may be passed through +channels to the following: + +* None +* bytes +* str +* int +* channels + +Limiting the initial shareable types is a practical matter, reducing +the potential complexity of the initial implementation. There are a +number of strategies we may pursue in the future to expand supported +objects and object sharing strategies. + +Interpreter Isolation +--------------------- + +CPython's interpreters are intended to be strictly isolated from each +other. Each interpreter has its own copy of all modules, classes, +functions, and variables. The same applies to state in C, including in +extension modules. The CPython C-API docs explain more. [caveats]_ + +However, there are ways in which interpreters share some state. First +of all, some process-global state remains shared: + +* file descriptors +* builtin types (e.g. dict, bytes) +* singletons (e.g. None) +* underlying static module data (e.g. functions) for + builtin/extension/frozen modules + +There are no plans to change this. + +Second, some isolation is faulty due to bugs or implementations that did +not take subinterpreters into account. This includes things like +extension modules that rely on C globals. [cryptography]_ In these +cases bugs should be opened (some are already): + +* readline module hook functions (http://bugs.python.org/issue4202) +* memory leaks on re-init (http://bugs.python.org/issue21387) + +Finally, some potential isolation is missing due to the current design +of CPython. Improvements are currently going on to address gaps in this +area: + +* GC is not run per-interpreter [global-gc]_ +* at-exit handlers are not run per-interpreter [global-atexit]_ +* extensions using the ``PyGILState_*`` API are incompatible [gilstate]_ +* interpreters share memory management (e.g. allocators, gc) +* interpreters share the GIL + +Existing Usage +-------------- + +Subinterpreters are not a widely used feature. In fact, the only +documented cases of widespread usage are +`mod_wsgi `_, +`OpenStack Ceph `_, and +`JEP `_. On the one hand, these cases +provide confidence that existing subinterpreter support is relatively +stable. On the other hand, there isn't much of a sample size from which +to judge the utility of the feature. + + +Deferred Functionality +====================== + +TBD + + +Reference Implementation +======================== + +[Link to any existing implementation and details about its state, e.g. proof-of-concept.] + + +Rejected Ideas +============== + +[Why certain ideas that were brought while discussing this PEP were not ultimately pursued.] + + +Open Issues +=========== + +[Any points that are still being decided/discussed.] + + +References +========== + +.. [c-api] + https://docs.python.org/3/c-api/init.html#sub-interpreter-support + +.. [caveats] + https://docs.python.org/3/c-api/init.html#bugs-and-caveats + +.. [petr-c-ext] + https://mail.python.org/pipermail/import-sig/2016-June/001062.html + https://mail.python.org/pipermail/python-ideas/2016-April/039748.html + +.. [cryptography] + https://github.com/pyca/cryptography/issues/2299 + +.. [global-gc] + http://bugs.python.org/issue24554 + +.. [gilstate] + https://bugs.python.org/issue10915 + http://bugs.python.org/issue15751 + +.. [global-atexit] + https://bugs.python.org/issue6531 + +.. [bug-rate] + https://mail.python.org/pipermail/python-ideas/2017-September/047094.html + +.. [benefits] + https://mail.python.org/pipermail/python-ideas/2017-September/047122.html + +.. [main-thread] + https://mail.python.org/pipermail/python-ideas/2017-September/047144.html + https://mail.python.org/pipermail/python-dev/2017-September/149566.html + +.. [reset_globals] + https://mail.python.org/pipermail/python-dev/2017-September/149545.html + +.. [multi-core-project] + https://github.com/ericsnowcurrently/multi-core-python + +.. [cache-line-ping-pong] + https://mail.python.org/archives/list/python-dev@python.org/message/3HVRFWHDMWPNR367GXBILZ4JJAUQ2STZ/ + +.. [extension-docs] + https://docs.python.org/3/extending/index.html + + +PEP 384 -- Defining a Stable ABI, which added C API for creating heap types +PEP 432 -- Simplifying the CPython startup sequence +PEP 489 -- Multi-phase extension module initialization +PEP 573 -- Module State Access from C Extension Methods +PEP 630 -- Isolating Extension Modules +PEP 3121 -- ... + +https://bugs.python.org/issue40512 [subinterpreters] Meta issue: per-interpreter GIL +https://bugs.python.org/issue45953 Statically allocate interpreter states as much as possible. + +globals: +https://bugs.python.org/issue36876 [subinterpreters] Global C variables are a problem +https://bugs.python.org/issue45887 [subinterpreters] Pull all interpreter-global objects into one place. +https://bugs.python.org/issue46006 [subinterpreter] _PyUnicode_EqualToASCIIId() issue with subinterpreters +https://bugs.python.org/issue41692 Deprecate immortal interned strings: PyUnicode_InternImmortal() + +interpreter isolation: +https://bugs.python.org/issue40533 [subinterpreters] Don't share Python objects between interpreters +https://bugs.python.org/issue39376 Avoid modifying the process global environment (not thread safe) +https://bugs.python.org/issue40521 ~ [subinterpreters] Make free lists and unicode caches per-interpreter +https://bugs.python.org/issue39511 [subinterpreters] Per-interpreter singletons (None, True, False, etc.) +https://bugs.python.org/issue40522 [subinterpreters] Get the current Python interpreter state from Thread Local Storage (autoTSSkey) +https://bugs.python.org/issue43313 feature: support pymalloc for subinterpreters. each subinterpreter has pymalloc_state + +stdlib isolation: +https://bugs.python.org/issue40077 Convert static types to heap types: use PyType_FromSpec() +https://bugs.python.org/issue42972 [C API] Heap types (PyType_FromSpec) must fully implement the GC protocol +https://bugs.python.org/issue15870 PyType_FromSpec should take metaclass as an argument +https://bugs.python.org/issue45113 [subinterpreters][C API] Add a new function to create PyStructSequence from Heap. + +possible restrictions: +https://bugs.python.org/issue40234 [subinterpreters] Disallow daemon threads in subinterpreters optionally +https://bugs.python.org/issue38435 Start the deprecation cycle for subprocess preexec_fn +https://bugs.python.org/issue42969 pthread_exit & PyThread_exit_thread from PyEval_RestoreThread etc. are harmful +https://bugs.python.org/issue40453 ~ [subinterpreters] Add PyConfig._isolated_interpreter: isolated subinterpreters +https://bugs.python.org/issue42346 [subinterpreters] Deny os.fork() in subinterpreters? +https://bugs.python.org/issue38865 [subinterpreters] Can Py_Finalize() be called if the current interpreter is not the main interpreter? + +C-API objects: +https://bugs.python.org/issue40601 [C API] Hide static types from the limited C API +https://bugs.python.org/issue43503 [subinterpreters] PyObject statics exposed in the limited API break isolation. +https://bugs.python.org/issue43442 multicorevm: guarantee type multi sub interpreters safe + +immortal objects: +https://bugs.python.org/issue40255 Fixing Copy on Writes from reference counting + +extension module isolation: +https://bugs.python.org/issue34309 Trouble when reloading extension modules. +https://bugs.python.org/issue32973 Importing the same extension module under multiple names breaks non-reinitialisable extension modules + +finalization bugs: +https://bugs.python.org/issue6642 returning after forking a child thread doesn't call Py_Finalize +https://bugs.python.org/issue36476 Runtime finalization assumes all other threads have exited. +https://bugs.python.org/issue36780 Interpreter exit blocks waiting for futures of shut-down ThreadPoolExecutors +https://bugs.python.org/issue42647 Unable to use concurrent.futures in atexit hook +https://bugs.python.org/issue43944 Processes in Python 3.9 exiting with code 1 when It's created inside a ThreadPoolExecutor +https://bugs.python.org/issue43588 [Subinterpreters]: use static variable under building Python with --with-experimental-isolated-subinterpreters cause crash. +https://bugs.python.org/issue44100 test__xxsubinterpreters: test_one() fails in AMD64 Fedora Stable 3.x: "Fatal Python error: Py_EndInterpreter: thread still has a frame" +https://bugs.python.org/issue36225 [subinterpreters] Lingering subinterpreters should be implicitly cleared on shutdown + +isolation bugs: +https://bugs.python.org/issue4202 [subinterpreters] Multiple interpreters and readline module hook functions. +https://bugs.python.org/issue10915 ~ [subinterpreters] Make the PyGILState API compatible with multiple interpreters +https://bugs.python.org/issue15751 [subinterpreters] Make the PyGILState API compatible with subinterpreters +https://bugs.python.org/issue24554 ~ [subinterpreters] GC should happen when a subinterpreter is destroyed +https://bugs.python.org/issue31517 MainThread association logic is fragile +https://bugs.python.org/issue39042 Use the runtime's main thread ID in the threading module. +https://bugs.python.org/issue40231 [subinterpreters] Fix pending calls in subinterpreters +https://bugs.python.org/issue40082 ~ trip_signal() gets NULL tstate on Windows on CTRL+C +https://bugs.python.org/issue44532 multi subinterpreters use _PyStructSequence_InitType failed. +https://bugs.python.org/issue46070 _PyImport_FixupExtensionObject() regression causing a crash in subintepreters +https://bugs.python.org/issue46036 Single-phase initialized modules gets initialized multiple times in 3.10.0 + +other bugs: +https://bugs.python.org/issue44374 PyThreadState_IsCurrent bug under building Python with --with-experimental-isolated-subinterpreters + +other (mine): +https://bugs.python.org/issue24553 [subinterpreters] Improve test coverage for subinterpreters +https://bugs.python.org/issue33607 [subinterpreters] Explicitly track object ownership (and allocator). + +PEP 554: +https://bugs.python.org/issue40572 [subinterpreters] Support basic asynchronous cross-interpreter operations. +https://bugs.python.org/issue33608 Add a cross-interpreter-safe mechanism to indicate that an object may be destroyed. +https://bugs.python.org/issue35813 shared memory construct to avoid need for serialization between processes +https://bugs.python.org/issue37293 concurrent.futures.InterpreterPoolExecutor + + +2005-06 https://mail.python.org/archives/list/python-dev@python.org/thread/B5JSYFLBIVKY4QXPBIUNUFG5OMGJX2CZ/#N3GI5BMQM3KQY7G5K3VAAIOC3V7QF2L3 + prioritize +2006-07 https://mail.python.org/archives/list/python-dev@python.org/thread/FNCZEX6PFCNJMIBPHSWHP4SSMP3A24HL/ + not strong isolation +2008-09 https://mail.python.org/archives/list/capi-sig@python.org/thread/UK4H6SRAEWIJM63VWBI724D2W7KYQLD6/#QYEUP6RRPCEMSOGDXD7YMIWKYBH32PUJ + not better than subprocesses (yet) +2008-12 https://mail.python.org/archives/list/python-dev@python.org/thread/GJC53OSY3IH7IGOTSLBIXMPDSUKAT2DL + a replacement for threads? +2009-07 https://mail.python.org/archives/list/python-ideas@python.org/thread/Y6DKIWDCNBGI6ZSTY2W4UDB5PYHQELAS/#UJ6WV4DQ455X7JFF77QUXFUJN6OEJZPE + shared objects must be immutable +2010-11 https://mail.python.org/archives/list/python-ideas@python.org/thread/I325GHF3HGVHTP4EOYNXFCU2I7QR7JMZ + need complete isolation +2011-08 https://mail.python.org/archives/list/python-dev@python.org/thread/ICJ46G7EAXTXRCTWLDERJ4N7NCZOS4ML/#XSVBXPL44ZSGFRRKXDPCTEQ75NDOR22L + allows GIL removal +2012-01 https://mail.python.org/archives/list/python-dev@python.org/thread/J3BPTMFFFJSJO52FFYMCWFNUJDSAYTKU + exposed ref leaks +2012-02 https://mail.python.org/archives/list/python-dev@python.org/thread/U26PM3JR2SIJFTNYWCSQ3NQA6EWBX722 + exposed missing incref +2012-06 https://mail.python.org/archives/list/python-dev@python.org/thread/NQJ2EIIG5SO763VHK7AA55X4CCJCA3T6/#OX3CCLABXIUKLP3LYT4YC2YLZS4F5HYG + can't share signatures on shared builtins +2013-06 https://mail.python.org/archives/list/python-dev@python.org/thread/7OC242PC4QB6XDDUZFP3LKZRCZJPH2DK + exposed bug +2014-07 https://mail.python.org/archives/list/python-dev@python.org/thread/QZBJBAR726XVSQOHF7WFFPYJ4BVUDVRM/#5U43ZX5WTTACYDL427J3YQTW7G6B4CZQ + benefits of moving to heap types for stdlib modules + +2015-06 https://mail.python.org/archives/list/python-ideas@python.org/thread/SVEG3TDLKFVPYD4PMYLT6J5L4H5BDT7Z + my original post +2015-07 https://mail.python.org/archives/list/python-ideas@python.org/thread/UVNNFEXOY3RHQTE2653VCIWOW7TPPLMP + concurrency models +2015-09 https://mail.python.org/archives/list/python-dev@python.org/thread/WMHLJ2XUDWZC22CDWRIMQRYA5RSEIJFT + are subinterpreters really solving multi-core? +2017-05 https://mail.python.org/archives/list/python-ideas@python.org/thread/TYLXUOANY6LWSUVCQPGJKNPPHOUNC54R + my new post +2017-09 https://mail.python.org/archives/list/python-ideas@python.org/thread/HQQWEE527HG3ILJVKQTXVSJIQO6NUSIA +2017-09 https://mail.python.org/archives/list/python-dev@python.org/thread/NBWMA6LVD22XOUYC5ZMPBFWDQOECRP77 +2017-09 https://mail.python.org/archives/list/python-dev@python.org/thread/EG4FSFG5E3O22FTIUQOXMQ6X6B5X3DP7 +2017-12 https://mail.python.org/archives/list/python-dev@python.org/thread/BCSRGAMCYB3NGXNU42U66J56XNZVMQP2 + PEP 554 +2018-04 https://mail.python.org/archives/list/python-dev@python.org/thread/MDBM27UNMEFNTS4FQRS3QAPZJRGX2OP2 + PEP 573 +2018-07 https://mail.python.org/archives/list/python-ideas@python.org/thread/OX5FMIATOMPNRSAF54QH25SEEGZFFJWV + questions about subinterpreters +2019-01 https://mail.python.org/archives/list/python-dev@python.org/thread/JJ7UB5BNVBZ5NLNDBNNUGSQVR6CUBAK5 + numpy breaks in subinterpreters +2018-05 https://mail.python.org/archives/list/python-dev@python.org/thread/UVP753UFBAYMEVOKT24KMHVITFYWGNPV + my PyCon talk +2018-09 https://mail.python.org/archives/list/python-dev@python.org/thread/GVQOMWXUDYLBXZ2MMIDX5D6X7X42VQV7 + static globals +2019-11 https://mail.python.org/archives/list/python-dev@python.org/thread/PQBGECVGVYFTVDLBYURLCXA3T7IPEHHO + passing around tstate +2020-04 https://mail.python.org/archives/list/python-dev@python.org/thread/3HVRFWHDMWPNR367GXBILZ4JJAUQ2STZ + (me) delay PEP 554? +2020-04 https://mail.python.org/archives/list/python-dev@python.org/thread/3KS3KACCJBUCHUGRBZ3R6WUGZXOKKWZ5 + PEP 554 feedback +2020-04 https://mail.python.org/archives/list/python-dev@python.org/thread/S674C2BJ7NHKB3SOJF4VFRXVNQDNSCHP + get rid of static types? +2020-05 https://mail.python.org/archives/list/python-dev@python.org/thread/X2KPCSRVBD2QD5GP5IMXXZTGZ46OXD3D + PEP 554 +2020-05 https://mail.python.org/archives/list/python-dev@python.org/thread/S5GZZCEREZLA2PEMTVFBCDM52H4JSENR + Victor's experiment +2020-06 https://mail.python.org/archives/list/python-dev@python.org/thread/5YNWDIYECDQDYQ7IFYJS6K5HUDUAWTT6 + too many changes? +2020-06 https://mail.python.org/archives/list/python-dev@python.org/thread/EV7F7Z6PLPWJU7SD2UPFEYKYUWU4ZJXZ + PEP 620 +2020-07 https://mail.python.org/archives/list/python-dev@python.org/thread/EJF67ZM2HMLWCVKAYNU4JCATO7CRILOS + GIL in stable ABI? +2021-01 https://mail.python.org/archives/list/python-dev@python.org/thread/C4ILXGPKBJQYUN5YDMTJOEOX7RHOD4S3 + exposed refleaks +2021-03 https://mail.python.org/archives/list/capi-sig@python.org/thread/INLCGPMTYFLRTWQL7RB4MUQZ37JAFRAU + (me) no subinterpreters in limited API? +2021-03 https://mail.python.org/archives/list/capi-sig@python.org/thread/G7FLMXII4V2J4Q625PDJIZWZ6JQKSJRH + (me) get rid of stable API? +2021-12 https://mail.python.org/archives/list/python-dev@python.org/thread/PNLBJBNIQDMG2YYGPBCTGOKOAVXRBJWY + my plans for subinterpreters (need PEP?) +2021-12 https://mail.python.org/archives/list/python-dev@python.org/thread/X3ZOSP2A4RTSKTBZ4XYHROSJBONCEDID + (me) impact on big projects +2021-12 https://mail.python.org/archives/list/python-dev@python.org/thread/7O3FUA52QGTVDC6MDAV5WXKNFEDRK5D6 + (me) immortal objects +2012-12 https://mail.python.org/archives/list/python-dev@python.org/thread/QTY25AHCLOXRCQ2LADUUZFVKNVLLYS25 + static types and singletons in C-API + + +Copyright +========= + +This document is placed in the public domain or under the +CC0-1.0-Universal license, whichever is more permissive. + + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: