Skip to content

Commit ed1b791

Browse files
authored
Merge pull request #10 from irgeek/comparable
* Add a Comparable mix-in * Add a MACRO_CASE StrEnum * Add RTD documentation - https://strenum.readthedocs.io/en/latest/ * Drop Python 3.5 in tests
2 parents eddc875 + 6288ae4 commit ed1b791

File tree

16 files changed

+341
-47
lines changed

16 files changed

+341
-47
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
runs-on: ubuntu-latest
1414
strategy:
1515
matrix:
16-
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
16+
python-version: [3.6, 3.7, 3.8, 3.9]
1717

1818
steps:
1919
- uses: actions/checkout@v2

.readthedocs.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
version: 2
3+
sphinx:
4+
configuration: docs/conf.py
5+
6+
formats:
7+
- pdf
8+
9+
python:
10+
version: 3.8
11+
install:
12+
- method: pip
13+
path: .
14+
extra_requirements:
15+
- docs

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ upload-test: .venv/bin/twine dist
2929
.venv/bin/twine: .venv
3030
@.venv/bin/python3 -m pip install .[test,release]
3131

32+
.venv/bin/sphinx-build: .venv
33+
@.venv/bin/python3 -m pip install .[docs]
34+
3235
clean:
3336
@rm -rf .venv/ dist/ build/ *.egg-info .tox/ .eggs/ .pytest_cache/ .coverage
3437
@find -d * -name '*.pyc' -delete -o -name __pycache__ -delete
38+
39+
SPHINX_COMMANDS := html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf latexpdfja text man texinfo info gettext changes xml pseudoxml linkcheck doctest coverage
40+
41+
$(SPHINX_COMMANDS): .venv/bin/sphinx-build
42+
@cd docs && ../.venv/bin/sphinx-build -M $@ . build

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ python3 -m venv .venv
131131
## License
132132
[MIT](https://choosealicense.com/licenses/mit/)
133133

134+
Contents
135+
--------
136+
137+
* [API Reference](api_ref.md)
138+
134139
**N.B. Starting with Python 3.10, `enum.StrEnum` is available in the standard
135140
library. This implementation is _not_ a drop-in replacement for the standard
136141
library implementation. Sepcifically, the Python devs have decided to case fold

docs/api_ref.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
API Reference
2+
=============
3+
4+
Enum Classes
5+
------------
6+
7+
```eval_rst
8+
.. automodule:: strenum
9+
:members:
10+
:show-inheritance:
11+
```
12+
13+
Mix-in Classes
14+
--------------
15+
16+
```eval_rst
17+
.. automodule:: strenum.mixins
18+
:members:
19+
:show-inheritance:
20+
```

docs/conf.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Configuration file for the Sphinx documentation builder.
2+
# pylint: disable=invalid-name,redefined-builtin,wrong-import-position
3+
#
4+
# This file only contains a selection of the most common options. For a full
5+
# list see the documentation:
6+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
7+
8+
# -- Path setup --------------------------------------------------------------
9+
10+
# If extensions (or modules to document with autodoc) are in another directory,
11+
# add these directories to sys.path here. If the directory is relative to the
12+
# documentation root, use os.path.abspath to make it absolute, like shown here.
13+
#
14+
import os
15+
import sys
16+
17+
import recommonmark
18+
from recommonmark.transform import AutoStructify
19+
20+
sys.path.insert(0, os.path.abspath(".."))
21+
22+
23+
import strenum
24+
25+
# -- Project information -----------------------------------------------------
26+
27+
project = "StrEnum"
28+
copyright = "2021, James Sinclair"
29+
author = "James Sinclair"
30+
31+
# The full version, including alpha/beta/rc tags
32+
release = strenum.__version__
33+
github_doc_root = "https://github.com/irgeek/strenum/tree/master/docs/"
34+
35+
36+
# -- General configuration ---------------------------------------------------
37+
38+
# Add any Sphinx extension module names here, as strings. They can be
39+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
40+
# ones.
41+
extensions = [
42+
# "sphinx.ext.autosectionlabel",
43+
"sphinx.ext.autodoc",
44+
# "sphinx.ext.viewcode",
45+
# "sphinx.ext.autosummary",
46+
"recommonmark",
47+
]
48+
49+
source_suffix = [".rst", ".md"]
50+
master_doc = "index"
51+
templates_path = []
52+
53+
html_theme = "sphinx_rtd_theme"
54+
html_static_path = []
55+
56+
exclude_patterns = [".venv"]
57+
58+
pygments_style = "sphinx"
59+
60+
autodoc_default_flags = ["members"]
61+
autosummary_generate = True
62+
63+
64+
def setup(app):
65+
app.add_config_value(
66+
"recommonmark_config",
67+
{
68+
#'url_resolver': lambda url: github_doc_root + url,
69+
"auto_toc_tree_section": "Contents",
70+
"enable_math": False,
71+
"enable_inline_math": False,
72+
"enable_eval_rst": True,
73+
},
74+
True,
75+
)
76+
app.add_transform(AutoStructify)

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../README.md

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[pytest]
2-
addopts = --cov=strenum --cov-report term-missing --black --pylint --ignore=versioneer.py --ignore=strenum/_version.py
2+
addopts = --cov=strenum --cov-report term-missing --black --pylint --ignore=versioneer.py --ignore=strenum/_version.py --ignore=docs/
33
filterwarnings = ignore::DeprecationWarning

setup.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@
2424
"pytest-pylint",
2525
"pylint",
2626
],
27+
"docs": [
28+
"sphinx",
29+
"sphinx_rtd_theme",
30+
"recommonmark",
31+
],
2732
"release": ["twine"],
2833
},
2934
setup_requires=["pytest-runner"],
30-
install_requires=["aenum;python_version<'3.6'"],
3135
classifiers=[
3236
"Development Status :: 5 - Production/Stable",
3337
"Programming Language :: Python :: 3 :: Only",
34-
"Programming Language :: Python :: 3.5",
3538
"Programming Language :: Python :: 3.6",
3639
"Programming Language :: Python :: 3.7",
3740
"Programming Language :: Python :: 3.8",

strenum/__init__.py

Lines changed: 111 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
try:
2-
import aenum as enum
3-
except ImportError:
4-
import enum
5-
1+
import enum
62
from ._version import get_versions
73
from ._name_mangler import _NameMangler
84

@@ -21,11 +17,26 @@
2117
# `self` arguments.
2218
# pylint: disable=no-self-argument
2319

20+
"""
21+
StrEnum contains a collection of subclasses of Python's `enum.Enum` that
22+
inherit from `str` to complement `enum.IntEnum` in the standard library.
23+
"""
24+
2425

2526
class StrEnum(str, enum.Enum):
2627
"""
27-
StrEnum is a Python `enum.Enum` that inherits from `str` to complement
28-
`enum.IntEnum` in the standard library.
28+
StrEnum is a Python `enum.Enum` that inherits from `str`.
29+
30+
Example usage::
31+
32+
class Example(StrEnum):
33+
UPPER_CASE = auto()
34+
lower_case = auto()
35+
MixedCase = auto()
36+
37+
assert Example.UPPER_CASE == "UPPER_CASE"
38+
assert Example.lower_case == "lower_case"
39+
assert Example.MixedCase == "MixedCase"
2940
"""
3041

3142
def __new__(cls, value, *args, **kwargs):
@@ -46,8 +57,19 @@ def _generate_next_value_(name, *_):
4657

4758
class LowercaseStrEnum(StrEnum):
4859
"""
49-
A subclass of `StrEnum` that the folds the member name to lowercase for the
50-
`auto()` value.
60+
A `StrEnum` that the folds values to lowercase.
61+
62+
Example usage::
63+
64+
class Example(LowercaseStrEnum):
65+
UPPER_CASE = auto()
66+
lower_case = auto()
67+
MixedCase = auto()
68+
69+
assert Example.UPPER_CASE == "upper_case"
70+
assert Example.lower_case == "lower_case"
71+
assert Example.MixedCase == "mixedcase"
72+
5173
"""
5274

5375
def _generate_next_value_(name, *_):
@@ -56,8 +78,18 @@ def _generate_next_value_(name, *_):
5678

5779
class UppercaseStrEnum(StrEnum):
5880
"""
59-
A subclass of `StrEnum` that the folds the member name to uppercase for the
60-
`auto()` value.
81+
A `StrEnum` that the folds values to UPPERCASE.
82+
83+
Example usage::
84+
85+
class Example(UppercaseStrEnum):
86+
UPPER_CASE = auto()
87+
lower_case = auto()
88+
MixedCase = auto()
89+
90+
assert Example.UPPER_CASE == "UPPER_CASE"
91+
assert Example.lower_case == "LOWER_CASE"
92+
assert Example.MixedCase == "MIXEDCASE"
6193
"""
6294

6395
def _generate_next_value_(name, *_):
@@ -66,8 +98,18 @@ def _generate_next_value_(name, *_):
6698

6799
class CamelCaseStrEnum(StrEnum):
68100
"""
69-
A subclass of `StrEnum` that the converts the member name to camelCase for the
70-
`auto()` value.
101+
A `StrEnum` that the converts values to camelCase.
102+
103+
Example usage::
104+
105+
class Example(CamelCaseStrEnum):
106+
UPPER_CASE = auto()
107+
lower_case = auto()
108+
MixedCase = auto()
109+
110+
assert Example.UPPER_CASE == "upperCase"
111+
assert Example.lower_case == "lowerCase"
112+
assert Example.MixedCase == "mixedCase"
71113
"""
72114

73115
def _generate_next_value_(name, *_):
@@ -76,8 +118,18 @@ def _generate_next_value_(name, *_):
76118

77119
class PascalCaseStrEnum(StrEnum):
78120
"""
79-
A subclass of `StrEnum` that the converts the member name to PascalCase for the
80-
`auto()` value.
121+
A `StrEnum` that the converts values to PascalCase.
122+
123+
Example usage::
124+
125+
class Example(PascalCaseStrEnum):
126+
UPPER_CASE = auto()
127+
lower_case = auto()
128+
MixedCase = auto()
129+
130+
assert Example.UPPER_CASE == "UpperCase"
131+
assert Example.lower_case == "LowerCase"
132+
assert Example.MixedCase == "MixedCase"
81133
"""
82134

83135
def _generate_next_value_(name, *_):
@@ -86,8 +138,18 @@ def _generate_next_value_(name, *_):
86138

87139
class KebabCaseStrEnum(StrEnum):
88140
"""
89-
A subclass of `StrEnum` that the converts the member name to kebab-case for the
90-
`auto()` value.
141+
A `StrEnum` that the converts values to kebab-case.
142+
143+
Example usage::
144+
145+
class Example(KebabCaseStrEnum):
146+
UPPER_CASE = auto()
147+
lower_case = auto()
148+
MixedCase = auto()
149+
150+
assert Example.UPPER_CASE == "upper-case"
151+
assert Example.lower_case == "lower-case"
152+
assert Example.MixedCase == "mixed-case"
91153
"""
92154

93155
def _generate_next_value_(name, *_):
@@ -96,9 +158,39 @@ def _generate_next_value_(name, *_):
96158

97159
class SnakeCaseStrEnum(StrEnum):
98160
"""
99-
A subclass of `StrEnum` that the converts the member name to snake-case for the
100-
`auto()` value.
161+
A `StrEnum` that the converts values to snake_case.
162+
163+
Example usage::
164+
165+
class Example(SnakeCaseStrEnum):
166+
UPPER_CASE = auto()
167+
lower_case = auto()
168+
MixedCase = auto()
169+
170+
assert Example.UPPER_CASE == "upper_case"
171+
assert Example.lower_case == "lower_case"
172+
assert Example.MixedCase == "mixed_case"
101173
"""
102174

103175
def _generate_next_value_(name, *_):
104176
return _name_mangler.snake(name)
177+
178+
179+
class MacroCaseStrEnum(StrEnum):
180+
"""
181+
A `StrEnum` that the converts values to MACRO_CASE.
182+
183+
Example usage::
184+
185+
class Example(MacroCaseStrEnum):
186+
UPPER_CASE = auto()
187+
lower_case = auto()
188+
MixedCase = auto()
189+
190+
assert Example.UPPER_CASE == "UPPER_CASE"
191+
assert Example.lower_case == "LOWER_CASE"
192+
assert Example.MixedCase == "MIXED_CASE"
193+
"""
194+
195+
def _generate_next_value_(name, *_):
196+
return _name_mangler.macro(name)

0 commit comments

Comments
 (0)