Skip to content

Commit

Permalink
Finish migration to new syntax (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmke8 committed Oct 8, 2023
1 parent bc73c9f commit 21a20d1
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 479 deletions.
22 changes: 13 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,30 @@ jobs:

runs-on: ubuntu-latest

strategy:
matrix:
directory: ["./type-enum", "./type-enum-plugin"]

defaults:
run:
working-directory: ./type-enum
working-directory: ${{ matrix.directory }}

steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
python-version: '3.11'
- name: Install ruff
run: |
python -m pip install --upgrade pip
pip install ruff
- name: Lint with ruff
run: |
ruff check --format=github type_enum
ruff check --output-format=github type_enum*
- name: Format with ruff
run: |
ruff format --check type_enum
ruff format --check type_enum*
run_tests:
Expand All @@ -45,11 +49,11 @@ jobs:
run: pipx install poetry
- uses: actions/setup-python@v4
with:
python-version: '3.10'
python-version: '3.11'

- name: Install dependencies
run: |
poetry env use 3.10
poetry env use 3.11
poetry install --no-interaction --no-root
- name: Run tests
run: |
Expand All @@ -68,12 +72,12 @@ jobs:
run: pipx install poetry
- uses: actions/setup-python@v4
with:
python-version: '3.10'
python-version: '3.11'

- name: Install dependencies
run: |
poetry env use 3.10
poetry env use 3.11
poetry install --no-interaction --no-root
- name: Run type check
run: |
poetry run mypy tests
poetry run mypy tests --enable-incomplete-feature=TypeVarTuple --enable-incomplete-feature=Unpack
42 changes: 12 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,28 @@
```
pip install type-enum
```

And for the mypy plugin:
```
pip install type-enum-plugin
```

Then register the plugin with
```toml
[tool.mypy]
plugins = "type_enum_plugin"
```

### Usage

```python
from type_enum import TypeEnum
from type_enum import Field, TypeEnum

class BgColor(TypeEnum):
transparent = ()
name = (str,)
rgb = (int, int, int)
hsv = (int, int, int)
transparent: Field[()]
name: Field[str]
rgb: Field[int, int, int]
hsv: Field[int, int, int]

background_color: BgColor = BgColor.rgb(39, 127, 168)
assert isinstance(background_color, BgColor)
Expand All @@ -36,28 +43,3 @@ match background_color:
print(f"HSV: {hue}, {saturation}, {value}")
# will print "RGB: 39, 127, 168"
```

You can also specify field names by using a dictionary instead of a tuple:

```python
from type_enum import TypeEnum

class BgColor(TypeEnum):
transparent = ()
name = (str,)
rgb = {"red": int, "green": int, "blue": int} # named args
hsv = {"hue": int, "saturation": int, "value": int}

background_color = BgColor.rgb(red=39, green=127, blue=168)
assert isinstance(background_color, BgColor)

match background_color:
case BgColor.transparent():
print("no color")
case BgColor.name(color_name):
print(f"color name: {color_name}")
case BgColor.rgb(red=r, green=g, blue=b):
print(f"RGB: {r}, {g}, {b}")
case BgColor.hsv(hue=h, saturation=s, value=v):
print(f"HSV: {h}, {s}, {v}")
```
223 changes: 51 additions & 172 deletions type-enum-plugin/poetry.lock

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion type-enum-plugin/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,21 @@ mypy = "*"

[tool.poetry.group.dev.dependencies]
mypy = "^1.0.1"
ruff = "^0.0.254"
ruff = ">=0.0.292"

[tool.ruff]
line-length = 88
select = [
"I", # isort
]

[tool.ruff.isort]
known-third-party = ["mypy", "pytest"]
extra-standard-library = ["typing_extensions"]
no-lines-before = ["future", "standard-library"]
force-sort-within-sections = true
split-on-trailing-comma = false
classes = ["MDEF"]

[build-system]
requires = ["poetry-core"]
Expand Down
30 changes: 25 additions & 5 deletions type-enum-plugin/type_enum_plugin/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
ProperType,
TupleType,
Type,
TypeAliasType,
TypeOfAny,
TypeType,
TypeVarLikeType,
Expand All @@ -44,8 +43,8 @@
@dataclass(kw_only=True)
class TypeEnumTransform:
cls: ClassDef
# Statement must also be accepted since class definition itself may be passed as the reason
# for subclass/metaclass-based uses of `typing.dataclass_transform`
# Statement must also be accepted since class definition itself may be passed as the
# reason for subclass/metaclass-based uses of `typing.dataclass_transform`
reason: Expression | Statement
# spec: DataclassTransformSpec
api: SemanticAnalyzerPluginInterface
Expand Down Expand Up @@ -113,7 +112,7 @@ def transform(self) -> None:
if stmt.new_syntax:
if not isinstance(stmt.rvalue, TempNode):
self.api.fail(
f"No type annotations allowed in the assignment style", stmt
"No type annotations allowed in the assignment style", stmt
)
error_reported = True
continue
Expand Down Expand Up @@ -170,7 +169,7 @@ def transform(self) -> None:
if aborted:
continue
info = self.create_namedtuple(
lhs.name, [f"_{i}" for i in range(len(types))], types, stmt.line
lhs.name, [f"field{i}" for i in range(len(types))], types, stmt.line
)
if tvars:
info.type_vars = []
Expand Down Expand Up @@ -295,4 +294,25 @@ def type_enum_callback(ctx: ClassDefContext) -> None:

def plugin(version: str) -> type[TypeEnumPlugin]:
# ignore version argument if the plugin works with all mypy versions.
parsed = parse_mypy_version(version)
if parsed < (1, 5):
raise RuntimeError("type-enum-plugin requires mypy >= 1.5.0")
return TypeEnumPlugin


def parse_mypy_version(version: str) -> tuple[int, ...]:
"""Parse mypy string version to tuple of ints.
This function is included here rather than the mypy plugin file because the mypy
plugin file cannot be imported outside a mypy run.
It parses normal version like `0.930` and dev version
like `0.940+dev.04cac4b5d911c4f9529e6ce86a27b44f28846f5d.dirty`.
Args:
version: The mypy version string.
Returns:
A tuple of ints. e.g. (0, 930).
"""
return tuple(map(int, version.partition("+")[0].split(".")))
Loading

0 comments on commit 21a20d1

Please sign in to comment.