Skip to content

Commit

Permalink
utils: remove backported total_ordering from functools
Browse files Browse the repository at this point in the history
Uses are replaced with the standard library functools.total_ordering now
that all supported platforms (Python 3.6 onwards) provide it.

As test_utils is removed (it tested only the total_ordering backport)
the test_module test in test_runtests needed modifying since it checks
the test infrastructure by counting the number of tests in test_utils -
instead it counts the tests in test_storeslice.
  • Loading branch information
gmarkall committed Jan 13, 2020
1 parent 225ce13 commit b7bd78b
Show file tree
Hide file tree
Showing 6 changed files with 11 additions and 206 deletions.
2 changes: 1 addition & 1 deletion numba/roc/hsadrv/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from contextlib import contextmanager

from collections import defaultdict, deque
from numba.utils import total_ordering
from functools import total_ordering
from numba import mviewbuf
from numba import utils
from numba import config
Expand Down
6 changes: 3 additions & 3 deletions numba/tests/test_runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ def test_cuda_submodules(self):
self.check_listing_prefix('numba.cuda.tests.cudasim')

def test_module(self):
self.check_testsuite_size(['numba.tests.test_utils'], 3)
self.check_testsuite_size(['numba.tests.test_nested_calls'], 5)
self.check_testsuite_size(['numba.tests.test_storeslice'], 2)
self.check_testsuite_size(['numba.tests.test_nested_calls'], 10)
# Several modules
self.check_testsuite_size(['numba.tests.test_nested_calls',
'numba.tests.test_utils'], 13)
'numba.tests.test_storeslice'], 12)

def test_subpackage(self):
self.check_testsuite_size(['numba.tests.npyufunc'], 50)
Expand Down
85 changes: 0 additions & 85 deletions numba/tests/test_utils.py

This file was deleted.

3 changes: 1 addition & 2 deletions numba/typeconv/castgraph.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from __future__ import print_function, absolute_import

from collections import defaultdict
from functools import total_ordering
import enum

from numba.utils import total_ordering


class Conversion(enum.IntEnum):
"""
Expand Down
11 changes: 6 additions & 5 deletions numba/types/scalars.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import numpy as np

from .abstract import Dummy, Hashable, Literal, Number, Type
from functools import total_ordering
from .. import npdatetime, utils
from ..typeconv import Conversion

Expand All @@ -27,7 +28,7 @@ def parse_integer_signed(name):
return signed


@utils.total_ordering
@total_ordering
class Integer(Number):
def __init__(self, name, bitwidth=None, signed=None):
super(Integer, self).__init__(name)
Expand Down Expand Up @@ -95,7 +96,7 @@ def can_convert_to(self, typingctx, other):
Literal.ctor_map[int] = IntegerLiteral


@utils.total_ordering
@total_ordering
class Float(Number):
def __init__(self, *args, **kws):
super(Float, self).__init__(*args, **kws)
Expand All @@ -113,7 +114,7 @@ def __lt__(self, other):
return self.bitwidth < other.bitwidth


@utils.total_ordering
@total_ordering
class Complex(Number):
def __init__(self, name, underlying_float, **kwargs):
super(Complex, self).__init__(name, **kwargs)
Expand Down Expand Up @@ -159,11 +160,11 @@ def cast_python_value(self, value):
return cls(value)


@utils.total_ordering
@total_ordering
class NPTimedelta(_NPDatetimeBase):
type_name = 'timedelta64'

@utils.total_ordering
@total_ordering
class NPDatetime(_NPDatetimeBase):
type_name = 'datetime64'

Expand Down
110 changes: 0 additions & 110 deletions numba/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,116 +498,6 @@ def benchmark(func, maxsec=1):
pass


# Backported from Python 3.4: functools.total_ordering()

def _not_op(op, other):
# "not a < b" handles "a >= b"
# "not a <= b" handles "a > b"
# "not a >= b" handles "a < b"
# "not a > b" handles "a <= b"
op_result = op(other)
if op_result is NotImplemented:
return NotImplemented
return not op_result


def _op_or_eq(op, self, other):
# "a < b or a == b" handles "a <= b"
# "a > b or a == b" handles "a >= b"
op_result = op(other)
if op_result is NotImplemented:
return NotImplemented
return op_result or self == other


def _not_op_and_not_eq(op, self, other):
# "not (a < b or a == b)" handles "a > b"
# "not a < b and a != b" is equivalent
# "not (a > b or a == b)" handles "a < b"
# "not a > b and a != b" is equivalent
op_result = op(other)
if op_result is NotImplemented:
return NotImplemented
return not op_result and self != other


def _not_op_or_eq(op, self, other):
# "not a <= b or a == b" handles "a >= b"
# "not a >= b or a == b" handles "a <= b"
op_result = op(other)
if op_result is NotImplemented:
return NotImplemented
return not op_result or self == other


def _op_and_not_eq(op, self, other):
# "a <= b and not a == b" handles "a < b"
# "a >= b and not a == b" handles "a > b"
op_result = op(other)
if op_result is NotImplemented:
return NotImplemented
return op_result and self != other


def _is_inherited_from_object(cls, op):
"""
Whether operator *op* on *cls* is inherited from the root object type.
"""
if PYVERSION >= (3,):
object_op = getattr(object, op)
cls_op = getattr(cls, op)
return object_op is cls_op
else:
# In 2.x, the inherited operator gets a new descriptor, so identity
# doesn't work. OTOH, dir() doesn't list methods inherited from
# object (which it does in 3.x).
return op not in dir(cls)


def total_ordering(cls):
"""Class decorator that fills in missing ordering methods"""
convert = {
'__lt__': [('__gt__',
lambda self, other: _not_op_and_not_eq(self.__lt__, self,
other)),
('__le__',
lambda self, other: _op_or_eq(self.__lt__, self, other)),
('__ge__', lambda self, other: _not_op(self.__lt__, other))],
'__le__': [('__ge__',
lambda self, other: _not_op_or_eq(self.__le__, self,
other)),
('__lt__',
lambda self, other: _op_and_not_eq(self.__le__, self,
other)),
('__gt__', lambda self, other: _not_op(self.__le__, other))],
'__gt__': [('__lt__',
lambda self, other: _not_op_and_not_eq(self.__gt__, self,
other)),
('__ge__',
lambda self, other: _op_or_eq(self.__gt__, self, other)),
('__le__', lambda self, other: _not_op(self.__gt__, other))],
'__ge__': [('__le__',
lambda self, other: _not_op_or_eq(self.__ge__, self,
other)),
('__gt__',
lambda self, other: _op_and_not_eq(self.__ge__, self,
other)),
('__lt__', lambda self, other: _not_op(self.__ge__, other))]
}
# Find user-defined comparisons (not those inherited from object).
roots = [op for op in convert if not _is_inherited_from_object(cls, op)]
if not roots:
raise ValueError(
'must define at least one ordering operation: < > <= >=')
root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
for opname, opfunc in convert[root]:
if opname not in roots:
opfunc.__name__ = opname
opfunc.__doc__ = getattr(int, opname).__doc__
setattr(cls, opname, opfunc)
return cls


def logger_hasHandlers(logger):
# Backport from python3.5 logging implementation of `.hasHandlers()`
c = logger
Expand Down

0 comments on commit b7bd78b

Please sign in to comment.