Skip to content

Commit

Permalink
Merge branch 'release/0.3.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenham committed Apr 1, 2024
2 parents f7b418a + a25ad27 commit add8a2d
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 235 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ jobs:
- name: ruff check
run: poetry run ruff check --output-format=github .

- name: pyright
run: poetry run pyright
- name: basedpyright
run: poetry run basedpyright

test:
timeout-minutes: 5
Expand Down
9 changes: 2 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ build/
dist/
site/

# Unit test
.cache
.pyright/
# Cache
.pytest_cache/
.ruff_cache/

Expand All @@ -21,7 +19,4 @@ venv/

# IntelliJ
.idea/
.run

# VSCode settings
.vscode/settings.json
.run/
22 changes: 11 additions & 11 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@ repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-yaml
- id: check-toml
- id: check-yaml
- id: check-toml

- repo: https://github.com/python-poetry/poetry
rev: 1.8.2
hooks:
- id: poetry-check
- id: poetry-check

- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
- id: codespell
- id: codespell

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.4
rev: v0.3.5
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.355
- repo: https://github.com/DetachHead/basedpyright
rev: b1ebff9e96a087851fc24efe1674660cfea59140
hooks:
- id: pyright
- id: basedpyright

- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.39.0
hooks:
- id: markdownlint
- id: markdownlint
14 changes: 14 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"recommendations": [
"charliermarsh.ruff",
"codezombiech.gitignore",
"davidanson.vscode-markdownlint",
"detachhead.basedpyright",
"editorconfig.editorconfig",
"elagil.pre-commit-helper",
"ms-python.python",
"serhioromano.vscode-gitflow",
"zeshuaro.vscode-python-poetry"
],
"unwantedRecommendations": ["ms-python.vscode-pylance"]
}
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"git.branchProtection": ["master"],
"githubPullRequests.overrideDefaultBranch": "dev",
"python.languageServer": "None"
}
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,47 @@ pip install optype

[OPTYPE]: https://pypi.org/project/optype/

## Example

Let's say you're writing a `twice(x)` function, that evaluates `2 * x`.
Implementing it is trivial, but what about the type annotations?

Because `twice(2) == 4`, `twice(3.14) == 6.28` and `twice('I') = 'II'`, it
might seem like a good idea to type it as `twice[T](x: T) -> T: ...`.
However, that wouldn't include cases such as `twice(True) == 2` or
`twice((42, True)) == (42, True, 42, True)`, where the input- and output types
differ.
Moreover, `twice` should accept *any* type with a custom `__rmul__` method
that accepts `2` as argument.

This is where `optype` comes in handy, which has single-method protocols for
*all* the builtin special methods.
For `twice`, we can use `optype.CanRMul[X, Y]`, which, as the name suggests,
is a protocol with (only) the `def __rmul__(self, x: X) -> Y: ...` method.
With this, the `twice` function can written as:

```python
import typing
import optype

type Two = typing.Literal[2]

def twice[Y](x: optype.CanRMul[Two, Y], /) -> Y:
return 2 * x
```

But what about types that implement `__add__` but not `__radd__`?
In this case, we could return `x * 2` as fallback.
Because the `optype.Can*` protocols are runtime-checkable, the revised
`twice2` function can be compactly written as:

```python
def twice2[Y](x: optype.CanRMul[Two, Y] | optype.CanMul[Two, Y], /) -> Y:
return 2 * x if isinstance(x, optype.CanRMul) else x * 2
```

See [`examples/twice.py`](examples/twice.py) for the full example.

## Overview

The API of `optype` is flat; a single `import optype` is all you need.
Expand Down
Loading

0 comments on commit add8a2d

Please sign in to comment.