Skip to content

Commit

Permalink
chore(ruff): use ruff instead isort, black and pyupgrade (#78)
Browse files Browse the repository at this point in the history
* chore(ruff): update doc
* chore(ruff): add ruff formater, removing isort, pyupgrade and black
* chore(ruff): parametrizing ruff config
  • Loading branch information
acostapazo authored Sep 11, 2024
1 parent 442844e commit 630c787
Show file tree
Hide file tree
Showing 26 changed files with 139 additions and 223 deletions.
44 changes: 17 additions & 27 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,47 +1,37 @@
default_language_version:
python: python3.10
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.6.0
hooks:
- id: check-added-large-files
- id: check-toml
- id: trailing-whitespace
- id: check-json
- id: check-yaml
args:
- --unsafe
- id: check-toml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-added-large-files
- repo: local
hooks:

- id: ruff
name: ruff
entry: ruff check meiga tests --fix
- id: commitizen
name: My commitizen check
entry: cz
args: ['check', '--commit-msg-file', '.git/COMMIT_EDITMSG']
pass_filenames: false
language: system
types: [ python ]
stages: [commit-msg]
require_serial: true
fail_fast: true

- id: isort
name: isort
entry: isort meiga tests
- id: ruff
name: ruff
entry: ruff check --fix meiga tests
language: system
types: [ python ]
require_serial: true
fail_fast: true

- id: black
name: black
entry: black meiga tests
- id: ruff-format
name: ruff-format
entry: ruff format meiga tests
language: system
types: [ python ]
require_serial: true
fail_fast: true

- id: pyupgrade
name: Pyupgrade
entry: pyupgrade --py37-plus
types: [ python ]
language: system
exclude: ^docs/.*$
fail_fast: true
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# meiga 🧙
# meiga 🧙

[![version](https://img.shields.io/github/release/alice-biometrics/meiga/all.svg)](https://github.com/alice-biometrics/meiga/releases)
[![ci](https://github.com/alice-biometrics/meiga/workflows/ci/badge.svg)](https://github.com/alice-biometrics/meiga/actions)
[![pypi](https://img.shields.io/pypi/dm/meiga)](https://pypi.org/project/meiga/)
[![version](https://img.shields.io/github/release/alice-biometrics/meiga/all.svg)](https://github.com/alice-biometrics/meiga/releases)
[![ci](https://github.com/alice-biometrics/meiga/workflows/ci/badge.svg)](https://github.com/alice-biometrics/meiga/actions)
[![pypi](https://img.shields.io/pypi/dm/meiga)](https://pypi.org/project/meiga/)
[![codecov](https://codecov.io/gh/alice-biometrics/meiga/branch/main/graph/badge.svg?token=BX1IZJZLJQ)](https://codecov.io/gh/alice-biometrics/meiga)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![license](https://img.shields.io/github/license/alice-biometrics/meiga.svg)](https://github.com/alice-biometrics/meiga/blob/main/LICENSE)
[![versions](https://img.shields.io/pypi/pyversions/meiga.svg)](https://github.com/alice-biometrics/meiga)

Expand All @@ -25,15 +24,15 @@

## How could meiga 🧙 help me?

`meiga 🧙` provides a simple and clear way of handling errors in Python without using `Exceptions`. This package improves the Dev Experience as it allows to know all possible typed responses. With Meiga 🧙 your IDE will help you much more.
`meiga 🧙` provides a simple and clear way of handling errors in Python without using `Exceptions`. This package improves the Dev Experience as it allows to know all possible typed responses. With Meiga 🧙 your IDE will help you much more.

## Installation 💻

```console
pip install meiga
```

## Contribute
## Contribute

We'd love you to contribute to *meiga* 🥳🥳🥳🥳🥳🥳️️!

Expand Down
11 changes: 5 additions & 6 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# meiga 🧙

[![version](https://img.shields.io/github/release/alice-biometrics/meiga/all.svg)](https://github.com/alice-biometrics/meiga/releases)
[![ci](https://github.com/alice-biometrics/meiga/workflows/ci/badge.svg)](https://github.com/alice-biometrics/meiga/actions)
[![pypi](https://img.shields.io/pypi/dm/meiga)](https://pypi.org/project/meiga/)
[![version](https://img.shields.io/github/release/alice-biometrics/meiga/all.svg)](https://github.com/alice-biometrics/meiga/releases)
[![ci](https://github.com/alice-biometrics/meiga/workflows/ci/badge.svg)](https://github.com/alice-biometrics/meiga/actions)
[![pypi](https://img.shields.io/pypi/dm/meiga)](https://pypi.org/project/meiga/)
[![codecov](https://codecov.io/gh/alice-biometrics/meiga/branch/main/graph/badge.svg?token=BX1IZJZLJQ)](https://codecov.io/gh/alice-biometrics/meiga)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![license](https://img.shields.io/github/license/alice-biometrics/meiga.svg)](https://github.com/alice-biometrics/meiga/blob/main/LICENSE)
[![versions](https://img.shields.io/pypi/pyversions/meiga.svg)](https://github.com/alice-biometrics/meiga)

Expand All @@ -18,7 +17,7 @@

## How could meiga help me?

`meiga` provides a simple and clear way of handling errors in Python without using `Exceptions`. This package improves the Dev Experience as it allows to know all possible typed responses. With meiga your IDE will help you much more.
`meiga` provides a simple and clear way of handling errors in Python without using `Exceptions`. This package improves the Dev Experience as it allows to know all possible typed responses. With meiga your IDE will help you much more.

## Content

Expand Down
6 changes: 2 additions & 4 deletions lume.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ steps:
- find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
lint:
run:
- ruff check $PACKAGE_NAME tests
- black $PACKAGE_NAME tests --check
- isort $PACKAGE_NAME tests --check-only
- pyupgrade --py37-plus `find $PACKAGE_NAME tests -name "*.py" -type f ! -name "*test_result_match.py"`
- ruff check --fix $PACKAGE_NAME tests
- ruff format $PACKAGE_NAME tests
check-requirements:
run: pip-audit
static-analysis:
Expand Down
10 changes: 3 additions & 7 deletions meiga/assertions/assert_failure.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,16 @@ def assert_failure(
value_is_instance_of: Union[Type[Any], None] = None,
value_is_equal_to: Union[Any, None] = None,
) -> None:
assert (
result.is_failure
), f"result is not failure as expected. Given failure value is {result.value}"
assert result.is_failure, f"result is not failure as expected. Given failure value is {result.value}"
if value_is_instance_of:
base = type(result.value)
if isinstance(base, type) and base is type:
base = result.value.__bases__

assert isinstance(result.value, value_is_instance_of), (
f"Value is not instance of {value_is_instance_of}. "
f"Given value is {result.value} of {base}"
f"Value is not instance of {value_is_instance_of}. " f"Given value is {result.value} of {base}"
)
if value_is_equal_to:
assert result.value == value_is_equal_to, (
f"Value is not equal to {value_is_equal_to}. "
f"Given value is {result.value}"
f"Value is not equal to {value_is_equal_to}. " f"Given value is {result.value}"
)
7 changes: 2 additions & 5 deletions meiga/assertions/assert_success.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@ def assert_success(
value_is_instance_of: Union[Type[Any], None] = None,
value_is_equal_to: Union[Any, None] = None,
) -> None:
assert (
result.is_success
), f"result is not success as expected. Given failure value is {result.value}"
assert result.is_success, f"result is not success as expected. Given failure value is {result.value}"
if value_is_instance_of:
assert isinstance(result.value, value_is_instance_of), (
f"Value is not instance of {value_is_instance_of}. "
f"Given value is {result.value} of {type({result.value})}"
)
if value_is_equal_to:
assert result.value == value_is_equal_to, (
f"Value is not equal to {value_is_equal_to}. "
f"Given value is {result.value}"
f"Value is not equal to {value_is_equal_to}. " f"Given value is {result.value}"
)
2 changes: 1 addition & 1 deletion meiga/decorators/async_early_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


def async_early_return(
func: Callable[..., Coroutine[Any, Any, R]]
func: Callable[..., Coroutine[Any, Any, R]],
) -> Callable[..., Coroutine[Any, Any, R]]:
@wraps(func)
async def _async_early_return(*args: P.args, **kwargs: P.kwargs) -> R:
Expand Down
4 changes: 1 addition & 3 deletions meiga/decorators/unexpected_decoration_order_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@

class UnexpectedDecorationOrderError(Error):
def __init__(self) -> None:
self.message = (
"meiga decorators must be declared after a @staticmethod, @classmethod"
)
self.message = "meiga decorators must be declared after a @staticmethod, @classmethod"
10 changes: 3 additions & 7 deletions meiga/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@


class Handler:
def __init__(
self, func: Callable[..., None], args: Iterable[Any] | None = None
) -> None:
def __init__(self, func: Callable[..., None], args: Iterable[Any] | None = None) -> None:
self.func = func
self.args = args

Expand All @@ -29,9 +27,7 @@ def execute(self, result: Result[TS, TF]) -> None:
self.func(result.value)


class OnSuccessHandler(Handler):
...
class OnSuccessHandler(Handler): ...


class OnFailureHandler(Handler):
...
class OnFailureHandler(Handler): ...
18 changes: 4 additions & 14 deletions meiga/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ def __repr__(self) -> str:

def __eq__(self, other: Any) -> bool:
if isinstance(other, Result):
return (
self._value_success == other._value_success
and self.value == other.value
)
return self._value_success == other._value_success and self.value == other.value
return False

def __ne__(self, other: Any) -> bool:
Expand All @@ -73,10 +70,7 @@ def _assert_values(self) -> None:
"Result is a monad, it must be a success or a failure. "
"Please model your result selecting only one type [success or failure]."
)
elif (
self._value_success is not NoGivenValue
and self._value_failure is not NoGivenValue
):
elif self._value_success is not NoGivenValue and self._value_failure is not NoGivenValue:
raise TypeError(
"Result is a monad, it cannot be success and failure at the same time. "
"Please model your result selecting only one type [success or failure]."
Expand Down Expand Up @@ -141,9 +135,7 @@ def unwrap_or_return(self, return_value_on_failure: Any = None) -> TS:
Returns the encapsulated value if this instance is a success or return Result as long as @early_return decorator wraps the function.
"""
if not self._is_success:
return_value = (
self if return_value_on_failure is None else return_value_on_failure
)
return_value = self if return_value_on_failure is None else return_value_on_failure
raise WaitingForEarlyReturn(return_value)
return cast(TS, self.value)

Expand Down Expand Up @@ -206,9 +198,7 @@ def handle(
self,
on_success_handler: OnSuccessHandler | None = None,
on_failure_handler: OnFailureHandler | None = None,
**kwargs: dict[
Any, Any
], # Deprecated parameter [on_success, on_failure, success_args, failure_args]
**kwargs: dict[Any, Any], # Deprecated parameter [on_success, on_failure, success_args, failure_args]
) -> Result[TS, TF]:
"""
Returns itself and execute the `on_success_handler` when the instance is a success and the `on_failure_handler` when it is failure.
Expand Down
49 changes: 46 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ dependencies = [
]
[project.optional-dependencies]
dev = [
"black==23.1",
"hypothesis<7.0.0,>=6.56.3",
"isort[colors]<6.0.0,>=5.10.1",
"mypy>=1.0.0",
"pip-audit<3.0.0,>=2.4.14",
"pre-commit<3.0.0,>=2.20",
Expand All @@ -63,7 +61,6 @@ dev = [
"pytest-mock<4.0.0,>=3.10",
"pytest-variables[yaml]<3.0.0,>=2",
"pytest-asyncio>=0.20.1,<1",
"pyupgrade>=3.2",
"ruff>=0.0.239",
]
doc = [
Expand Down Expand Up @@ -119,6 +116,9 @@ norecursedirs = [
]

[tool.ruff]
target-version = "py38" # keeping our older version supported
line-length = 120
indent-width = 4
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
Expand All @@ -133,6 +133,49 @@ ignore = [
"C901", # too complex
]

fixable = ["ALL"]
unfixable = []

dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
# Exclude a variety of commonly ignored directories.
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
".pyenv",
".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
".vscode",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
"tests/unit/test_result_match.py"
]

[tool.ruff.per-file-ignores]
"meiga/__init__.py" = ["F403"]
"tests/unit/test_result_match.py" = ["E999"]



[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
10 changes: 3 additions & 7 deletions tests/unit/doc/example_with_meiga.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,13 @@
from meiga import Error, Failure, Result, Success


class NoSuchKey(Error):
...
class NoSuchKey(Error): ...


class TypeMismatch(Error):
...
class TypeMismatch(Error): ...


def string_from_key(
dictionary: dict, key: str
) -> Result[str, NoSuchKey | TypeMismatch]:
def string_from_key(dictionary: dict, key: str) -> Result[str, NoSuchKey | TypeMismatch]:
if key not in dictionary.keys():
return Failure(NoSuchKey())

Expand Down
6 changes: 2 additions & 4 deletions tests/unit/doc/example_without_meiga.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
class NoSuchKey(Exception):
...
class NoSuchKey(Exception): ...


class TypeMismatch(Exception):
...
class TypeMismatch(Exception): ...


# This return value masks the behavior of the unhappy path (Exceptions). 🥲
Expand Down
10 changes: 2 additions & 8 deletions tests/unit/legacy/test_meiga_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,7 @@ def decorated_method() -> BoolResult:

result = MyClass.decorated_method()
assert_failure(result, value_is_instance_of=UnexpectedDecorationOrderError)
assert (
result.value.message
== "meiga decorators must be declared after a @staticmethod, @classmethod"
)
assert result.value.message == "meiga decorators must be declared after a @staticmethod, @classmethod"


@pytest.mark.unit
Expand All @@ -109,7 +106,4 @@ def decorated_method(cls) -> BoolResult:

result = MyClass.decorated_method()
assert_failure(result, value_is_instance_of=UnexpectedDecorationOrderError)
assert (
result.value.message
== "meiga decorators must be declared after a @staticmethod, @classmethod"
)
assert result.value.message == "meiga decorators must be declared after a @staticmethod, @classmethod"
Loading

0 comments on commit 630c787

Please sign in to comment.