Enum & EnumArray

Enumerations for variables with a limited set of possible values.

openfisca_core.indexed_enums.ENUM_ARRAY_DTYPE

alias of int16

class openfisca_core.indexed_enums.Enum(*_Enum__args, **_Enum__kwargs)[source]

Enum based on enum34.

Its items have an int index, useful and performant when running simulations on large populations.

Examples

>>> from openfisca_core import indexed_enums as enum
>>> class Housing(enum.Enum):
...     OWNER = "Owner"
...     TENANT = "Tenant"
...     FREE_LODGER = "Free lodger"
...     HOMELESS = "Homeless"
>>> repr(Housing)
"<enum 'Housing'>"
>>> repr(Housing.TENANT)
'Housing.TENANT'
>>> str(Housing.TENANT)
'Housing.TENANT'
>>> dict([(Housing.TENANT, Housing.TENANT.value)])
{Housing.TENANT: 'Tenant'}
>>> list(Housing)
[Housing.OWNER, Housing.TENANT, Housing.FREE_LODGER, Housing.HOMELESS]
>>> Housing["TENANT"]
Housing.TENANT
>>> Housing("Tenant")
Housing.TENANT
>>> Housing.TENANT in Housing
True
>>> len(Housing)
4
>>> Housing.TENANT == Housing.TENANT
True
>>> Housing.TENANT != Housing.TENANT
False
>>> Housing.TENANT.index
1
>>> Housing.TENANT.name
'TENANT'
>>> Housing.TENANT.value
'Tenant'
__eq__(other)[source]

Return self==value.

Return type:

bool

__ne__(other)[source]

Return self!=value.

Return type:

bool

__new__(value)[source]
classmethod encode(array)[source]

Encode an encodable array into an EnumArray.

Parameters:

array (ndarray[Any, dtype[generic]] | Sequence[object]) – ndarray to encode.

Returns:

EnumArray – An EnumArray with the encoded input values.

Return type:

EnumArray

Examples

>>> import numpy
>>> from openfisca_core import indexed_enums as enum
>>> class Housing(enum.Enum):
...     OWNER = "Owner"
...     TENANT = "Tenant"

# EnumArray

>>> array = numpy.array([1])
>>> enum_array = enum.EnumArray(array, Housing)
>>> Housing.encode(enum_array)
EnumArray([Housing.TENANT])

# Array of Enum

>>> array = numpy.array([Housing.TENANT])
>>> enum_array = Housing.encode(array)
>>> enum_array == Housing.TENANT
array([ True])

# Array of integers

>>> array = numpy.array([1])
>>> enum_array = Housing.encode(array)
>>> enum_array == Housing.TENANT
array([ True])

# Array of strings

>>> array = numpy.array(["TENANT"])
>>> enum_array = Housing.encode(array)
>>> enum_array == Housing.TENANT
array([ True])

# Array of bytes

>>> array = numpy.array([b"TENANT"])
>>> enum_array = Housing.encode(array)
Traceback (most recent call last):
EnumEncodingError: Failed to encode "[b'TENANT']" of type 'bytes...

See also

EnumArray.decode() for decoding.

index: int

The index of the Enum member.

class openfisca_core.indexed_enums.EnumArray(input_array: ndarray[Any, dtype[uint8]], possible_values: type[Enum])[source]

A subclass of ndarray of Enum.

Enum arrays are encoded as int to improve performance.

Note

Subclassing ndarray is a little tricky™. To read more about the __new__() and __array_finalize__() methods below, see Subclassing ndarray.

Examples

>>> import numpy
>>> from openfisca_core import indexed_enums as enum, variables
>>> class Housing(enum.Enum):
...     OWNER = "Owner"
...     TENANT = "Tenant"
...     FREE_LODGER = "Free lodger"
...     HOMELESS = "Homeless"
>>> array = numpy.array([1], dtype=numpy.int16)
>>> enum_array = enum.EnumArray(array, Housing)
>>> repr(enum.EnumArray)
"<class 'openfisca_core.indexed_enums.enum_array.EnumArray'>"
>>> repr(enum_array)
'EnumArray([Housing.TENANT])'
>>> str(enum_array)
"['TENANT']"
>>> list(map(int, enum_array))
[1]
>>> int(enum_array[0])
1
>>> enum_array[0] in enum_array
True
>>> len(enum_array)
1
>>> enum_array = enum.EnumArray(list(Housing), Housing)
Traceback (most recent call last):
AttributeError: 'list' object has no attribute 'view'
>>> class OccupancyStatus(variables.Variable):
...     value_type = enum.Enum
...     possible_values = Housing
>>> enum.EnumArray(array, OccupancyStatus.possible_values)
EnumArray([Housing.TENANT])
__array_finalize__(obj)[source]

