Rename lalib.elements.gf2.GF2
& friends
- the future (concrete) Galois `Field` implementation shall receive the name `GF2` (as per common math notation) => name conflict with the current `GF2` class implementing the elements of the future Galois `Field` => rename the current `GF2` class into `GF2Element` - because `GF2Element` is a bit tedius to type for the end user, we introduce a `gf2` alias in line with the naming convention for the built-in data types (e.g., `int` or `float`) that are also used as elements of (other) `Field`s => name conflict with the current `lalib.elements.gf2` module => rename the module into `lalib.elements.galois` - adjust the docstrings to refer to "the `gf2` type" - adjust the top-level imports and tests
This commit is contained in:
parent
65de932f8d
commit
917c217ca0
5 changed files with 89 additions and 78 deletions
|
@ -22,7 +22,7 @@ one
|
||||||
|
|
||||||
from importlib import metadata
|
from importlib import metadata
|
||||||
|
|
||||||
from lalib.elements import gf2
|
from lalib import elements
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -40,15 +40,15 @@ else:
|
||||||
del pkg_info
|
del pkg_info
|
||||||
|
|
||||||
|
|
||||||
GF2, one, zero = gf2.GF2, gf2.one, gf2.zero
|
gf2, one, zero = elements.gf2, elements.one, elements.zero
|
||||||
|
|
||||||
|
|
||||||
del gf2
|
del elements
|
||||||
del metadata
|
del metadata
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"GF2",
|
"gf2",
|
||||||
"one",
|
"one",
|
||||||
"zero",
|
"zero",
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,26 +9,26 @@ Then, use them:
|
||||||
>>> one + zero
|
>>> one + zero
|
||||||
one
|
one
|
||||||
|
|
||||||
>>> GF2(0)
|
>>> gf2(0)
|
||||||
zero
|
zero
|
||||||
>>> GF2(42)
|
>>> gf2(42)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValueError: ...
|
ValueError: ...
|
||||||
>>> GF2(42, strict=False)
|
>>> gf2(42, strict=False)
|
||||||
one
|
one
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from lalib.elements import gf2
|
from lalib.elements import galois
|
||||||
|
|
||||||
|
|
||||||
GF2, one, zero = gf2.GF2, gf2.one, gf2.zero
|
gf2, one, zero = galois.gf2, galois.one, galois.zero
|
||||||
|
|
||||||
del gf2
|
del galois
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"GF2",
|
"gf2",
|
||||||
"one",
|
"one",
|
||||||
"zero",
|
"zero",
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
This module defines two singleton objects, `one` and `zero`,
|
This module defines two singleton objects, `one` and `zero`,
|
||||||
that follow the rules of a Galois field of two elements,
|
that follow the rules of a Galois field of two elements,
|
||||||
or `GF2` for short:
|
also called `GF2` in `lalib`:
|
||||||
|
|
||||||
>>> one + one
|
>>> one + one
|
||||||
zero
|
zero
|
||||||
|
@ -22,7 +22,10 @@ zero
|
||||||
zero
|
zero
|
||||||
|
|
||||||
Further usage explanations of `one` and `zero`
|
Further usage explanations of `one` and `zero`
|
||||||
can be found in the various docstrings of the `GF2` class.
|
can be found in the various docstrings of the `GF2Element` class.
|
||||||
|
|
||||||
|
This class is also referred to as just "the `gf2` type" outside
|
||||||
|
this module.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
@ -102,15 +105,16 @@ def to_gf2(
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
class _GF2Meta(abc.ABCMeta):
|
class GF2Meta(abc.ABCMeta):
|
||||||
"""Make data type of `one` and `zero` appear to be `GF2`."""
|
"""Make data type of `one` and `zero` appear to be `gf2`."""
|
||||||
|
|
||||||
def __repr__(cls) -> str:
|
def __repr__(cls) -> str:
|
||||||
return "GF2"
|
"""Text representation for `GF2Element` and sub-classes."""
|
||||||
|
return "gf2"
|
||||||
|
|
||||||
|
|
||||||
@functools.total_ordering
|
@functools.total_ordering
|
||||||
class GF2(metaclass=_GF2Meta):
|
class GF2Element(metaclass=GF2Meta):
|
||||||
"""A Galois field value: either `one` or `zero`.
|
"""A Galois field value: either `one` or `zero`.
|
||||||
|
|
||||||
Implements the singleton design pattern such that
|
Implements the singleton design pattern such that
|
||||||
|
@ -276,8 +280,8 @@ class GF2(metaclass=_GF2Meta):
|
||||||
Either `1` or `0`.
|
Either `1` or `0`.
|
||||||
|
|
||||||
Reasoning:
|
Reasoning:
|
||||||
- `int(one) == 1` => `GF2(1 / 1) == one`
|
- `int(one) == 1` => `gf2(1 / 1) == one`
|
||||||
- `int(zero) == 0` => `GF2(0 / 1) == zero`
|
- `int(zero) == 0` => `gf2(0 / 1) == zero`
|
||||||
|
|
||||||
See also docstring for `.denominator`.
|
See also docstring for `.denominator`.
|
||||||
"""
|
"""
|
||||||
|
@ -287,7 +291,7 @@ class GF2(metaclass=_GF2Meta):
|
||||||
def denominator(self) -> Literal[1]:
|
def denominator(self) -> Literal[1]:
|
||||||
"""Smallest denominator when expressed as a `Rational` number.
|
"""Smallest denominator when expressed as a `Rational` number.
|
||||||
|
|
||||||
Always `1` for `GF2` values.
|
Always `1` for `gf2` values.
|
||||||
|
|
||||||
See also docstring for `.numerator`.
|
See also docstring for `.numerator`.
|
||||||
"""
|
"""
|
||||||
|
@ -308,7 +312,7 @@ class GF2(metaclass=_GF2Meta):
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
other = GF2(other)
|
other = GF2Element(other)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -327,7 +331,7 @@ class GF2(metaclass=_GF2Meta):
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
other = GF2(other)
|
other = GF2Element(other)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -358,16 +362,16 @@ class GF2(metaclass=_GF2Meta):
|
||||||
def _compute(self, other: object, func: Callable) -> Self:
|
def _compute(self, other: object, func: Callable) -> Self:
|
||||||
"""Run arithmetic operations using `int`s.
|
"""Run arithmetic operations using `int`s.
|
||||||
|
|
||||||
The `GF2` atithmetic operations can transparently be conducted
|
The `gf2` atithmetic operations can transparently be conducted
|
||||||
by converting `self` and `other` into `int`s first, and
|
by converting `self` and `other` into `int`s first, and
|
||||||
then "do the math".
|
then "do the math".
|
||||||
|
|
||||||
Besides the generic arithmetic, this method also handles the
|
Besides the generic arithmetic, this method also handles the
|
||||||
casting of non-`GF2` values and various errors occuring
|
casting of non-`gf2` values and various errors occuring
|
||||||
along the way.
|
along the way.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
other = GF2(other)
|
other = GF2Element(other)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -391,7 +395,7 @@ class GF2(metaclass=_GF2Meta):
|
||||||
def __add__(self, other: object) -> Self:
|
def __add__(self, other: object) -> Self:
|
||||||
"""Addition / Subtraction: `self + other` / `self - other`.
|
"""Addition / Subtraction: `self + other` / `self - other`.
|
||||||
|
|
||||||
For `GF2`, addition and subtraction are identical. Besides
|
For `gf2`, addition and subtraction are identical. Besides
|
||||||
`one + one` which cannot result in a "two", all operations
|
`one + one` which cannot result in a "two", all operations
|
||||||
behave as one would expect from `int`s.
|
behave as one would expect from `int`s.
|
||||||
|
|
||||||
|
@ -417,7 +421,7 @@ class GF2(metaclass=_GF2Meta):
|
||||||
def __mul__(self, other: object) -> Self:
|
def __mul__(self, other: object) -> Self:
|
||||||
"""Multiplication: `self * other`.
|
"""Multiplication: `self * other`.
|
||||||
|
|
||||||
Multiplying `GF2` values is like multiplying `int`s.
|
Multiplying `gf2` values is like multiplying `int`s.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
|
@ -435,7 +439,7 @@ class GF2(metaclass=_GF2Meta):
|
||||||
def __truediv__(self, other: object) -> Self:
|
def __truediv__(self, other: object) -> Self:
|
||||||
"""Division: `self / other` and `self // other`.
|
"""Division: `self / other` and `self // other`.
|
||||||
|
|
||||||
Dividing `GF2` values is like dividing `int`s.
|
Dividing `gf2` values is like dividing `int`s.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
|
@ -466,7 +470,7 @@ class GF2(metaclass=_GF2Meta):
|
||||||
def __mod__(self, other: object) -> Self:
|
def __mod__(self, other: object) -> Self:
|
||||||
"""Modulo Division: `self % other`.
|
"""Modulo Division: `self % other`.
|
||||||
|
|
||||||
Modulo dividing `GF2` values is like modulo dividing `int`s.
|
Modulo dividing `gf2` values is like modulo dividing `int`s.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
|
@ -493,7 +497,7 @@ class GF2(metaclass=_GF2Meta):
|
||||||
def __pow__(self, other: object, _modulo: Optional[object] = None) -> Self:
|
def __pow__(self, other: object, _modulo: Optional[object] = None) -> Self:
|
||||||
"""Exponentiation: `self ** other`.
|
"""Exponentiation: `self ** other`.
|
||||||
|
|
||||||
Powers of `GF2` values are like powers of `int`s.
|
Powers of `gf2` values are like powers of `int`s.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
|
@ -516,16 +520,16 @@ class GF2(metaclass=_GF2Meta):
|
||||||
return self._compute(other, lambda s, o: o**s)
|
return self._compute(other, lambda s, o: o**s)
|
||||||
|
|
||||||
|
|
||||||
numbers.Rational.register(GF2)
|
numbers.Rational.register(GF2Element)
|
||||||
|
|
||||||
|
|
||||||
class GF2One(GF2):
|
class GF2One(GF2Element):
|
||||||
"""The Galois field value `one`."""
|
"""The Galois field value `one`."""
|
||||||
|
|
||||||
_value = 1
|
_value = 1
|
||||||
|
|
||||||
|
|
||||||
class GF2Zero(GF2):
|
class GF2Zero(GF2Element):
|
||||||
"""The Galois field value `zero`."""
|
"""The Galois field value `zero`."""
|
||||||
|
|
||||||
_value = 0
|
_value = 0
|
||||||
|
@ -533,3 +537,10 @@ class GF2Zero(GF2):
|
||||||
|
|
||||||
one = GF2One()
|
one = GF2One()
|
||||||
zero = GF2Zero()
|
zero = GF2Zero()
|
||||||
|
|
||||||
|
|
||||||
|
# Outside this module the `GF2Element` is just "the `gf2` type"
|
||||||
|
gf2 = GF2Element
|
||||||
|
|
||||||
|
|
||||||
|
del GF2Meta
|
|
@ -1,4 +1,4 @@
|
||||||
"""Test the `GF2` singeltons `one` and `zero`."""
|
"""Test the `gf2` singeltons `one` and `zero`."""
|
||||||
|
|
||||||
import decimal
|
import decimal
|
||||||
import fractions
|
import fractions
|
||||||
|
@ -11,25 +11,25 @@ import sys
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from lalib.elements import gf2
|
from lalib.elements import galois
|
||||||
|
|
||||||
|
|
||||||
one, zero = (
|
one, zero = (
|
||||||
gf2.one,
|
galois.one,
|
||||||
gf2.zero,
|
galois.zero,
|
||||||
)
|
)
|
||||||
|
|
||||||
to_gf2 = gf2.to_gf2
|
to_gf2 = galois.to_gf2
|
||||||
|
|
||||||
GF2, GF2One, GF2Zero = (
|
gf2, GF2One, GF2Zero = (
|
||||||
gf2.GF2,
|
galois.gf2,
|
||||||
gf2.GF2One,
|
galois.GF2One,
|
||||||
gf2.GF2Zero,
|
galois.GF2Zero,
|
||||||
)
|
)
|
||||||
|
|
||||||
_THRESHOLD = gf2.THRESHOLD
|
_THRESHOLD = galois.THRESHOLD
|
||||||
|
|
||||||
del gf2
|
del galois
|
||||||
|
|
||||||
|
|
||||||
CROSS_REFERENCE = not os.environ.get("NO_CROSS_REFERENCE")
|
CROSS_REFERENCE = not os.environ.get("NO_CROSS_REFERENCE")
|
||||||
|
@ -158,16 +158,16 @@ class TestGF2Casting:
|
||||||
to_gf2(float("NaN"), strict=strict)
|
to_gf2(float("NaN"), strict=strict)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("cls", [GF2, GF2One, GF2Zero])
|
@pytest.mark.parametrize("cls", [gf2, GF2One, GF2Zero])
|
||||||
class TestGF2ConstructorWithCastedValue:
|
class TestGF2ConstructorWithCastedValue:
|
||||||
"""Test the `GF2` class's constructor.
|
"""Test the `gf2` class's constructor.
|
||||||
|
|
||||||
`GF2(value, ...)` returns either `one` or `zero`.
|
`gf2(value, ...)` returns either `one` or `zero`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@pytest.mark.parametrize("value", strict_one_like_values)
|
@pytest.mark.parametrize("value", strict_one_like_values)
|
||||||
def test_cast_ones_strictly(self, cls, value):
|
def test_cast_ones_strictly(self, cls, value):
|
||||||
"""`GF2(value, strict=True)` returns `one`."""
|
"""`gf2(value, strict=True)` returns `one`."""
|
||||||
result1 = cls(value) # `strict=True` by default
|
result1 = cls(value) # `strict=True` by default
|
||||||
assert result1 is one
|
assert result1 is one
|
||||||
|
|
||||||
|
@ -176,13 +176,13 @@ class TestGF2ConstructorWithCastedValue:
|
||||||
|
|
||||||
@pytest.mark.parametrize("value", one_like_values)
|
@pytest.mark.parametrize("value", one_like_values)
|
||||||
def test_cast_ones_not_strictly(self, cls, value):
|
def test_cast_ones_not_strictly(self, cls, value):
|
||||||
"""`GF2(value, strict=False)` returns `one`."""
|
"""`gf2(value, strict=False)` returns `one`."""
|
||||||
result = cls(value, strict=False)
|
result = cls(value, strict=False)
|
||||||
assert result is one
|
assert result is one
|
||||||
|
|
||||||
@pytest.mark.parametrize("value", non_strict_one_like_values)
|
@pytest.mark.parametrize("value", non_strict_one_like_values)
|
||||||
def test_cannot_cast_ones_strictly(self, cls, value):
|
def test_cannot_cast_ones_strictly(self, cls, value):
|
||||||
"""`GF2(value, strict=False)` returns `1`."""
|
"""`gf2(value, strict=False)` returns `1`."""
|
||||||
with pytest.raises(ValueError, match="`1`-like or `0`-like"):
|
with pytest.raises(ValueError, match="`1`-like or `0`-like"):
|
||||||
cls(value)
|
cls(value)
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ class TestGF2ConstructorWithCastedValue:
|
||||||
|
|
||||||
@pytest.mark.parametrize("value", zero_like_values)
|
@pytest.mark.parametrize("value", zero_like_values)
|
||||||
def test_cast_zeros(self, cls, value):
|
def test_cast_zeros(self, cls, value):
|
||||||
"""`GF2(value, strict=...)` returns `zero`."""
|
"""`gf2(value, strict=...)` returns `zero`."""
|
||||||
result1 = cls(value) # `strict=True` by default
|
result1 = cls(value) # `strict=True` by default
|
||||||
assert result1 is zero
|
assert result1 is zero
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ class TestGF2ConstructorWithCastedValue:
|
||||||
|
|
||||||
@pytest.mark.parametrize("scaler", [1, 10, 100, 1000])
|
@pytest.mark.parametrize("scaler", [1, 10, 100, 1000])
|
||||||
def test_get_one_if_within_threshold(self, cls, scaler):
|
def test_get_one_if_within_threshold(self, cls, scaler):
|
||||||
"""`GF2()` returns `one` if `value` is larger than `threshold`."""
|
"""`gf2()` returns `one` if `value` is larger than `threshold`."""
|
||||||
# `not_within_threshold` is larger than the `default_threshold`
|
# `not_within_threshold` is larger than the `default_threshold`
|
||||||
# but still different from `1` => `strict=False`
|
# but still different from `1` => `strict=False`
|
||||||
value = scaler * not_within_threshold
|
value = scaler * not_within_threshold
|
||||||
|
@ -241,7 +241,7 @@ class TestGF2ConstructorWithCastedValue:
|
||||||
@pytest.mark.parametrize("scaler", [1, 10, 100, 1000])
|
@pytest.mark.parametrize("scaler", [1, 10, 100, 1000])
|
||||||
@pytest.mark.parametrize("strict", [True, False])
|
@pytest.mark.parametrize("strict", [True, False])
|
||||||
def test_get_zero_if_within_threshold(self, cls, scaler, strict):
|
def test_get_zero_if_within_threshold(self, cls, scaler, strict):
|
||||||
"""`GF2()` returns `zero` if `value` is smaller than `threshold`."""
|
"""`gf2()` returns `zero` if `value` is smaller than `threshold`."""
|
||||||
# `within_threshold` is smaller than the `default_threshold`
|
# `within_threshold` is smaller than the `default_threshold`
|
||||||
value = scaler * within_threshold
|
value = scaler * within_threshold
|
||||||
threshold = scaler * default_threshold
|
threshold = scaler * default_threshold
|
||||||
|
@ -252,9 +252,9 @@ class TestGF2ConstructorWithCastedValue:
|
||||||
|
|
||||||
@pytest.mark.parametrize("strict", [True, False])
|
@pytest.mark.parametrize("strict", [True, False])
|
||||||
class TestGF2ConstructorWithoutCastedValue:
|
class TestGF2ConstructorWithoutCastedValue:
|
||||||
"""Test the `GF2` class's constructor.
|
"""Test the `gf2` class's constructor.
|
||||||
|
|
||||||
`GF2()` returns either `one` or `zero`.
|
`gf2()` returns either `one` or `zero`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_get_one_from_sub_class_with_no_input_value(self, strict):
|
def test_get_one_from_sub_class_with_no_input_value(self, strict):
|
||||||
|
@ -262,9 +262,9 @@ class TestGF2ConstructorWithoutCastedValue:
|
||||||
result = GF2One(strict=strict)
|
result = GF2One(strict=strict)
|
||||||
assert result is one
|
assert result is one
|
||||||
|
|
||||||
@pytest.mark.parametrize("cls", [GF2, GF2Zero])
|
@pytest.mark.parametrize("cls", [gf2, GF2Zero])
|
||||||
def test_get_zero_with_no_input_value(self, cls, strict):
|
def test_get_zero_with_no_input_value(self, cls, strict):
|
||||||
"""`GF2()` and `GF2Zero()` return `zero`."""
|
"""`gf2()` and `GF2Zero()` return `zero`."""
|
||||||
result = cls(strict=strict)
|
result = cls(strict=strict)
|
||||||
assert result is zero
|
assert result is zero
|
||||||
|
|
||||||
|
@ -273,12 +273,12 @@ class TestGenericBehavior:
|
||||||
"""Test the classes behind `one` and `zero`."""
|
"""Test the classes behind `one` and `zero`."""
|
||||||
|
|
||||||
def test_cannot_instantiate_base_class_alone(self, monkeypatch):
|
def test_cannot_instantiate_base_class_alone(self, monkeypatch):
|
||||||
"""`GF2One` and `GF2Zero` must be instantiated before `GF2`."""
|
"""`GF2One` and `GF2Zero` must be instantiated before `gf2`."""
|
||||||
monkeypatch.setattr(GF2, "_instances", {})
|
monkeypatch.setattr(gf2, "_instances", {})
|
||||||
with pytest.raises(RuntimeError, match="internal error"):
|
with pytest.raises(RuntimeError, match="internal error"):
|
||||||
GF2()
|
gf2()
|
||||||
|
|
||||||
@pytest.mark.parametrize("cls", [GF2, GF2One, GF2Zero])
|
@pytest.mark.parametrize("cls", [gf2, GF2One, GF2Zero])
|
||||||
def test_create_singletons(self, cls):
|
def test_create_singletons(self, cls):
|
||||||
"""Singleton pattern: The classes always return the same instance."""
|
"""Singleton pattern: The classes always return the same instance."""
|
||||||
first = cls()
|
first = cls()
|
||||||
|
@ -292,7 +292,7 @@ class TestGenericBehavior:
|
||||||
the sub-classes that create `one` and `zero`.
|
the sub-classes that create `one` and `zero`.
|
||||||
"""
|
"""
|
||||||
sub_cls = type(obj)
|
sub_cls = type(obj)
|
||||||
assert sub_cls is not GF2
|
assert sub_cls is not gf2
|
||||||
|
|
||||||
new_obj = sub_cls()
|
new_obj = sub_cls()
|
||||||
assert new_obj is obj
|
assert new_obj is obj
|
||||||
|
@ -311,7 +311,7 @@ class TestGenericBehavior:
|
||||||
"""`one` and `zero` are officially `Numbers`s."""
|
"""`one` and `zero` are officially `Numbers`s."""
|
||||||
assert isinstance(obj, type_)
|
assert isinstance(obj, type_)
|
||||||
|
|
||||||
@pytest.mark.parametrize("cls", [GF2, GF2One, GF2Zero])
|
@pytest.mark.parametrize("cls", [gf2, GF2One, GF2Zero])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"method",
|
"method",
|
||||||
[
|
[
|
||||||
|
@ -339,8 +339,8 @@ class TestGenericBehavior:
|
||||||
value,
|
value,
|
||||||
):
|
):
|
||||||
"""Ensure all of `numbers.Rational`'s abstact methods are implemented."""
|
"""Ensure all of `numbers.Rational`'s abstact methods are implemented."""
|
||||||
monkeypatch.setattr(GF2, "_instances", {})
|
monkeypatch.setattr(gf2, "_instances", {})
|
||||||
monkeypatch.delattr(GF2, method)
|
monkeypatch.delattr(gf2, method)
|
||||||
|
|
||||||
sub_cls = type("GF2Baby", (cls, numbers.Rational), {})
|
sub_cls = type("GF2Baby", (cls, numbers.Rational), {})
|
||||||
|
|
||||||
|
@ -362,14 +362,14 @@ class TestGenericBehavior:
|
||||||
@pytest.mark.parametrize("func", [repr, str])
|
@pytest.mark.parametrize("func", [repr, str])
|
||||||
@pytest.mark.parametrize("obj", [one, zero])
|
@pytest.mark.parametrize("obj", [one, zero])
|
||||||
def test_text_repr_for_classes(self, func, obj):
|
def test_text_repr_for_classes(self, func, obj):
|
||||||
"""'GF2' is the text representation for all sub-classes ...
|
"""'gf2' is the text representation for all sub-classes ...
|
||||||
|
|
||||||
... which is valid code referring to the base class `GF2`.
|
... which is valid code referring to the base class `gf2`.
|
||||||
|
|
||||||
`GF2()` returns `zero` if called without arguments.
|
`gf2()` returns `zero` if called without arguments.
|
||||||
"""
|
"""
|
||||||
base_cls = eval(func(type(obj))) # noqa: S307
|
base_cls = eval(func(type(obj))) # noqa: S307
|
||||||
assert base_cls is GF2
|
assert base_cls is gf2
|
||||||
|
|
||||||
new_obj = base_cls()
|
new_obj = base_cls()
|
||||||
assert new_obj is zero
|
assert new_obj is zero
|
||||||
|
@ -595,10 +595,10 @@ class TestArithmetic:
|
||||||
|
|
||||||
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
||||||
|
|
||||||
result3 = GF2((operator(int(abs(first)), int(abs(second))) + 2) % 2)
|
result3 = gf2((operator(int(abs(first)), int(abs(second))) + 2) % 2)
|
||||||
assert result3 is expected
|
assert result3 is expected
|
||||||
|
|
||||||
result4 = GF2((operator(int(abs(second)), int(abs(first))) + 2) % 2)
|
result4 = gf2((operator(int(abs(second)), int(abs(first))) + 2) % 2)
|
||||||
assert result4 is expected
|
assert result4 is expected
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -631,10 +631,10 @@ class TestArithmetic:
|
||||||
|
|
||||||
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
||||||
|
|
||||||
result3 = GF2(int(abs(first)) * int(abs(second)))
|
result3 = gf2(int(abs(first)) * int(abs(second)))
|
||||||
assert result3 is expected
|
assert result3 is expected
|
||||||
|
|
||||||
result4 = GF2(int(abs(second)) * int(abs(first)))
|
result4 = gf2(int(abs(second)) * int(abs(first)))
|
||||||
assert result4 is expected
|
assert result4 is expected
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -668,7 +668,7 @@ class TestArithmetic:
|
||||||
|
|
||||||
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
||||||
|
|
||||||
result2 = GF2(operator(int(abs(first)), int(abs(second))))
|
result2 = gf2(operator(int(abs(first)), int(abs(second))))
|
||||||
assert result2 is expected
|
assert result2 is expected
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -698,7 +698,7 @@ class TestArithmetic:
|
||||||
|
|
||||||
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
||||||
|
|
||||||
result2 = GF2(int(abs(first)) % int(abs(second)))
|
result2 = gf2(int(abs(first)) % int(abs(second)))
|
||||||
assert result2 is expected
|
assert result2 is expected
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -775,7 +775,7 @@ class TestArithmetic:
|
||||||
|
|
||||||
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
if CROSS_REFERENCE: # cast `one` and `zero` as `integer`s before doing the math
|
||||||
|
|
||||||
result2 = GF2(int(abs(first)) ** int(abs(second)))
|
result2 = gf2(int(abs(first)) ** int(abs(second)))
|
||||||
assert result2 is expected
|
assert result2 is expected
|
||||||
|
|
||||||
@pytest.mark.parametrize("obj", [one, zero])
|
@pytest.mark.parametrize("obj", [one, zero])
|
||||||
|
@ -826,7 +826,7 @@ class TestArithmetic:
|
||||||
)
|
)
|
||||||
def test_can_import_typing_extensions():
|
def test_can_import_typing_extensions():
|
||||||
"""For Python versions 3.11+ we do not need the "typing-extensions"."""
|
"""For Python versions 3.11+ we do not need the "typing-extensions"."""
|
||||||
package = importlib.import_module("lalib.elements.gf2")
|
package = importlib.import_module("lalib.elements.galois")
|
||||||
importlib.reload(package)
|
importlib.reload(package)
|
||||||
|
|
||||||
assert package.Self is not None
|
assert package.Self is not None
|
|
@ -15,7 +15,7 @@ import xdoctest
|
||||||
[
|
[
|
||||||
"lalib",
|
"lalib",
|
||||||
"lalib.elements",
|
"lalib.elements",
|
||||||
"lalib.elements.gf2",
|
"lalib.elements.galois",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_docstrings(module):
|
def test_docstrings(module):
|
||||||
|
|
Loading…
Reference in a new issue