Skip to content

Commit

Permalink
Cleaner implementation of Predicate __init__ and __new__
Browse files Browse the repository at this point in the history
Instead of having the metaclass create a new __init__ for each Predicate
sub-class, have a single common __init__ and have __new__ test to make sure
only sub-classes are instantiated. This is cleaner and also works better with
pylint.

Thanks to @florianfisher91 for pointing this out.
  • Loading branch information
daveraja committed Oct 25, 2021
1 parent 4284313 commit 7e1be72
Showing 1 changed file with 20 additions and 26 deletions.
46 changes: 20 additions & 26 deletions clorm/orm/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2346,27 +2346,6 @@ def _predicate_init_by_positional_values(self, *args, **kwargs):
# Create the raw clingo.Symbol object
self._raw = None

# Constructor for every Predicate sub-class
def _predicate_constructor(self, *args, **kwargs):
if len(args) > 0:
if len(kwargs) > 1 or (len(kwargs) == 1 and "sign" not in kwargs):
raise ValueError(("Invalid Predicate initialisation: only \"sign\" is a "
"valid keyword argument when combined with positional "
"arguments: {}").format(kwargs))
_predicate_init_by_positional_values(self, *args,**kwargs)
elif "raw" in kwargs:
_predicate_init_by_raw(self, **kwargs)
else:
_predicate_init_by_keyword_values(self, **kwargs)

# Force the hash to be calculated and cached.
self._hash = None
self.__hash__()


def _predicate_base_constructor(self, *args, **kwargs):
raise TypeError(("Predicate/ComplexTerm must be sub-classed"))

#------------------------------------------------------------------------------
# Metaclass constructor support functions to create the fields
#------------------------------------------------------------------------------
Expand Down Expand Up @@ -2548,14 +2527,12 @@ def __new__(meta, name, bases, dct):

if name == "Predicate":
dct["_predicate"] = None
dct["__init__"] = _predicate_base_constructor
return super(_PredicateMeta, meta).__new__(meta, name, bases, dct)

# Create the metadata AND populate dct - the class dict (including the fields)

# Set the _meta attribute and constuctor
dct["_meta"] = _make_predicatedefn(name, dct)
dct["__init__"] = _predicate_constructor
dct["_field"] = _lateinit("{}._field".format(name))

parents = [ b for b in bases if issubclass(b, Predicate) ]
Expand Down Expand Up @@ -2645,10 +2622,27 @@ class Booking(Predicate):
#--------------------------------------------------------------------------
#
#--------------------------------------------------------------------------
def __init__(self):
raise NotImplementedError(("Class {} can only be instantiated through a "
"sub-class").format(self.__name__))
def __init__(self, *args, **kwargs):
if len(args) > 0:
if len(kwargs) > 1 or (len(kwargs) == 1 and "sign" not in kwargs):
raise ValueError(("Invalid Predicate initialisation: only \"sign\" is a "
"valid keyword argument when combined with positional "
"arguments: {}").format(kwargs))
_predicate_init_by_positional_values(self, *args,**kwargs)
elif "raw" in kwargs:
_predicate_init_by_raw(self, **kwargs)
else:
_predicate_init_by_keyword_values(self, **kwargs)

# Force the hash to be calculated and cached.
self._hash = None
self.__hash__()


def __new__(cls, *args, **kwargs):
if cls == __class__:
raise TypeError(("Predicate/ComplexTerm must be sub-classed"))
return super().__new__(cls)

#--------------------------------------------------------------------------
# Properties and functions for Predicate
Expand Down

0 comments on commit 7e1be72

Please sign in to comment.