See comment above.

Return type:

None

__eq__(other)[source]

Compare equality with the item’s index.

When comparing to an item of possible_values, use the item’s index. to speed up the comparison.

Whenever possible, use numpy.ndarray.view so that the result is a classic ndarray, not an EnumArray.

Parameters:

other (object) – Another object to compare to.

Returns:
  • bool – When ???

  • ndarray[bool_] – When ???

Return type:

ndarray[Any, dtype[bool_]]

Examples

>>> import numpy
>>> from openfisca_core import indexed_enums as enum
>>> class Housing(enum.Enum):
...     OWNER = "Owner"
...     TENANT = "Tenant"
>>> array = numpy.array([1])
>>> enum_array = enum.EnumArray(array, Housing)
>>> enum_array == Housing
array([False,  True])
>>> enum_array == Housing.TENANT
array([ True])
>>> enum_array == 1
array([ True])
>>> enum_array == [1]
array([ True])
>>> enum_array == [2]
array([False])
>>> enum_array == "1"
array([False])
>>> enum_array is None
False
>>> enum_array == enum.EnumArray(numpy.array([1]), Housing)
array([ True])

Note

This breaks the Liskov substitution principle.

__ne__(other)[source]

Inequality.

Parameters:

other (object) – Another object to compare to.

Returns:
  • bool – When ???

  • ndarray[bool_] – When ???

Return type:

ndarray[Any, dtype[bool_]]

Examples

>>> import numpy
>>> from openfisca_core import indexed_enums as enum
>>> class Housing(enum.Enum):
...     OWNER = "Owner"
...     TENANT = "Tenant"
>>> array = numpy.array([1])
>>> enum_array = enum.EnumArray(array, Housing)
>>> enum_array != Housing
array([ True, False])
>>> enum_array != Housing.TENANT
array([False])
>>> enum_array != 1
array([False])
>>> enum_array != [1]
array([False])
>>> enum_array != [2]
array([ True])
>>> enum_array != "1"
array([ True])
>>> enum_array is not None
True

Note

This breaks the Liskov substitution principle.

static __new__(cls, input_array, possible_values)[source]

See comment above.

Return type:

Self

decode()[source]

Decode itself to a normal array.

Returns:

ndarray[Enum] – The items of the EnumArray.

Raises:

TypeError – When the possible_values is not defined.

Return type:

ndarray[Any, dtype[object_]]

Examples

>>> import numpy
>>> from openfisca_core import indexed_enums as enum
>>> class Housing(enum.Enum):
...     OWNER = "Owner"
...     TENANT = "Tenant"
>>> array = numpy.array([1])
>>> enum_array = enum.EnumArray(array, Housing)
>>> enum_array.decode()
array([Housing.TENANT], dtype=object)
decode_to_str()[source]

Decode itself to an array of strings.

Returns:

ndarray[str_] – The string values of the EnumArray.

Raises:

TypeError – When the possible_values is not defined.

Return type:

ndarray[Any, dtype[str_]]

Examples

>>> import numpy
>>> from openfisca_core import indexed_enums as enum
>>> class Housing(enum.Enum):
...     OWNER = "Owner"
...     TENANT = "Tenant"
>>> array = numpy.array([1])
>>> enum_array = enum.EnumArray(array, Housing)
>>> enum_array.decode_to_str()
array(['TENANT'], dtype='<U6')
possible_values: None | type[Enum]

Enum type of the array items.

exception openfisca_core.indexed_enums.EnumEncodingError(enum_class, value)[source]

Raised when an enum is encoded with an unsupported type.

exception openfisca_core.indexed_enums.EnumMemberNotFoundError(enum_class)[source]

Raised when a member is not found in an enum.

final class openfisca_core.indexed_enums.EnumType(name: str, bases: tuple[type, ...], classdict: _EnumDict, **kwds: object)[source]

Meta class for creating an indexed Enum.

Examples

>>> from openfisca_core import indexed_enums as enum
>>> class Enum(enum.Enum, metaclass=enum.EnumType):
...     pass
>>> Enum.items
Traceback (most recent call last):
AttributeError: ...
>>> class Housing(Enum):
...     OWNER = "Owner"
...     TENANT = "Tenant"
>>> Housing.indices
array([0, 1], dtype=uint8)
>>> Housing.names
array(['OWNER', 'TENANT'], dtype='<U6')
>>> Housing.enums
array([Housing.OWNER, Housing.TENANT], dtype=object)
static __new__(metacls, name, bases, classdict, **kwds)[source]

Create a new indexed enum class.

Return type:

EnumType