Commit c6e7fce
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.
Always calling object.__new__(cls) to bypass the cache broke CI, which
pins portage 3.0.70: through 3.0.81.3, portage.dep.Atom subclasses str
instead of using an intern cache, so object.__new__(cls) raised
"TypeError: object.__new__(Atom) is not safe, use str.__new__()".
Atom.__new__ now checks whether portage.dep.Atom is still a str subclass
and, if so, allocates via str.__new__(cls, atom) instead; that version
has no cache to bypass, so this is just correct allocation, not a
workaround.
Bug: https://bugs.gentoo.org/981521
Signed-off-by: Matt Turner <mattst88@gentoo.org>1 parent de9169f commit c6e7fce
1 file changed
Lines changed: 14 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
48 | 62 | | |
49 | 63 | | |
50 | 64 | | |
| |||
0 commit comments