basicenum
Simple(r) enums.
basicenum.compat
A (mostly) API-compatible re-implementation of
enum.Enum from the
stdlib (plus related code).
The goal for this module was to try and re-implement as much of the API of
enum.Enum as possible while using modern Python features. While this does lead
to some API breakage (e.g. type(enum.member) == type(enum) is no longer true),
it mostly revolves around metaclass-level details. If you rely on the surface
API for enum.Enum, then this module should be compatible.
API Compatibility
Using the example enum:
class Colour(Enum):
RED = auto()
GREEN = auto()
BLUE = auto()
The compatibility with enum.Enum is:
| Feature | Supported? |
|---|---|
repr(Colour.RED) |
✅ |
str(Colour.RED) |
✅ |
type(Colour.RED) |
❌ (Member instead) |
isinstance(Colour.RED, Colour) |
✅ |
iter(Colour) |
✅ |
hash(Colour.RED) |
✅ |
Colour(1) |
✅ |
Colour["RED"] |
✅ |
Colour.RED in Colour |
✅ |
Colour.RED.name |
✅ |
Colour.RED.value |
✅ |
auto() |
✅ |
_generate_next_value_() |
✅ |
Colour.__members__ |
✅ |
Colour.RED == Colour.RED |
✅ |
| Restricted subclassing | ❌ |
| Pickling | ✅ |
| Functional API | ✅ (via create()) |
Type Checking
Unfortunately, type checkers hard-code their support for enum.Enum. That means
they do not recognize members of basicenum.compat.Enum as being instances of
Member or matching the API of members of enum.Enum.
Luckily, you can lie to the type checkers. You can tell them to type check as if
you're using enum while using basicenum.compat during execution.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from enum import Enum, auto
else:
from basicenum.compat import Enum, auto
Benchmarking
If you install the [benchmark] extra, you can use
richbench to see a performance
comparison between enum and basicenum.compat.
Results
On a MacBook Pro (Retina, 13-inch, Early 2015):
richbench --repeat 5 --times 5 --benchmark compat benchmarks/
| Benchmark | Min | Max | Mean | Min (+) | Max (+) | Mean (+) |
|---|---|---|---|---|---|---|
| import | 0.374 | 0.503 | 0.422 | 0.117 (3.2x) | 0.120 (4.2x) | 0.119 (3.5x) |
creation w/ auto() |
0.422 | 0.429 | 0.425 | 0.075 (5.7x) | 0.077 (5.5x) | 0.076 (5.6x) |
_generate_next_value_() |
0.373 | 0.383 | 0.376 | 0.077 (4.8x) | 0.078 (4.9x) | 0.078 (4.8x) |
| creation w/ constants | 0.333 | 0.351 | 0.339 | 0.060 (5.5x) | 0.066 (5.4x) | 0.063 (5.4x) |
| functional API | 0.392 | 0.397 | 0.394 | 0.070 (5.6x) | 0.074 (5.4x) | 0.072 (5.5x) |
| isinstance(..., Enum) | 0.189 | 0.191 | 0.190 | 0.279 (-1.5x) | 0.282 (-1.5x) | 0.280 (-1.5x) |
iter(Enum) |
0.912 | 0.922 | 0.917 | 0.197 (4.6x) | 0.199 (4.6x) | 0.198 (4.6x) |
Enum(...) |
0.297 | 0.297 | 0.297 | 0.078 (3.8x) | 0.079 (3.8x) | 0.078 (3.8x) |
Enum[...] |
0.121 | 0.122 | 0.121 | 0.075 (1.6x) | 0.139 (-1.1x) | 0.093 (1.3x) |
... in Enum |
0.267 | 0.375 | 0.308 | 0.162 (1.6x) | 0.164 (2.3x) | 0.163 (1.9x) |
| member access | 0.333 | 0.337 | 0.334 | 0.118 (2.8x) | 0.121 (2.8x) | 0.119 (2.8x) |
| value access | 0.735 | 0.761 | 0.744 | 0.141 (5.2x) | 0.143 (5.3x) | 0.142 (5.2x) |
| equality | 0.343 | 0.345 | 0.344 | 0.103 (3.3x) | 0.107 (3.2x) | 0.105 (3.3x) |
| repr | 0.379 | 0.386 | 0.382 | 0.236 (1.6x) | 0.238 (1.6x) | 0.237 (1.6x) |
| hashing | 0.345 | 0.355 | 0.348 | 0.245 (1.4x) | 0.250 (1.4x) | 0.247 (1.4x) |
| pickling | 0.270 | 0.272 | 0.271 | 0.270 (-1.0x) | 0.274 (-1.0x) | 0.272 (-1.0x) |
| unpickling | 0.229 | 0.232 | 0.231 | 0.230 (-1.0x) | 0.232 (-1.0x) | 0.231 (-1.0x) |
__members__ |
0.373 | 0.381 | 0.376 | 0.046 (8.1x) | 0.047 (8.1x) | 0.046 (8.1x) |
@unique |
0.518 | 0.523 | 0.520 | 0.104 (5.0x) | 0.109 (4.8x) | 0.106 (4.9x) |
Module Contents
Enum
The class to inherit from to create an enum.
Member
The class which all enum members are instances of.
auto()
Function for automatic, incrementing integer member values.
@unique
Guarantee that all enum members have unique values.
Raises ValueError if values are not all unique.
create()
A re-implementation of the functional API of enum.Enum.
def create(
enum_name, member_names, /, *, module=None, qualname=None, type=None, start=1
): ...
Metadata
Release files for basicenum 2023.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| basicenum-2023.1.tar.gz | 6.8 kB | Without provenance | Details for basicenum-2023.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| basicenum-2023.1-py3-none-any.whl | Python 3 | none | any | Details for basicenum-2023.1-py3-none-any.whl |
Total release size: 13.5 kB
Release files / basicenum-2023.1.tar.gz
| Download URL | basicenum-2023.1.tar.gz |
|---|---|
| Size | 6.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
695f1e5101d89f3b74889b79b3c88c071f96352c8d5f3a1535f541961f69ae81
|
|
BLAKE2b-256 checksum How to use checksums |
031de40e5c09b0e582f5d7775f7118b8a56e9a050b5f335f06d9e0d996d68cce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/4.0.2 CPython/3.11.7
|
Release files / basicenum-2023.1-py3-none-any.whl
| Download URL | basicenum-2023.1-py3-none-any.whl |
|---|---|
| Size | 6.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6c345483e4bf2c9a56a4fdf4f4713bdd47ae3f403dec265f44220c2ac54aabaa
|
|
BLAKE2b-256 checksum How to use checksums |
3bb41d33a2de0ed7488c7c06703108bbe90303560b625a5ca71a5539026db73a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/4.0.2 CPython/3.11.7
|
Security for basicenum 2023.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.