From 7428f9553744ad2de4a74e2152b6e8732f187bc4 Mon Sep 17 00:00:00 2001 From: Matt Bogosian Date: Tue, 11 Oct 2022 13:35:47 -0500 Subject: [PATCH] Minor cleanup --- .github/workflows/on-push.yaml | 2 ++ docs/perf_rational_baseline.ipy | 5 ++-- docs/perf_rational_baseline.txt | 12 ++++----- docs/perf_rational_big_protocol.ipy | 32 +++++++++++------------ docs/perf_rational_big_protocol.txt | 12 ++++----- docs/perf_rational_protocol.ipy | 6 ++--- docs/perf_rational_protocol.txt | 12 ++++----- docs/perf_supports_complex.ipy | 2 +- docs/perf_supports_complex.txt | 40 ++++++++++++++--------------- numerary/_protocol.py | 6 ++--- numerary/types.py | 12 ++++----- tests/test_integral_like.py | 16 ++++++------ tests/test_types.py | 4 +-- 13 files changed, 79 insertions(+), 82 deletions(-) diff --git a/.github/workflows/on-push.yaml b/.github/workflows/on-push.yaml index f4559a1..9ae2f79 100644 --- a/.github/workflows/on-push.yaml +++ b/.github/workflows/on-push.yaml @@ -2,6 +2,8 @@ name: tests and deployment on: pull_request: + branches: + - main push: jobs: diff --git a/docs/perf_rational_baseline.ipy b/docs/perf_rational_baseline.ipy index 3aa99ca..2975a75 100644 --- a/docs/perf_rational_baseline.ipy +++ b/docs/perf_rational_baseline.ipy @@ -5,8 +5,7 @@ one_int = 1 two_frac = Fraction(2) three_float = 3.0 vals = (one_int, two_frac, three_float) -t = Rational for v in vals: - print(f"%timeit isinstance({type(v).__module__}.{type(v).__name__}({v}), {t.__name__})") - %timeit isinstance(v, t) + print(f"%timeit isinstance({v!r}, Rational)") + %timeit isinstance(v, Rational) diff --git a/docs/perf_rational_baseline.txt b/docs/perf_rational_baseline.txt index fa346bf..237b128 100644 --- a/docs/perf_rational_baseline.txt +++ b/docs/perf_rational_baseline.txt @@ -1,6 +1,6 @@ -%timeit isinstance(builtins.int(1), Rational) -241 ns ± 1.56 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each) -%timeit isinstance(fractions.Fraction(2), Rational) -237 ns ± 0.889 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each) -%timeit isinstance(builtins.float(3.0), Rational) -254 ns ± 2.55 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each) +%timeit isinstance(1, Rational) +115 ns ± 1.26 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) +%timeit isinstance(Fraction(2, 1), Rational) +119 ns ± 0.366 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) +%timeit isinstance(3.0, Rational) +126 ns ± 0.499 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) diff --git a/docs/perf_rational_big_protocol.ipy b/docs/perf_rational_big_protocol.ipy index 4c47998..304a98f 100644 --- a/docs/perf_rational_big_protocol.ipy +++ b/docs/perf_rational_big_protocol.ipy @@ -1,23 +1,23 @@ +from abc import abstractproperty from fractions import Fraction -from numbers import Rational -from numerary.types import ( # "raw" (non-caching) versions - _SupportsComplexOps, - _SupportsConjugate, - _SupportsFloorCeil, - _SupportsDivmod, - _SupportsRealImag, - _SupportsRealOps, - _SupportsTrunc, -) from typing import ( Any, Protocol, SupportsAbs, - SupportsFloat, SupportsComplex, + SupportsFloat, SupportsRound, runtime_checkable, ) +from numerary.types import ( # "raw" (non-caching) versions + _SupportsComplexOps, + _SupportsConjugate, + _SupportsDivmod, + _SupportsFloorCeil, + _SupportsRealImag, + _SupportsRealOps, + _SupportsTrunc, +) one_int = 1 two_frac = Fraction(2) @@ -40,15 +40,13 @@ class SupportsLotsOfNumberStuff( Protocol, ): __slots__: Any = () - @property + @abstractproperty def numerator(self) -> int: pass - @property + @abstractproperty def denominator(self) -> int: pass -t = SupportsLotsOfNumberStuff - for v in vals: - print(f"%timeit isinstance({type(v).__module__}.{type(v).__name__}({v}), {t.__name__})") - %timeit isinstance(v, t) + print(f"%timeit isinstance({v!r}, SupportsLotsOfNumberStuff)") + %timeit isinstance(v, SupportsLotsOfNumberStuff) diff --git a/docs/perf_rational_big_protocol.txt b/docs/perf_rational_big_protocol.txt index ebd547e..31c1ed8 100644 --- a/docs/perf_rational_big_protocol.txt +++ b/docs/perf_rational_big_protocol.txt @@ -1,6 +1,6 @@ -%timeit isinstance(builtins.int(1), SupportsLotsOfNumberStuff) -112 µs ± 517 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each) -%timeit isinstance(fractions.Fraction(2), SupportsLotsOfNumberStuff) -115 µs ± 1.7 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each) -%timeit isinstance(builtins.float(3.0), SupportsLotsOfNumberStuff) -110 µs ± 1.52 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each) +%timeit isinstance(1, SupportsLotsOfNumberStuff) +49.8 µs ± 169 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each) +%timeit isinstance(Fraction(2, 1), SupportsLotsOfNumberStuff) +51.2 µs ± 185 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each) +%timeit isinstance(3.0, SupportsLotsOfNumberStuff) +47 µs ± 795 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each) diff --git a/docs/perf_rational_protocol.ipy b/docs/perf_rational_protocol.ipy index 06265f7..4172804 100644 --- a/docs/perf_rational_protocol.ipy +++ b/docs/perf_rational_protocol.ipy @@ -17,8 +17,6 @@ class SupportsNumeratorDenominator(Protocol): def denominator(self) -> int: pass -t = SupportsNumeratorDenominator - for v in vals: - print(f"%timeit isinstance({type(v).__module__}.{type(v).__name__}({v}), {t.__name__})") - %timeit isinstance(v, t) + print(f"%timeit isinstance({v!r}, SupportsNumeratorDenominator)") + %timeit isinstance(v, SupportsNumeratorDenominator) diff --git a/docs/perf_rational_protocol.txt b/docs/perf_rational_protocol.txt index 2936ffc..c0321b5 100644 --- a/docs/perf_rational_protocol.txt +++ b/docs/perf_rational_protocol.txt @@ -1,6 +1,6 @@ -%timeit isinstance(builtins.int(1), SupportsNumeratorDenominator) -10.4 µs ± 95 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) -%timeit isinstance(fractions.Fraction(2), SupportsNumeratorDenominator) -10.6 µs ± 94 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) -%timeit isinstance(builtins.float(3.0), SupportsNumeratorDenominator) -10.8 µs ± 231 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) +%timeit isinstance(1, SupportsNumeratorDenominator) +4.71 µs ± 34.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) +%timeit isinstance(Fraction(2, 1), SupportsNumeratorDenominator) +5.01 µs ± 36.9 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) +%timeit isinstance(3.0, SupportsNumeratorDenominator) +4.89 µs ± 52.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) diff --git a/docs/perf_supports_complex.ipy b/docs/perf_supports_complex.ipy index d85649a..424d041 100644 --- a/docs/perf_supports_complex.ipy +++ b/docs/perf_supports_complex.ipy @@ -16,6 +16,6 @@ for v in vals: _SupportsComplexOps, SupportsComplexOps, ): - print(f"%timeit isinstance({type(v).__module__}.{type(v).__name__}({v}), {t.__name__})") + print(f"%timeit isinstance({v!r}, {t.__name__})") %timeit isinstance(v, t) print() diff --git a/docs/perf_supports_complex.txt b/docs/perf_supports_complex.txt index 46b824d..7f852c8 100644 --- a/docs/perf_supports_complex.txt +++ b/docs/perf_supports_complex.txt @@ -1,25 +1,25 @@ -%timeit isinstance(builtins.int(1), _SupportsComplexOps) -9.8 µs ± 88.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) -%timeit isinstance(builtins.int(1), SupportsComplexOps) -189 ns ± 2.62 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) +%timeit isinstance(1, _SupportsComplexOps) +4.61 µs ± 20.3 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) +%timeit isinstance(1, SupportsComplexOps) +97.2 ns ± 0.316 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) -%timeit isinstance(builtins.float(2.0), _SupportsComplexOps) -9.83 µs ± 84.6 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) -%timeit isinstance(builtins.float(2.0), SupportsComplexOps) -189 ns ± 3.35 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) +%timeit isinstance(2.0, _SupportsComplexOps) +4.61 µs ± 18.2 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) +%timeit isinstance(2.0, SupportsComplexOps) +98.6 ns ± 1.04 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) -%timeit isinstance(decimal.Decimal(3), _SupportsComplexOps) -9.88 µs ± 89.9 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) -%timeit isinstance(decimal.Decimal(3), SupportsComplexOps) -188 ns ± 2.22 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) +%timeit isinstance(Decimal('3'), _SupportsComplexOps) +4.59 µs ± 50.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) +%timeit isinstance(Decimal('3'), SupportsComplexOps) +98.3 ns ± 0.435 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) -%timeit isinstance(fractions.Fraction(4), _SupportsComplexOps) -9.9 µs ± 52.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) -%timeit isinstance(fractions.Fraction(4), SupportsComplexOps) -191 ns ± 1.7 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) +%timeit isinstance(Fraction(4, 1), _SupportsComplexOps) +4.46 µs ± 20.1 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) +%timeit isinstance(Fraction(4, 1), SupportsComplexOps) +97.1 ns ± 0.161 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) -%timeit isinstance(sympy.core.numbers.Integer(5), _SupportsComplexOps) -10 µs ± 79.1 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) -%timeit isinstance(sympy.core.numbers.Integer(5), SupportsComplexOps) -189 ns ± 0.786 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) +%timeit isinstance(5, _SupportsComplexOps) +4.53 µs ± 32.6 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) +%timeit isinstance(5, SupportsComplexOps) +96.2 ns ± 0.317 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each) diff --git a/numerary/_protocol.py b/numerary/_protocol.py index 2e73181..6cb28dd 100644 --- a/numerary/_protocol.py +++ b/numerary/_protocol.py @@ -11,8 +11,6 @@ from collections import defaultdict from typing import TYPE_CHECKING, Any, Dict, Set, Tuple, Type, TypeVar -from beartype.typing import Protocol as _BeartypeCachingProtocol - __all__ = ("CachingProtocolMeta",) @@ -28,7 +26,9 @@ # . from abc import ABCMeta as _BeartypeCachingProtocolMeta else: - _BeartypeCachingProtocolMeta = type(_BeartypeCachingProtocol) + from beartype.typing import Protocol as _BeartypeProtocol + + _BeartypeCachingProtocolMeta = type(_BeartypeProtocol) class CachingProtocolMeta(_BeartypeCachingProtocolMeta): diff --git a/numerary/types.py b/numerary/types.py index d6010fa..f977243 100644 --- a/numerary/types.py +++ b/numerary/types.py @@ -12,7 +12,7 @@ import math import sys import traceback -from abc import abstractmethod +from abc import abstractmethod, abstractproperty from decimal import Decimal from fractions import Fraction from typing import TYPE_CHECKING, Any, Generic, Optional @@ -218,11 +218,11 @@ class _SupportsRealImag(_Protocol): The non-caching version of [``SupportsRealImag``][numerary.types.SupportsRealImag]. """ - @property + @abstractproperty def real(self) -> Any: pass - @property + @abstractproperty def imag(self) -> Any: pass @@ -563,11 +563,11 @@ class _SupportsNumeratorDenominator(_Protocol): [``SupportsNumeratorDenominator``][numerary.types.SupportsNumeratorDenominator]. """ - @property + @abstractproperty def numerator(self) -> int: pass - @property + @abstractproperty def denominator(self) -> int: pass @@ -1083,7 +1083,7 @@ class SupportsIntegralPow( >>> integral_pow_my_thing(sympy.Integer(3)) 1 >>> type(_) - + >>> # error: Value of type variable "MyIntegralPowT" of "integral_pow_my_thing" cannot be "str" >>> integral_pow_my_thing("not-a-number") # type: ignore [type-var] diff --git a/tests/test_integral_like.py b/tests/test_integral_like.py index 96ef472..d22425b 100644 --- a/tests/test_integral_like.py +++ b/tests/test_integral_like.py @@ -131,14 +131,14 @@ def test_integral_like_numpy() -> None: pytest.importorskip("numpy", reason="requires numpy") import numpy - uint8_val: IntegralLike = numpy.uint8(2) - uint16_val: IntegralLike = numpy.uint16(273) - uint32_val: IntegralLike = numpy.uint32(273) - uint64_val: IntegralLike = numpy.uint64(273) - int8_val: IntegralLike = numpy.int8(-2) - int16_val: IntegralLike = numpy.int16(-273) - int32_val: IntegralLike = numpy.int32(-273) - int64_val: IntegralLike = numpy.int64(-273) + uint8_val: IntegralLike = numpy.uint8(2) # type: ignore [assignment] + uint16_val: IntegralLike = numpy.uint16(273) # type: ignore [assignment] + uint32_val: IntegralLike = numpy.uint32(273) # type: ignore [assignment] + uint64_val: IntegralLike = numpy.uint64(273) # type: ignore [assignment] + int8_val: IntegralLike = numpy.int8(-2) # type: ignore [assignment] + int16_val: IntegralLike = numpy.int16(-273) # type: ignore [assignment] + int32_val: IntegralLike = numpy.int32(-273) # type: ignore [assignment] + int64_val: IntegralLike = numpy.int64(-273) # type: ignore [assignment] for good_val in ( uint8_val, diff --git a/tests/test_types.py b/tests/test_types.py index c6639ca..ed6770a 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -68,9 +68,9 @@ def _lies_all_lies(arg: RealLike) -> Tuple[str]: def test_beartype_validators() -> None: try: - from beartype.typing import Annotated + from typing import Annotated except ImportError: - pytest.skip("requires beartype.typing.Annotated") + pytest.skip("requires typing.Annotated") raise