irgeek / strenum Goto Github PK
View Code? Open in Web Editor NEWA Python Enum that inherits from str.
License: MIT License
A Python Enum that inherits from str.
License: MIT License
How about using Poetry to manage dependencies? Also potentially could use tox to test against different python versions.
Under mypy 0.991
, it doesn't appear that we can use Literal
types whose values are StrEnum
elements. With the following sample code:
from enum import Enum
from typing import Literal, TypedDict
from strenum import StrEnum
class Entree(str, Enum):
spam = "SPAM"
eggs = "EGGS"
class Side(StrEnum):
bacon = "BACON"
grits = "GRITS"
class Breakfast(TypedDict):
entree: Entree
side: Side
class EggBreakfast(TypedDict):
entree: Literal[Entree.eggs]
side: Side
class BaconBreakfast(TypedDict):
entree: Entree
side: Literal[Side.bacon]
The mypy
output is:
type-error.py:28: error: Variable "type-error.Side.bacon" is not valid as a type [valid-type]
type-error.py:28: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
type-error.py:28: error: Parameter 1 of Literal[...] is invalid [valid-type]
Found 2 errors in 1 file (checked 1 source file)
Note that no error is thrown for Literal[Entree.eggs]
, which is defined on a (str, Enum)
value rather than a StrEnum
value.
I don't know whether this can be resolved from outside mypy
, but I wanted to make the maintainers here aware if they're not, and find out if there's a better way to do this that I haven't come up with yet. In particular, Literal["BACON"]
does remove the error, but is clearly not ideal.
Some other libraries such as @dataclass
, just use type hints without explicit value set
class C:
a: int
Maybe we could do the same and use this:
class HTTP(StrEnum):
GET: str
POST: str
instead of (or in addition to) the current syntax:
class HTTP(StrEnum):
GET = auto()
POST = auto()
I'd argue that makes it look more pythonic by being explicit in the intent of the variables being of typestr
Hi,
I'm getting an error message when running mypy. Here's a reproducer
mypy.py
from enum import auto
from strenum import StrEnum
class HttpMethod(StrEnum):
GET = auto()
HEAD = auto()
class MyClass:
def __init__(self, method: HttpMethod) -> None:
self.method = method
MyClass(HttpMethod.GET)
mypy error message:
mypy --ignore-missing-imports mypy.py
mypy.py:16: error: Argument 1 to "MyClass" has incompatible type "auto"; expected "HttpMethod"
Found 1 error in 1 file (checked 1 source file)
It seems that StrEnum installation creates a new package in site-packages
.
ls <path-to-virtualenv>/site-packages/tests/
__init__.py __pycache__ test_comparable.py test_name_mangler.py test_strenum_casefold.py test_strenum_name_mangler.py test_strenum.py
In my case, this caused tests in my project to fail, as importing something like tests.mock_data
would no longer work.
I'm using Poetry, this may make matters worse in this case.
I believe this is unintended.
Hi,
Thank you for this package. I am cutting a PR to the conda-forge/staged-recipes repo to make this available via the Conda Forge for those who use anaconda as their package manager. Would you like to be listed as a recipe maintainer as well as me? Totally understand either way. Just as an FYI, if you do wish to be listed as a recipe maintainer, version updates are generally automated, but every now and then they require manual intervention. You will also periodically get notifications related to the repo associated with the recipe.
Let me know what you decide, and again, thanks!
Is there any way to make case-insensitive StrEnum
without changing EnumMeta
class?
That is what I mean:
class InterpMethods(StrEnum, case_sensitive=False):
LINEAR = auto()
CUBIC = auto()
LANCZOS = auto()
print(InterpMethods.LINEAR)
# <InterpMethods.LINEAR: 'LINEAR'>
assert InterpMethods.LINEAR == 'linear'
assert InterpMethods.LINEAR == 'Linear'
assert InterpMethods.LINEAR == 'LINEAR'
assert InterpMethods('linear') == InterpMethods.LINEAR
assert InterpMethods('Linear') == InterpMethods.LINEAR
assert InterpMethods('LINEAR') == InterpMethods.LINEAR
Real-life usage example:
import click
from strenum import StrEnum, auto
from something import linear, cubic, lanczos
class InterpMethods(StrEnum, case_sensitive=False):
LINEAR = auto(), linear
CUBIC = auto(), cubic
LANCZOS = auto(), lanczos
def __new__(cls, value, calculator):
obj = str.__new__(cls, value)
obj._value_ = value
obj.apply = calculator
return obj
@click.command()
@click.option('-m', '--method', type=click.Choices(InterpMethods, case_sensitive=False))
def cli(method: InterpMethods):
...
result = method.apply(data)
# Usage of CLI:
# > cli -m linear
# > cli -m Linear
# > cli -m LINEAR
Steps to reproduce.
mkdir check_strenum && cd !$
python3.7 -m venv env && . env/bin/activate
pip install strenum mypy
from strenum import StrEnum
class MyCheck(StrEnum):
PASS: str = 'pass'
FAIL: str = 'fail'
mypy
:mypy --install-types --strict check_strenum.py
Actual result:
check_strenum.py:1: error: Skipping analyzing "strenum": module is installed, but missing library stubs or py.typed marker [import]
check_strenum.py:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
check_strenum.py:3: error: Class cannot subclass "StrEnum" (has type "Any") [misc]
Found 2 errors in 1 file (checked 1 source file)
Expected result:
Success: no issues found in 1 source file
Here are the contents of the package after it's installed with pip.
$ ll env/lib/python3.7/site-packages/strenum/
total 36K
drwxr-xr-x 3 eugenesqr eugenesqr 4.0K Apr 27 13:16 .
drwxr-xr-x 19 eugenesqr eugenesqr 4.0K Apr 27 13:16 ..
drwxr-xr-x 2 eugenesqr eugenesqr 4.0K Apr 27 13:16 __pycache__
-rw-r--r-- 1 eugenesqr eugenesqr 8.4K Apr 27 13:16 __init__.py
-rw-r--r-- 1 eugenesqr eugenesqr 2.0K Apr 27 13:16 mixins.py
-rw-r--r-- 1 eugenesqr eugenesqr 3.4K Apr 27 13:16 _name_mangler.py
-rw-r--r-- 1 eugenesqr eugenesqr 498 Apr 27 13:16 _version.py
Note that *.pyi
files are missing.
If we manually copy stub files from the repo along with py.typed
, it starts working:
cd env/lib/python3.7/site-packages/strenum/
touch py.typed
curl -O https://raw.githubusercontent.com/irgeek/StrEnum/master/strenum/__init__.pyi
I believe these files should be included into the result package. For example via setup.py
:
package_data={'strenum': ['*.pyi', 'py.typed']},
I found that StrEnums couldn't support "in" so I wrote this for my own work:
class StrEnumMeta(EnumMeta):
def __contains__(cls, item):
if isinstance(item, str):
if item in cls.__members__.values():
return True
else:
return False
try:
return super().__contains__(item)
except TypeError:
return False
class MyEnum(str, Enum, metaclass=StrEnumMeta):
ITEM_ONE = 'one'
ITEM_TWO = 'two'
Might be worth making a metaclass for this...
Could you add this method to base StrEnum
so that pydantic.BaseModel.model_dump
and list
when applied to StrEnum
can return a normal string value?
class StrEnum:
...
def __repr__(self) -> str:
return str.__repr__(self.value)
I am currently subclassing StrEnum
to make it work, but couldn't be bothered to add it to every class you have here. Do you think this is a reasonable design choice for this lib?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.