Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(enums): fix types #1224

Merged
merged 29 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0ea77de
docs(enums): add docs to Enum (#1271)
bonjourmauko Oct 5, 2024
91beee1
docs(enums): add docs to EnumArray (#1271)
bonjourmauko Oct 5, 2024
15c67c0
docs(enums): fix sphinx markup (#1271)
bonjourmauko Oct 5, 2024
6300df6
style(enums): fix linter issues (#1271)
bonjourmauko Oct 5, 2024
8be6ae4
style(sphinx): fix more doc markup errors (#1271)
bonjourmauko Oct 5, 2024
6783cb6
chore: version bump (fixes #1271)
bonjourmauko Oct 5, 2024
00120b1
test(enums): fix doctests (#1267)
bonjourmauko Oct 6, 2024
993a04f
test(enums): fix Enum.decode (#1267)
bonjourmauko Oct 7, 2024
0195451
refactor(enums): remove magic methods (#1267)
bonjourmauko Oct 7, 2024
b5b7968
fix(enums): do actual indexing (#1267)
bonjourmauko Oct 9, 2024
cbc7fdb
build(test): add enums to test path (#1267)
bonjourmauko Oct 9, 2024
cd6ca32
fix(enums): failing doctest when AttributeError (#1267)
bonjourmauko Oct 9, 2024
38f99e0
fix(enums): ensure __eq__ gives a numpy array (#1267)
bonjourmauko Oct 9, 2024
8074af4
fix(enums): fix __repr__ (#1267)
bonjourmauko Oct 9, 2024
5259224
test(enums): update str eq test (#1267)
bonjourmauko Oct 9, 2024
6dfc93f
chore: version bump (fixes #1267)
bonjourmauko Oct 9, 2024
803680c
docs(enums): add types (#1233)
bonjourmauko Oct 9, 2024
b8efde7
test(enums): fix mypy errors (#1233)
bonjourmauko Oct 9, 2024
c54d3a5
chore: version bump (fixes #1233)
bonjourmauko Oct 9, 2024
62c29b7
fix(enums): preserve order in encode (#1233)
bonjourmauko Oct 10, 2024
a69cb0a
fix(enums): do really proper indexing (#1233)
bonjourmauko Oct 10, 2024
bbecb0e
feat(enums): add custom error (#1233)
bonjourmauko Oct 10, 2024
67f14dc
refactor(enums): cache index arrays (#1233)
bonjourmauko Oct 10, 2024
573eb2f
refactor(enums): make __eq__ faster (#1233)
bonjourmauko Oct 11, 2024
8494e6c
refactor(enums): make dtype check faster (#1233)
bonjourmauko Oct 11, 2024
73b296a
chore(enums): remove leftovers (#1233)
bonjourmauko Oct 12, 2024
02c0576
refactor(enums): consolidate encode(#1233)
bonjourmauko Oct 13, 2024
ef85e1f
refactor(enums): improve performance enum array (#1233)
bonjourmauko Oct 13, 2024
9b7d9c9
chore!: version bump (fixes #1271 #1267 #1233)
bonjourmauko Oct 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,64 @@
# Changelog

### 42.1.1 [#1224](https://github.com/openfisca/openfisca-core/pull/1224)

#### Technical changes

- Fix type definitions in the enums module

## 42.1.0 [#1273](https://github.com/openfisca/openfisca-core/pull/1273)

#### New features

- Introduce `indexed_enums.EnumType`
- Allows for actually fancy indexing `indexed_enums.Enum`

#### Technical changes

- Fix doctests
- Now `pytest openfisca_core/indexed_enums` runs without errors
- Fix bug in `Enum.encode` when passing a scalar
- Still raises `TypeError` but with an explanation of why it fails
- Fix bug in `Enum.encode` when encoding values not present in the enum
- When encoding values not present in an enum, `Enum.encode` always encoded
the first item of the enum
- Now, it correctly encodes only the values requested that exist in the enum

##### Before

```python
from openfisca_core import indexed_enums as enum

class TestEnum(enum.Enum):
ONE = "one"
TWO = "two"

TestEnum.encode([2])
# EnumArray([0])
```

##### After

```python
from openfisca_core import indexed_enums as enum

class TestEnum(enum.Enum):
ONE = "one"
TWO = "two"

TestEnum.encode([2])
# EnumArray([])

TestEnum.encode([0,1,2,5])
# EnumArray([<TestEnum.ONE: 'one'> <TestEnum.TWO: 'two'>])
```

### 42.0.8 [#1272](https://github.com/openfisca/openfisca-core/pull/1272)

#### Documentation

- Add documentation to the `indexed_enums` module

### 42.0.7 [#1264](https://github.com/openfisca/openfisca-core/pull/1264)

#### Technical changes
Expand Down
53 changes: 1 addition & 52 deletions openfisca_core/commons/__init__.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,4 @@
"""Common tools for contributors and users.

The tools in this sub-package are intended, to help both contributors
to OpenFisca Core and to country packages.

Official Public API:
* :func:`.apply_thresholds`
* :func:`.average_rate`
* :func:`.concat`
* :func:`.empty_clone`
* :func:`.eval_expression`
* :func:`.marginal_rate`
* :func:`.stringify_array`
* :func:`.switch`

Deprecated:
* :class:`.Dummy`

Note:
The ``deprecated`` imports are transitional, in order to ensure non-breaking
changes, and could be removed from the codebase in the next
major release.

Note:
How imports are being used today::

from openfisca_core.commons import * # Bad
from openfisca_core.commons.formulas import switch # Bad
from openfisca_core.commons.decorators import deprecated # Bad


The previous examples provoke cyclic dependency problems, that prevent us
from modularizing the different components of the library, which would make
them easier to test and to maintain.

How they could be used in a future release::

from openfisca_core import commons
from openfisca_core.commons import deprecated

deprecated() # Good: import classes as publicly exposed
commons.switch() # Good: use functions as publicly exposed

.. seealso:: `PEP8#Imports`_ and `OpenFisca's Styleguide`_.

.. _PEP8#Imports:
https://www.python.org/dev/peps/pep-0008/#imports

.. _OpenFisca's Styleguide:
https://github.com/openfisca/openfisca-core/blob/master/STYLEGUIDE.md

"""
"""Common tools for contributors and users."""

from . import types
from .dummy import Dummy
Expand Down
14 changes: 3 additions & 11 deletions openfisca_core/commons/formulas.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ def apply_thresholds(
choices: A list of the possible values to choose from.

Returns:
Array[numpy.float32]: A list of the values chosen.

Raises:
AssertionError: When thresholds and choices are incompatible.
ndarray[float32]: A list of the values chosen.

Examples:
>>> input = numpy.array([4, 5, 6, 7, 8])
Expand All @@ -37,7 +34,6 @@ def apply_thresholds(
array([10, 10, 15, 15, 20])

"""

condlist: list[t.Array[numpy.bool_] | bool]
condlist = [input <= threshold for threshold in thresholds]

Expand Down Expand Up @@ -66,7 +62,7 @@ def concat(
that: Another array to concatenate.

Returns:
Array[numpy.str_]: An array with the concatenated values.
ndarray[str_]: An array with the concatenated values.

Examples:
>>> this = ["this", "that"]
Expand All @@ -75,7 +71,6 @@ def concat(
array(['this1.0', 'that2.5']...)

"""

if not isinstance(this, numpy.ndarray):
this = numpy.array(this)

Expand Down Expand Up @@ -105,10 +100,7 @@ def switch(
value_by_condition: Values to replace for each condition.

Returns:
Array: An array with the replaced values.

Raises:
AssertionError: When ``value_by_condition`` is empty.
ndarray[float32]: An array with the replaced values.

Examples:
>>> conditions = numpy.array([1, 1, 1, 2])
Expand Down
8 changes: 3 additions & 5 deletions openfisca_core/commons/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def empty_clone(original: object) -> object:
original: An object to clone.

Returns:
The cloned, empty, object.
object: The cloned, empty, object.

Examples:
>>> Foo = type("Foo", (list,), {})
Expand Down Expand Up @@ -50,7 +50,7 @@ def stringify_array(array: None | t.Array[numpy.generic]) -> str:
array: An array.

Returns:
str: "None" if the ``array`` is None.
str: ``"None"`` if the ``array`` is ``None``.
str: The stringified ``array`` otherwise.

Examples:
Expand All @@ -71,7 +71,6 @@ def stringify_array(array: None | t.Array[numpy.generic]) -> str:
"[<class 'list'>, {}, <function stringify_array...]"

"""

if array is None:
return "None"

Expand All @@ -87,7 +86,7 @@ def eval_expression(
expression: An expression to evaluate.

Returns:
Array: The result of the evaluation.
ndarray: The result of the evaluation.
str: The expression if it couldn't be evaluated.

Examples:
Expand All @@ -98,7 +97,6 @@ def eval_expression(
'salary'

"""

try:
return numexpr.evaluate(expression)

Expand Down
12 changes: 5 additions & 7 deletions openfisca_core/commons/rates.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def average_rate(
trim: The lower and upper bounds of the average rate.

Returns:
Array[numpy.float32]: The average rate for each target. When ``trim``
ndarray[float32]: The average rate for each target. When ``trim``
is provided, values that are out of the provided bounds are
replaced by :any:`numpy.nan`.
replaced by :obj:`numpy.nan`.

Examples:
>>> target = numpy.array([1, 2, 3])
Expand All @@ -37,7 +37,6 @@ def average_rate(
array([ nan, 0. , -0.5])

"""

if not isinstance(varying, numpy.ndarray):
varying = numpy.array(varying, dtype=numpy.float32)

Expand Down Expand Up @@ -79,9 +78,9 @@ def marginal_rate(
trim: The lower and upper bounds of the marginal rate.

Returns:
Array[numpy.float32]: The marginal rate for each target. When ``trim``
is provided, values that are out of the provided bounds are replaced by
:any:`numpy.nan`.
ndarray[float32]: The marginal rate for each target. When ``trim``
is provided, values that are out of the provided bounds are
replaced by :class:`numpy.nan`.

Examples:
>>> target = numpy.array([1, 2, 3])
Expand All @@ -91,7 +90,6 @@ def marginal_rate(
array([nan, 0.5])

"""

if not isinstance(varying, numpy.ndarray):
varying = numpy.array(varying, dtype=numpy.float32)

Expand Down
1 change: 0 additions & 1 deletion openfisca_core/commons/tests/test_dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@

def test_dummy_deprecation() -> None:
"""Dummy throws a deprecation warning when instantiated."""

with pytest.warns(DeprecationWarning):
assert Dummy()
7 changes: 0 additions & 7 deletions openfisca_core/commons/tests/test_formulas.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

def test_apply_thresholds_when_several_inputs() -> None:
"""Make a choice for any given input."""

input_ = numpy.array([4, 5, 6, 7, 8, 9, 10])
thresholds = [5, 7, 9]
choices = [10, 15, 20, 25]
Expand All @@ -19,7 +18,6 @@ def test_apply_thresholds_when_several_inputs() -> None:

def test_apply_thresholds_when_too_many_thresholds() -> None:
"""Raise an AssertionError when thresholds > choices."""

input_ = numpy.array([6])
thresholds = [5, 7, 9, 11]
choices = [10, 15, 20]
Expand All @@ -30,7 +28,6 @@ def test_apply_thresholds_when_too_many_thresholds() -> None:

def test_apply_thresholds_when_too_many_choices() -> None:
"""Raise an AssertionError when thresholds < choices - 1."""

input_ = numpy.array([6])
thresholds = [5, 7]
choices = [10, 15, 20, 25]
Expand All @@ -41,7 +38,6 @@ def test_apply_thresholds_when_too_many_choices() -> None:

def test_concat_when_this_is_array_not_str() -> None:
"""Cast ``this`` to ``str`` when it is a NumPy array other than string."""

this = numpy.array([1, 2])
that = numpy.array(["la", "o"])

Expand All @@ -52,7 +48,6 @@ def test_concat_when_this_is_array_not_str() -> None:

def test_concat_when_that_is_array_not_str() -> None:
"""Cast ``that`` to ``str`` when it is a NumPy array other than string."""

this = numpy.array(["ho", "cha"])
that = numpy.array([1, 2])

Expand All @@ -63,7 +58,6 @@ def test_concat_when_that_is_array_not_str() -> None:

def test_concat_when_args_not_str_array_like() -> None:
"""Cast ``this`` and ``that`` to a NumPy array or strings."""

this = (1, 2)
that = (3, 4)

Expand All @@ -74,7 +68,6 @@ def test_concat_when_args_not_str_array_like() -> None:

def test_switch_when_values_are_empty() -> None:
"""Raise an AssertionError when the values are empty."""

conditions = [1, 1, 1, 2]
value_by_condition = {}

Expand Down
2 changes: 0 additions & 2 deletions openfisca_core/commons/tests/test_rates.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

def test_average_rate_when_varying_is_zero() -> None:
"""Yield infinity when the varying gross income crosses zero."""

target = numpy.array([1, 2, 3])
varying = [0, 0, 0]

Expand All @@ -19,7 +18,6 @@ def test_average_rate_when_varying_is_zero() -> None:

def test_marginal_rate_when_varying_is_zero() -> None:
"""Yield infinity when the varying gross income crosses zero."""

target = numpy.array([1, 2, 3])
varying = numpy.array([0, 0, 0])

Expand Down
23 changes: 1 addition & 22 deletions openfisca_core/data_storage/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,4 @@
# Transitional imports to ensure non-breaking changes.
# Could be deprecated in the next major release.
#
# How imports are being used today:
#
# >>> from openfisca_core.module import symbol
#
# The previous example provokes cyclic dependency problems
# that prevent us from modularizing the different components
# of the library so to make them easier to test and to maintain.
#
# How could them be used after the next major release:
#
# >>> from openfisca_core import module
# >>> module.symbol()
#
# And for classes:
#
# >>> from openfisca_core.module import Symbol
# >>> Symbol()
#
# See: https://www.python.org/dev/peps/pep-0008/#imports
"""Different storage backends for the data of a simulation."""

from . import types
from .in_memory_storage import InMemoryStorage
Expand Down
Loading