Skip to content

Commit

Permalink
Revert "Re-apply pull request #165 from nucleic/member-mro"
Browse files Browse the repository at this point in the history
This reverts commit 288c8bd.

# Conflicts:
#	releasenotes.rst
  • Loading branch information
MatthieuDartiailh committed Oct 18, 2022
1 parent 572ef07 commit 5c61846
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 60 deletions.
29 changes: 2 additions & 27 deletions atom/atom.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
Callable,
ClassVar,
Dict,
FrozenSet,
Iterator,
List,
Mapping,
MutableMapping,
Optional,
Set,
Tuple,
TypeVar,
Union,
Expand Down Expand Up @@ -260,7 +258,6 @@ class so that the CAtom class can allocate exactly enough space for
"""

__atom_members__: Mapping[str, Member]
__atom_specific_members__: FrozenSet[str]

def __new__( # noqa: C901
meta,
Expand Down Expand Up @@ -338,22 +335,13 @@ def __new__( # noqa: C901

# Walk the mro of the class, excluding itself, in reverse order
# collecting all of the members into a single dict. The reverse
# update preserves the mro of overridden members. We use only known
# specific members to also preserve the mro in presence of multiple
# inheritance.
# update preserves the mro of overridden members.
members: MutableMapping[str, Member] = {}
for base in reversed(cls.__mro__[1:-1]):
if base is not CAtom and issubclass(base, CAtom):
# Except if somebody abuses the system and create a non-Atom subclass
# of CAtom, this works
# Mypy does not narrow the type from the above test hence the ignores
members.update(
{
k: v
for k, v in base.__atom_members__.items() # type: ignore
if k in base.__atom_specific_members__ # type: ignore
}
)
members.update(base.__atom_members__) # type: ignore

# The set of members which live on this class as opposed to a
# base class. This enables the code which hooks up the various
Expand Down Expand Up @@ -384,9 +372,6 @@ def __new__( # noqa: C901
setattr(cls, clone.name, clone)
resolved_index += 1

# Keep track of the members whose behavior is specific to this class.
specific_members: Set[Member] = set()

# Walk the dict a second time to collect the class members. This
# assigns the name and the index to the member. If a member is
# overriding an existing member, the memory index of the old
Expand All @@ -397,7 +382,6 @@ def __new__( # noqa: C901
value = value.clone()
setattr(cls, key, value)
owned_members.add(value)
specific_members.add(value)
value.set_name(key)
if key in members:
supermember = members[key]
Expand All @@ -413,10 +397,6 @@ def __new__( # noqa: C901
# so that the behavior of the subclass is not modified.

def clone_if_needed(m):
# The member may have been cloned due to slot conflicts but that
# does not make it specific. However, each member on which function
# is called is guaranteed to be specific.
specific_members.add(m)
if m not in owned_members:
m = m.clone()
members[m.name] = m
Expand Down Expand Up @@ -513,11 +493,6 @@ def clone_if_needed(m):
# by CAtom to query for the members and member count as needed.
cls.__atom_members__ = members

# Keep a reference to the specific members dict on the class. Specific
# members are members which are defined or altered in the class. This
# is used to ensure proper MRO resolution for members.
cls.__atom_specific_members__ = frozenset(m.name for m in specific_members)

return cls


Expand Down
33 changes: 0 additions & 33 deletions tests/test_atom.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
Atom,
Int,
MissingMemberWarning,
Str,
Value,
atomref,
observe,
Expand Down Expand Up @@ -104,38 +103,6 @@ class Multi(Multi1, Multi2):
assert m.index != m2.index


def test_member_mro_in_multiple_inheritance():
"""Test that we respect the MRO for members."""

class A(Atom):
a = Str("a")

class B(Atom):
b = Str("b")

class AB(A, B):
pass

class A2(A):
a = Str("a2")

class C(AB, A2):
pass

# C mro AB -> A2 -> A -> B -> Atom
# a is not defined or altered on AB so we expect to get A2 behavior
assert C().a == "a2"

# When AB alters a we expect to see it
class BB(A, B):
a = set_default("b")

class D(BB, A2):
pass

assert D().a == "b"


def test_cloning_members():
"""Test cloning a member when appropriate.
Expand Down

0 comments on commit 5c61846

Please sign in to comment.