@@ -113,76 +113,85 @@ def wraps(wrapped,
113113# underlying user provided method. Using this scheme, the __gt__ derived
114114# from a user provided __lt__ becomes:
115115#
116- # lambda self, other: _not_op_and_not_eq(self.__lt__, self, other))
117-
118- def _not_op ( op , other ):
119- # "not a < b" handles "a >= b"
120- # "not a < = b" handles "a > b"
121- # "not a >= b" handles "a < b"
122- # "not a > b" handles "a <= b"
123- op_result = op (other )
116+ # 'def __gt__( self, other):' + _not_op_and_not_eq % '__lt__'
117+
118+ # "not a < b" handles "a >= b"
119+ # "not a <= b" handles "a > b"
120+ # "not a > = b" handles "a < b"
121+ # "not a > b" handles "a <= b"
122+ _not_op = '''
123+ op_result = self.%s (other)
124124 if op_result is NotImplemented:
125125 return NotImplemented
126126 return not op_result
127+ '''
127128
128- def _op_or_eq ( op , self , other ):
129- # "a < b or a == b" handles "a <= b"
130- # "a > b or a == b" handles "a >= b"
131- op_result = op (other )
129+ # "a > b or a == b" handles "a >= b"
130+ # "a < b or a == b" handles "a <= b"
131+ _op_or_eq = '''
132+ op_result = self.%s (other)
132133 if op_result is NotImplemented:
133134 return NotImplemented
134135 return op_result or self == other
135-
136- def _not_op_and_not_eq (op , self , other ):
137- # "not (a < b or a == b)" handles "a > b"
138- # "not a < b and a != b" is equivalent
139- # "not (a > b or a == b)" handles "a < b"
140- # "not a > b and a != b" is equivalent
141- op_result = op (other )
136+ '''
137+
138+ # "not (a < b or a == b)" handles "a > b"
139+ # "not a < b and a != b" is equivalent
140+ # "not (a > b or a == b)" handles "a < b"
141+ # "not a > b and a != b" is equivalent
142+ _not_op_and_not_eq = '''
143+ op_result = self.%s(other)
142144 if op_result is NotImplemented:
143145 return NotImplemented
144146 return not op_result and self != other
147+ '''
145148
146- def _not_op_or_eq ( op , self , other ):
147- # "not a < = b or a == b" handles "a > = b"
148- # "not a >= b or a == b" handles "a <= b"
149- op_result = op (other )
149+ # "not a <= b or a == b" handles "a >= b"
150+ # "not a > = b or a == b" handles "a < = b"
151+ _not_op_or_eq = '''
152+ op_result = self.%s (other)
150153 if op_result is NotImplemented:
151154 return NotImplemented
152155 return not op_result or self == other
156+ '''
153157
154- def _op_and_not_eq ( op , self , other ):
155- # "a < = b and not a == b" handles "a < b"
156- # "a >= b and not a == b" handles "a > b"
157- op_result = op (other )
158+ # "a <= b and not a == b" handles "a < b"
159+ # "a > = b and not a == b" handles "a > b"
160+ _op_and_not_eq = '''
161+ op_result = self.%s (other)
158162 if op_result is NotImplemented:
159163 return NotImplemented
160164 return op_result and self != other
165+ '''
161166
162167def total_ordering (cls ):
163168 """Class decorator that fills in missing ordering methods"""
164169 convert = {
165- '__lt__' : [( '__gt__' , lambda self , other : _not_op_and_not_eq ( self . __lt__ , self , other )) ,
166- ( '__le__' , lambda self , other : _op_or_eq ( self . __lt__ , self , other )) ,
167- ( '__ge__' , lambda self , other : _not_op ( self . __lt__ , other ))] ,
168- '__le__' : [( '__ge__' , lambda self , other : _not_op_or_eq ( self . __le__ , self , other )) ,
169- ( '__lt__' , lambda self , other : _op_and_not_eq ( self . __le__ , self , other )) ,
170- ( '__gt__' , lambda self , other : _not_op ( self . __le__ , other ))] ,
171- '__gt__' : [( '__lt__' , lambda self , other : _not_op_and_not_eq ( self . __gt__ , self , other )) ,
172- ( '__ge__' , lambda self , other : _op_or_eq ( self . __gt__ , self , other )) ,
173- ( '__le__' , lambda self , other : _not_op ( self . __gt__ , other ))] ,
174- '__ge__' : [( '__le__' , lambda self , other : _not_op_or_eq ( self . __ge__ , self , other )) ,
175- ( '__gt__' , lambda self , other : _op_and_not_eq ( self . __ge__ , self , other )) ,
176- ( '__lt__' , lambda self , other : _not_op ( self . __ge__ , other ))]
170+ '__lt__' : { '__gt__' : _not_op_and_not_eq ,
171+ '__le__' : _op_or_eq ,
172+ '__ge__' : _not_op } ,
173+ '__le__' : { '__ge__' : _not_op_or_eq ,
174+ '__lt__' : _op_and_not_eq ,
175+ '__gt__' : _not_op } ,
176+ '__gt__' : { '__lt__' : _not_op_and_not_eq ,
177+ '__ge__' : _op_or_eq ,
178+ '__le__' : _not_op } ,
179+ '__ge__' : { '__le__' : _not_op_or_eq ,
180+ '__gt__' : _op_and_not_eq ,
181+ '__lt__' : _not_op }
177182 }
178183 # Find user-defined comparisons (not those inherited from object).
179184 roots = [op for op in convert if getattr (cls , op , None ) is not getattr (object , op , None )]
180185 if not roots :
181186 raise ValueError ('must define at least one ordering operation: < > <= >=' )
182187 root = max (roots ) # prefer __lt__ to __le__ to __gt__ to __ge__
183- for opname , opfunc in convert [root ]:
188+ for opname , opfunc in convert [root ]. items () :
184189 if opname not in roots :
185- opfunc .__name__ = opname
190+ namespace = {}
191+ exec ('def %s(self, other):%s' % (opname , opfunc % root ), namespace )
192+ opfunc = namespace [opname ]
193+ opfunc .__qualname__ = '%s.%s' % (cls .__qualname__ , opname )
194+ opfunc .__module__ = cls .__module__
186195 opfunc .__doc__ = getattr (int , opname ).__doc__
187196 setattr (cls , opname , opfunc )
188197 return cls
0 commit comments