Skip to content

Commit

Permalink
Resolve diamond shaped inheritance
Browse files Browse the repository at this point in the history
In the previous implementation `firewall.AccessList` would inherit from
`l3.AccessList` which inherited from `base.Base`.
`firewall.AccessList` also inherited from
`firewall.FirewallPolicyObject`. That lead to a Diamond Shaped
inheritance. The fact that `FirewallPolicyObject` and `l3.AccessList`
had constructors with different arguments made it difficult to let
`super()` call the constructors with different arguments.

To resolve that, the diamond Shaped inheritance was resolved making it
clearer which `__init__`'s `super()` calls which superclasses
constructor.

The different signatures of the constructor still pose a problem, hence
we send all supplemental arguments of a constructor to `**kwargs`.
  • Loading branch information
swagner-de committed Aug 16, 2024
1 parent aa54681 commit 7a6528a
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 12 deletions.
5 changes: 1 addition & 4 deletions asr1k_neutron_l3/models/neutron/l3/access_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@

class AccessList(base.Base):
def __init__(self, id, drop_on_17_3=False):
# If we use super(AccessList, self) here the MRO of type(self) is determining the __init__
# we call. If self is a child, that could lead to not calling base.Base.__init__().
# If the second argument to super is a type, the returned method is unbound, hence we pass self to it.
super(AccessList, AccessList).__init__(self)
super().__init__()
self.id = id
self._drop_on_17_3 = drop_on_17_3
self.rules = []
Expand Down
2 changes: 1 addition & 1 deletion asr1k_neutron_l3/models/neutron/l3/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


class Base(object):
def __init__(self):
def __init__(self, **kwargs):
self.contexts = asr1k_pair.ASR1KPair().contexts

@property
Expand Down
14 changes: 7 additions & 7 deletions asr1k_neutron_l3/models/neutron/l3/firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,23 @@
LOG = logging.getLogger(__name__)


class FirewallPolicyObject(base.Base):
class FirewallPolicyMixin:

PREFIX = None

@classmethod
def get_id_by_policy_id(cls, policy_id: str) -> str:
if not cls.PREFIX:
raise NotImplementedError("Class derived from 'FirewallPolicyObject' must define static var 'PREFIX'")
raise NotImplementedError("Class derived from 'FirewallPolicyMixin' must define static var 'PREFIX'")
return f"{cls.PREFIX}{policy_id}"

def __init__(self, policy_id: str):
def __init__(self, policy_id=None, **kwargs):
self.policy_id = policy_id
self.id = self.get_id_by_policy_id(self.policy_id)
super().__init__()
super().__init__(id=self.id, **kwargs)


class AccessList(access_list.AccessList, FirewallPolicyObject):
class AccessList(FirewallPolicyMixin, access_list.AccessList):

PREFIX = const.FWAAS_ACL_PREFIX
ACTIONS = {
Expand Down Expand Up @@ -98,7 +98,7 @@ def __init__(self, policy_id: str, rules: List[dict]):
self.rules.append(access_list.Rule(**rule_args))


class ClassMap(FirewallPolicyObject):
class ClassMap(FirewallPolicyMixin, base.Base):
PREFIX = const.FWAAS_CLASS_MAP_PREFIX

@property
Expand All @@ -107,7 +107,7 @@ def _rest_definition(self):
type='inspect', prematch='match-all')


class ServicePolicy(FirewallPolicyObject):
class ServicePolicy(FirewallPolicyMixin, base.Base):
PREFIX = const.FWAAS_SERVICE_POLICY_PREFIX

@property
Expand Down

0 comments on commit 7a6528a

Please sign in to comment.