PEP 699: Remove private dict version field added in PEP 509

Hello! PEP 699 is a PEP to undo the changes in PEP 509. It’s very short so please give it a read and leave any comments in this discourse thread.

CC @vstinner and @markshannon


Is it worth pointing out in the PEP which version the ma_version_tag field was added in? Are we talking about something fairly new or that’s been around for a while.


It’s 3.6. However, it wasn’t actually properly used until 3.8 (at least by CPython) for LOAD_GLOBAL.

This looks good to me. FWIW Cinder does not use the version tag for any optimizations, but does rely on dictionary watchers, which will be simpler to implement if we don’t have to steal bits from the version tag while still updating it (as done in add support for watching writes to selected dictionaries · Issue #91052 · python/cpython · GitHub) but can just eliminate it instead.

I was pinged about this on Github but responding here because it’s probably more useful and more visible.

I don’t think this should cause Cython any problem. Cython only uses that feature on some Python anyway and falls back to public-API-only code for older versions/PyPy/limited API/etc. So it’s just a case of changing the version guard that selects this feature.

The PEP is now online at

Just for reference, Deepmind’s S6 (GitHub - deepmind/s6) used ma_version_tag for hidden classes: s6/util.h at 557187c514e9e9f7e42ad060ecbd50c5483f02c9 · deepmind/s6 · GitHub
(This is just for reference since Deepmind stopped work on S6.)

The header section needs hard returns so it reads like…

PEP: 699
Title: Remove private dict version field added in PEP 509
Author: Ken Jin <>

Click on “raw” button on GitHub to see newlines :wink:

The current SC will leave the decision to the next one. However, we see no reason to avoid the usual backwards compatibility policy: the field can be deprecated with a compiler warning, and removed after a minimum of two releases.
If there’s a pressing reason to remove it now, please put it in the PEP. An extra pointer in all dicts isn’t great, but also not terrible if it’d just be there for the deprecation period.

— Petr, on behalf of the SC


Note that I consider ma_version_tag part of the public C API. These things weren’t as clear back in 2016, but it’s included from <Python.h>, not documented as private, and according to PEP 509 it’s clearly meant to be used outside CPython.


Thanks SC for considering the PEP.

I will adjust it and resubmit it to the new SC for consideration!


The (“new”) SC is happy to accept the current version of PEP 699. Thanks, everyone, for your contributions.


FWIW, I’m proposing to add a _Py_DEPRECATED_EXTERNALLY macro you can use. Feel free to copy it to your PR so it can be merged first (or make a different one).