- so far, `gf2()` runs in a `strict` mode by default
=> `gf2(42)` results in a `ValueError`
- we adapt `gf2()` (a.k.a. `lalib.elements.galois.GF2Element`)
such that it behaves more like the built-in `bool()`
=> `gf2(42)` returns `one`, like `bool(42)` returns `True`
- further, the `GF2Element` class is adjusted such that
`one` and `zero` assume their counterparts to be
`1`-like or `0`-like objects during binary operations;
other values result in an error
=> for example, `one + 1` works but `one + 42` does not
=> so, when used in binary operations, `one` and `zero`
continue to cast their counterparts in `strict` mode
- simplify the casting logic
- make `value` a positional-only argument in `gf2()`
(like most of the built-in constructors)
- provide more usage examples in the docstrings
clarifying when `strict` mode is used and when not
- propagate the above changes to the test suite:
+ adapt test cases with regard to the `strict` mode logic
+ add new test cases to `assert` how `gf2()`
can process `str`ings directly
+ rename two test cases involving `complex` numbers
to mimic the naming from the newly added test cases
- extend `pytest` with an option to run only the minimum number
of (unit) test cases to just keep the coverage at 100%
- rationale:
+ many of the unit test cases partly overlap with
respect to the lines of source code executed
+ also, integration tests, by definition, do not
contribute to a higher test coverage
- implementation: mark "redundant" test cases as one of:
+ `pytest.mark.integration_test`
=> code usage from the perspective of the end user
+ `pytest.mark.overlapping_test`
=> tests not contributing to the 100% coverage
+ `pytest.mark.sanity_test`
=> tests providing confidence in the test data
- add `tests.conftest` module
=> programatically convert the above markers into
`@pytest.mark.no_cover` and collect the non-"redundant" tests
- add nox session "test-fast" to run only the minimum
number of (unit) test while holding coverage at 100%
- refactor some test modules
+ wrap some test cases in a class
+ move sanity tests to the end of the files
- add `lalib.fields.base.Field`, a blueprint for all concrete fields,
providing a unified interface to be used outside of the
`lalib.fields` sub-package
- implement `lalib.fields.complex_.ComplexField`, or `C` for short,
the field over the complex numbers (modeled as `complex` numbers)
- implement `lalib.fields.galois.GaloisField2`, or `GF2` for short,
the (finite) field over the two elements `one` and `zero`
+ adapt `lalib.elements.galois.GF2Element.__eq__()` to return
`NotImplemented` instead of `False` for non-castable `other`s
=> this fixes a minor issue with `pytest.approx()`
- implement `lalib.fields.rational.RationalField`, or `Q` for short,
the field over the rational numbers (modeled as `fractions.Fraction`s)
- implement `lalib.fields.real.RealField`, or `R` for short,
the field over the real numbers (modeled as `float`s)
- organize top-level imports for `lalib.fields`,
making `Q`, `R`, `C`, and `GF2` importable with
`from lalib.fields import *`
- provide extensive unit and integration tests for the new objects:
+ test generic and common behavior in `tests.fields.test_base`
+ test specific behavior is other modules
+ test the well-known math axioms for all fields (integration tests)
+ test the new objects' docstrings
+ add "pytest-repeat" to run randomized tests many times