Code Duplication    Length = 45-45 lines in 2 locations

src/hunter/predicates.py 2 locations

@@ 323-367 (lines=45) @@
320
    __rand__ = __and__
321
322
323
class Or(Fields.predicates):
324
    """
325
    `Or` predicate. Exits at first sub-predicate that returns ``True``.
326
    """
327
328
    def __init__(self, *predicates):
329
        self.predicates = predicates
330
331
    def __str__(self):
332
        return 'Or(%s)' % ', '.join(str(p) for p in self.predicates)
333
334
    def __repr__(self):
335
        return '<hunter.predicates.Or: predicates=%r>' % (self.predicates,)
336
337
    def __call__(self, event):
338
        """
339
        Handles the event.
340
        """
341
        for predicate in self.predicates:
342
            if predicate(event):
343
                return True
344
        else:
345
            return False
346
347
    def __eq__(self, other):
348
        if isinstance(other, Or):
349
            if len(self.predicates) != len(other.predicates):
350
                return False
351
            return set(self.predicates) == set(other.predicates)
352
        return NotImplemented
353
354
    def __or__(self, other):
355
        return Or(*chain(self.predicates, other.predicates if isinstance(other, Or) else (other,)))
356
357
    def __and__(self, other):
358
        return And(self, other)
359
360
    def __invert__(self):
361
        return Not(self)
362
363
    def __hash__(self):
364
        return hash(frozenset(self.predicates))
365
366
    __ror__ = __or__
367
    __rand__ = __and__
368
369
370
class Not(Fields.predicate):
@@ 276-320 (lines=45) @@
273
    __rand__ = __and__
274
275
276
class And(Fields.predicates):
277
    """
278
    `And` predicate. Exits at the first sub-predicate that returns ``False``.
279
    """
280
281
    def __init__(self, *predicates):
282
        self.predicates = predicates
283
284
    def __str__(self):
285
        return 'And(%s)' % ', '.join(str(p) for p in self.predicates)
286
287
    def __repr__(self):
288
        return '<hunter.predicates.And: predicates=%r>' % (self.predicates,)
289
290
    def __call__(self, event):
291
        """
292
        Handles the event.
293
        """
294
        for predicate in self.predicates:
295
            if not predicate(event):
296
                return False
297
        else:
298
            return True
299
300
    def __eq__(self, other):
301
        if isinstance(other, And):
302
            if len(self.predicates) != len(other.predicates):
303
                return False
304
            return set(self.predicates) == set(other.predicates)
305
        return NotImplemented
306
307
    def __or__(self, other):
308
        return Or(self, other)
309
310
    def __and__(self, other):
311
        return And(*chain(self.predicates, other.predicates if isinstance(other, And) else (other,)))
312
313
    def __invert__(self):
314
        return Not(self)
315
316
    def __hash__(self):
317
        return hash(frozenset(self.predicates))
318
319
    __ror__ = __or__
320
    __rand__ = __and__
321
322
323
class Or(Fields.predicates):