Skip to content

Commit 1aa0355

Browse files
committed
atom: force a fresh instance instead of using portage's intern cache
portage.dep.Atom.__new__ now interns instances in a module-level cache keyed only by the atom string and parse flags, not by the constructor's class. Constructing gentoolkit.atom.Atom with a string already interned elsewhere as a plain portage.dep.Atom silently returns that cached instance instead of one of our subclass, so methods we override (like intersects()) resolve to portage's implementation instead of ours. Reproduced with portage d52efac67: gentoolkit.atom.Atom() returned a plain portage.dep.Atom whenever the same atom string had already been interned by portage itself, which happens constantly in normal use. This also explains why equery d was under-reporting some reverse dependencies: portage.dep.Atom.intersects() and our own implementation don't always agree. Bug: https://bugs.gentoo.org/981521 Signed-off-by: Matt Turner <mattst88@gentoo.org>
1 parent de9169f commit 1aa0355

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

pym/gentoolkit/atom.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ class Atom(portage.dep.Atom, CPV):
4545
# Necessary for Portage versions < 2.1.7
4646
_atoms = weakref.WeakValueDictionary()
4747

48+
def __new__(cls, *args, **kwargs):
49+
# portage.dep.Atom.__new__ interns instances in a module-level
50+
# cache keyed only by the atom string (not by cls), so calling
51+
# this subclass's constructor with an already-interned string can
52+
# silently hand back a plain portage.dep.Atom instead of one of
53+
# ours. Always build a fresh instance so we stay this subclass.
54+
return object.__new__(cls)
55+
4856
@property
4957
def operator(self):
5058
# Old portage stored operator as a plain instance attribute in

0 commit comments

Comments
 (0)