Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADD] Move from richcmp to __eq__() #182

Merged
merged 2 commits into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 39 additions & 105 deletions ConfigSpace/conditions.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -115,41 +115,27 @@ cdef class AbstractCondition(ConditionComponent):
self.child_vector_id = -1
self.parent_vector_id = -1

def __richcmp__(self, other: Any, int op):
def __eq__(self, other: Any) -> bool:
"""
Todo: With Cython 2.7 this function can be replaced by using the six
Python special methods (__eq__(), __lt__(),...).
(--> https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html\
#rich-comparisons)

Before 2.7 there were no separate methods for the individual rich
comparison operations. Instead there is a single method __richcmp__()
which takes an integer indicating which operation is to be performed,
as follows:
< 0
== 2
> 4
<= 1
!= 3
>= 5
"""
if isinstance(other, self.__class__):
This method implements a comparison between self and another
object.

if op == 2:
if self.child != other.child:
return False
elif self.parent != other.parent:
return False
return self.value == other.value
Additionally, it defines the __ne__() as stated in the
documentation from python:
By default, object implements __eq__() by using is, returning NotImplemented
in the case of a false comparison: True if x is y else NotImplemented.
For __ne__(), by default it delegates to __eq__() and inverts the result
unless it is NotImplemented.

elif op == 3:
if (self.child != other.child or
self.parent != other.parent or self.value != other.value):
return True
else:
return False
"""
if not isinstance(other, self.__class__):
mfeurer marked this conversation as resolved.
Show resolved Hide resolved
return False

return NotImplemented
if self.child != other.child:
return False
elif self.parent != other.parent:
return False
return self.value == other.value

def set_vector_idx(self, hyperparameter_to_idx: dict):
self.child_vector_id = hyperparameter_to_idx[self.child.name]
Expand Down Expand Up @@ -545,42 +531,6 @@ cdef class InCondition(AbstractCondition):
self.value = values
self.vector_values = [self.parent._inverse_transform(value) for value in self.values]

def __richcmp__(self, other: Any, int op):
"""
Todo: With Cython 2.7 this function can be replaced by using the six
Python special methods (__eq__(), __lt__(),...).
(--> https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html\
#rich-comparisons)

Before 2.7 there were no separate methods for the individual rich
comparison operations. Instead there is a single method __richcmp__()
which takes an integer indicating which operation is to be performed,
as follows:
< 0
== 2
> 4
<= 1
!= 3
>= 5
"""
if isinstance(other, self.__class__):

if op == 2:
if self.child != other.child:
return False
elif self.parent != other.parent:
return False
return self.values == other.values

elif op == 3:
if (self.child != other.child or
self.parent != other.parent or self.values != other.values):
return True
else:
return False

return NotImplemented

def __repr__(self) -> str:
return "%s | %s in {%s}" % (self.child.name, self.parent.name,
", ".join(
Expand Down Expand Up @@ -618,47 +568,31 @@ cdef class AbstractConjunction(ConditionComponent):
raise ValueError("All Conjunctions and Conditions must have "
"the same child.")

def __richcmp__(self, other: Any, int op):
def __eq__(self, other: Any) -> bool:
"""
Todo: With Cython 2.7 this function can be replaced by using the six
Python special methods (__eq__(), __lt__(),...).
(--> https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html\
#rich-comparisons)

Before 2.7 there were no separate methods for the individual rich
comparison operations. Instead there is a single method __richcmp__()
which takes an integer indicating which operation is to be performed,
as follows:
< 0
== 2
> 4
<= 1
!= 3
>= 5
This method implements a comparison between self and another
object.

Additionally, it defines the __ne__() as stated in the
documentation from python:
By default, object implements __eq__() by using is, returning NotImplemented
in the case of a false comparison: True if x is y else NotImplemented.
For __ne__(), by default it delegates to __eq__() and inverts the result
unless it is NotImplemented.

"""
if isinstance(other, self.__class__):
if len(self.components) != len(other.components):
if op == 2:
return False
if op == 3:
return True
else:
return NotImplemented

for component, other_component in \
zip(self.components, other.components):
eq = component == other_component
if op == 2:
if not eq:
return False
elif op == 3:
if eq:
return False
else:
raise NotImplemented
return True
if not isinstance(other, self.__class__):
return False

if len(self.components) != len(other.components):
return False

for component, other_component in zip(self.components, other.components):
if (component != other_component):
return False

return True

return NotImplemented

def __copy__(self):
return self.__class__(*[copy.copy(comp) for comp in self.components])
Expand Down
91 changes: 35 additions & 56 deletions ConfigSpace/forbidden.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,39 +57,29 @@ cdef class AbstractForbiddenComponent(object):
def __repr__(self):
pass

def __richcmp__(self, other: Any, int op):
def __eq__(self, other: Any) -> bool:
"""
Todo: With Cython 2.7 this function can be replaced by using the six
Python special methods (__eq__(), __lt__(),...).
(--> https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html\
#rich-comparisons)

Before 2.7 there were no separate methods for the individual rich
comparison operations. Instead there is a single method __richcmp__()
which takes an integer indicating which operation is to be performed,
as follows:
< 0
== 2
> 4
<= 1
!= 3
>= 5
This method implements a comparison between self and another
object.

Additionally, it defines the __ne__() as stated in the
documentation from python:
By default, object implements __eq__() by using is, returning NotImplemented
in the case of a false comparison: True if x is y else NotImplemented.
For __ne__(), by default it delegates to __eq__() and inverts the result
unless it is NotImplemented.

"""
if not isinstance(other, self.__class__):
return False

if self.value is None:
self.value = self.values
if other.value is None:
other.value = other.values

if isinstance(other, self.__class__):
if other.value is None:
other.value = other.values
if op == 2:
return (self.value == other.value and
self.hyperparameter.name == other.hyperparameter.name)

elif op == 3:
return False == (self.value == other.value and
self.hyperparameter.name == other.hyperparameter.name)

return NotImplemented
return (self.value == other.value and
self.hyperparameter.name == other.hyperparameter.name)

def __hash__(self) -> int:
"""Override the default hash behavior (that returns the id or the object)"""
Expand Down Expand Up @@ -353,39 +343,28 @@ cdef class AbstractForbiddenConjunction(AbstractForbiddenComponent):
def __copy__(self):
return self.__class__([copy(comp) for comp in self.components])

def __richcmp__(self, other: Any, int op):
def __eq__(self, other: Any) -> bool:
"""
Todo: With Cython 2.7 this function can be replaced by using the six
Python special methods (__eq__(), __lt__(),...).
(--> https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html\
#rich-comparisons)

Before 2.7 there were no separate methods for the individual rich
comparison operations. Instead there is a single method __richcmp__()
which takes an integer indicating which operation is to be performed,
as follows:
< 0
== 2
> 4
<= 1
!= 3
>= 5
This method implements a comparison between self and another
object.

Additionally, it defines the __ne__() as stated in the
documentation from python:
By default, object implements __eq__() by using is, returning NotImplemented
in the case of a false comparison: True if x is y else NotImplemented.
For __ne__(), by default it delegates to __eq__() and inverts the result
unless it is NotImplemented.
"""

if isinstance(other, self.__class__):
if op == 2:
if self.n_components != other.n_components:
return False
return all([self.components[i] == other.components[i]
for i in range(self.n_components)])
if not isinstance(other, self.__class__):
return False

elif op == 3:
if self.n_components == other.n_components:
return False
return any([self.components[i] != other.components[i]
for i in range(self.n_components)])
if self.n_components != other.n_components:
return False

return all([self.components[i] == other.components[i]
for i in range(self.n_components)])

return NotImplemented

cpdef set_vector_idx(self, hyperparameter_to_idx):
for component in self.components:
Expand Down
Loading