[Python-Dev] PEP 509: Add a private version to dict

Brett Cannon brett at python.org
Wed Jan 20 19:08:12 EST 2016


On Wed, 20 Jan 2016 at 15:46 Victor Stinner <victor.stinner at gmail.com>
wrote:

> Hi,
>
> 2016-01-20 22:18 GMT+01:00 Glenn Linderman <v+python at g.nevcal.com>:
> > On 1/20/2016 12:50 PM, Brett Cannon wrote:
> >>
> >> A global (shared between all dicts) unit64 ma_version is actually quite
> >> reliable -- if a program does 1,000,000 dict modifications per second,
> >> it would take it 600,000 years till wrap-around.
>
> I think that Yury found a bug in FAT Python. I didn't test the case
> when the builtins dictionary is replaced after the definition of the
> function. To be more concrete: when a function is executed in a
> different namespace using exec(code, namespace). That's why I like the
> PEP process, it helps to find all issues before going too far :-)
>
> I like the idea of global counter for dictionary versions. It means
> that the dictionary constructor increases this counter instead of
> always starting to 0.
>
> FYI a fat.GuardDict keeps a strong reference to the dictionary. For
> some guards, I hesitated to store the object identifier and/or using a
> weak reference. An object identifier is not reliable because the
> object can be destroyed and a new object, completly different, or of
> the same type, can get the same identifier.
>
> > But would invalidate everything, instead of just a fraction of things, on
> > every update to anything that is monitored...
>
> I don't understand this point.
>

I think Glenn was assuming we had a single, global version # that all dicts
shared *without* having a per-dict version ID. The key thing here is that
we have a global counter that tracks the number of mutations for *all*
dictionaries
but whose value we store as a *per-dictionary* value. That ends up making
the version ID inherently both a token representing the state of any dict
but also the uniqueness of the dict since no two dictionaries will ever
have the same version ID.


>
> In short, the guard only has to compare two 64 bit integers in the
> fast-path, when nothing changed. For a namespace, it means that no
> value was replaced in this namespace.
>
> If a different namespace is modified, the version of the watched
> namespace does not change, so we are still in the fast-path.
>
> If a value is replaced in the watched namespace, but not the watched
> variable, we have to take a slow-path, hopefully only once.
>
> The worst case is when a value different than the watched value is
> modified between each guard check. In this case, we always need a dict
> lookup. An heuristic can be chosen to decide to give up after N tries.
> Currently, fat.GuardDict always retries.
>

Does "retries" mean "check if the value really changed, and if it hasn't
then just update the version ID the guard checks"?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20160121/59b1cbb9/attachment-0001.html>


More information about the Python-Dev mailing list