Add isort, check-toml, and check-yaml to pre-commit
Signed-off-by: Dan Yeaw <dan@yeaw.me>
This commit is contained in:
parent
5d6970ae16
commit
34f7a524bc
10
.flake8
Normal file
10
.flake8
Normal file
@ -0,0 +1,10 @@
|
||||
[flake8]
|
||||
# E501 (Line too long) is handled by Black (reformatting)
|
||||
# W503 (Line break occurred before a binary operator) conflicts with Black formatting
|
||||
# E203 (whitespace before ':') is not PEP8 compliant
|
||||
ignore = E501, W503, E203
|
||||
max-line-length = 88
|
||||
max-complexity = 18
|
||||
select = B,C,E,F,W,T4,B9
|
||||
exclude = .venv, dist, __init__.py
|
||||
show-source = True
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -8,3 +8,9 @@ __pycache__
|
||||
cc-test-reporter
|
||||
htmlcov/
|
||||
.python-version
|
||||
|
||||
# Virtualenv
|
||||
.venv
|
||||
|
||||
# Tox
|
||||
.tox
|
||||
|
@ -1,11 +1,24 @@
|
||||
repos:
|
||||
- repo: https://github.com/ambv/black
|
||||
rev: 19.10b0
|
||||
rev: 20.8b1
|
||||
hooks:
|
||||
- id: black
|
||||
language_version: python3
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.740
|
||||
rev: v0.770
|
||||
hooks:
|
||||
- id: mypy
|
||||
args: [ --show-error-codes ]
|
||||
# - repo: https://gitlab.com/pycqa/flake8
|
||||
# rev: 3.8.3
|
||||
# hooks:
|
||||
# - id: flake8
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
- repo: https://github.com/pre-commit/mirrors-isort
|
||||
rev: v5.4.2
|
||||
hooks:
|
||||
- id: isort
|
||||
additional_dependencies: [toml]
|
||||
|
@ -11,7 +11,8 @@
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
project_dir = Path(__file__).resolve().parent.parent
|
||||
|
@ -16,7 +16,6 @@ from typing import Callable, Set, Type
|
||||
|
||||
from generic.registry import Registry, TypeAxis
|
||||
|
||||
|
||||
__all__ = "Manager"
|
||||
|
||||
Event = object
|
||||
@ -25,7 +24,7 @@ HandlerSet = Set[Handler]
|
||||
|
||||
|
||||
class Manager:
|
||||
""" Event manager
|
||||
"""Event manager
|
||||
|
||||
Provides API for subscribing for and firing events. There's also global
|
||||
event manager instantiated at module level with functions
|
||||
@ -53,7 +52,7 @@ class Manager:
|
||||
handler_set.remove(handler)
|
||||
|
||||
def handle(self, event: Event) -> None:
|
||||
""" Fire ``event``
|
||||
"""Fire ``event``
|
||||
|
||||
All subscribers will be executed with no determined order.
|
||||
"""
|
||||
@ -64,14 +63,13 @@ class Manager:
|
||||
handler(event)
|
||||
|
||||
def _register_handler_set(self, event_type: Type[Event]) -> HandlerSet:
|
||||
""" Register new handler set for ``event_type``.
|
||||
"""
|
||||
"""Register new handler set for ``event_type``."""
|
||||
handler_set: HandlerSet = set()
|
||||
self.registry.register(handler_set, event_type)
|
||||
return handler_set
|
||||
|
||||
def subscriber(self, event_type: Type[Event]) -> Callable[[Handler], Handler]:
|
||||
""" Decorator for subscribing handlers
|
||||
"""Decorator for subscribing handlers
|
||||
|
||||
Works like this:
|
||||
|
||||
|
@ -11,10 +11,9 @@ Note that this module does not support annotated functions.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import cast, Any, Callable, Generic, TypeVar, Union
|
||||
|
||||
import functools
|
||||
import inspect
|
||||
from typing import Any, Callable, Generic, TypeVar, Union, cast
|
||||
|
||||
from generic.registry import Registry, TypeAxis
|
||||
|
||||
@ -25,7 +24,7 @@ KeyType = Union[type, None]
|
||||
|
||||
|
||||
def multidispatch(*argtypes: KeyType) -> Callable[[T], FunctionDispatcher[T]]:
|
||||
""" Declare function as multidispatch
|
||||
"""Declare function as multidispatch
|
||||
|
||||
This decorator takes ``argtypes`` argument types and replace decorated
|
||||
function with :class:`.FunctionDispatcher` object, which is responsible for
|
||||
@ -53,7 +52,7 @@ def multidispatch(*argtypes: KeyType) -> Callable[[T], FunctionDispatcher[T]]:
|
||||
|
||||
|
||||
class FunctionDispatcher(Generic[T]):
|
||||
""" Multidispatcher for functions
|
||||
"""Multidispatcher for functions
|
||||
|
||||
This object dispatch calls to function by its argument types. Usually it is
|
||||
produced by :func:`.multidispatch` decorator.
|
||||
@ -64,7 +63,7 @@ class FunctionDispatcher(Generic[T]):
|
||||
registry: Registry[T]
|
||||
|
||||
def __init__(self, argspec: inspect.FullArgSpec, params_arity: int) -> None:
|
||||
""" Initialize dispatcher with ``argspec`` of type
|
||||
"""Initialize dispatcher with ``argspec`` of type
|
||||
:class:`inspect.ArgSpec` and ``params_arity`` that represent number
|
||||
params."""
|
||||
# Check if we have enough positional arguments for number of type params
|
||||
@ -81,7 +80,7 @@ class FunctionDispatcher(Generic[T]):
|
||||
self.registry = Registry(*axis)
|
||||
|
||||
def check_rule(self, rule: T, *argtypes: KeyType) -> None:
|
||||
""" Check if the argument types match wrt number of arguments.
|
||||
"""Check if the argument types match wrt number of arguments.
|
||||
|
||||
Raise TypeError in case of failure.
|
||||
"""
|
||||
@ -106,7 +105,7 @@ class FunctionDispatcher(Generic[T]):
|
||||
self.registry.register(rule, *argtypes)
|
||||
|
||||
def register(self, *argtypes: KeyType) -> Callable[[T], T]:
|
||||
""" Decorator for registering new case for multidispatch
|
||||
"""Decorator for registering new case for multidispatch
|
||||
|
||||
New case will be registered for types identified by ``argtypes``. The
|
||||
length of ``argtypes`` should be equal to the length of ``argtypes``
|
||||
|
@ -5,15 +5,13 @@ to provide generic methods.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import cast, Any, Callable, Type, TypeVar, Union
|
||||
|
||||
import inspect
|
||||
import functools
|
||||
import inspect
|
||||
import threading
|
||||
import types
|
||||
from typing import Any, Callable, Type, TypeVar, Union, cast
|
||||
|
||||
from generic.multidispatch import FunctionDispatcher, _arity, KeyType
|
||||
|
||||
from generic.multidispatch import FunctionDispatcher, KeyType, _arity
|
||||
|
||||
__all__ = ("multimethod", "has_multimethods")
|
||||
|
||||
@ -22,8 +20,8 @@ T = TypeVar("T", bound=Union[Callable[..., Any], type])
|
||||
|
||||
|
||||
def multimethod(*argtypes: KeyType) -> Callable[[T], MethodDispatcher[T]]:
|
||||
""" Declare method as multimethod
|
||||
|
||||
"""Declare method as multimethod
|
||||
|
||||
This decorator works exactly the same as :func:`.multidispatch` decorator
|
||||
but replaces decorated method with :class:`.MethodDispatcher` object
|
||||
instead.
|
||||
@ -49,7 +47,7 @@ def multimethod(*argtypes: KeyType) -> Callable[[T], MethodDispatcher[T]]:
|
||||
|
||||
|
||||
def has_multimethods(cls: Type[C]) -> Type[C]:
|
||||
""" Declare class as one that have multimethods
|
||||
"""Declare class as one that have multimethods
|
||||
|
||||
Should only be used for decorating classes which have methods decorated with
|
||||
:func:`.multimethod` decorator.
|
||||
@ -61,11 +59,11 @@ def has_multimethods(cls: Type[C]) -> Type[C]:
|
||||
|
||||
|
||||
class MethodDispatcher(FunctionDispatcher[T]):
|
||||
""" Multiple dispatch for methods
|
||||
"""Multiple dispatch for methods
|
||||
|
||||
This object dispatch call to method by its class and arguments types.
|
||||
Usually it is produced by :func:`.multimethod` decorator.
|
||||
|
||||
|
||||
You should not manually create objects of this type.
|
||||
"""
|
||||
|
||||
@ -77,7 +75,7 @@ class MethodDispatcher(FunctionDispatcher[T]):
|
||||
self.local.unbound_rules = []
|
||||
|
||||
def register_unbound_rule(self, func, *argtypes) -> None:
|
||||
""" Register unbound rule that should be processed by
|
||||
"""Register unbound rule that should be processed by
|
||||
``proceed_unbound_rules`` later."""
|
||||
self.local.unbound_rules.append((argtypes, func))
|
||||
|
||||
|
@ -7,15 +7,13 @@ This implementation was borrowed from happy[1] project by Chris Rossi.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ("Registry", "SimpleAxis", "TypeAxis")
|
||||
|
||||
from typing import (
|
||||
Any,
|
||||
Dict,
|
||||
Generator,
|
||||
Generic,
|
||||
KeysView,
|
||||
List,
|
||||
Generator,
|
||||
Optional,
|
||||
Sequence,
|
||||
Tuple,
|
||||
@ -23,6 +21,8 @@ from typing import (
|
||||
Union,
|
||||
)
|
||||
|
||||
__all__ = ("Registry", "SimpleAxis", "TypeAxis")
|
||||
|
||||
K = TypeVar("K")
|
||||
S = TypeVar("S")
|
||||
T = TypeVar("T")
|
||||
@ -70,9 +70,9 @@ class Registry(Generic[T]):
|
||||
def _query(
|
||||
self, tree_node: _TreeNode[T], objs: Sequence[Optional[V]], axes: Sequence[Axis]
|
||||
) -> Generator[Optional[T], None, None]:
|
||||
""" Recursively traverse registration tree, from left to right, most
|
||||
"""Recursively traverse registration tree, from left to right, most
|
||||
specific to least specific, returning the first target found on a
|
||||
matching node. """
|
||||
matching node."""
|
||||
if not objs:
|
||||
yield tree_node.target
|
||||
else:
|
||||
@ -92,9 +92,9 @@ class Registry(Generic[T]):
|
||||
def _align_with_axes(
|
||||
self, args: Sequence[S], kw: Dict[str, S]
|
||||
) -> Sequence[Optional[S]]:
|
||||
""" Create a list matching up all args and kwargs with their
|
||||
"""Create a list matching up all args and kwargs with their
|
||||
corresponding axes, in order, using ``None`` as a placeholder for
|
||||
skipped axes. """
|
||||
skipped axes."""
|
||||
axes_dict = self._axes_dict
|
||||
aligned: List[Optional[S]] = [None for i in range(len(axes_dict))]
|
||||
|
||||
@ -133,7 +133,7 @@ class _TreeNode(Generic[T], Dict[Any, Any]):
|
||||
|
||||
|
||||
class SimpleAxis:
|
||||
""" A simple axis where the key into the axis is the same as the object to
|
||||
"""A simple axis where the key into the axis is the same as the object to
|
||||
be matched (aka the identity axis). This axis behaves just like a
|
||||
dictionary. You might use this axis if you are interested in registering
|
||||
something by name, where you're registering an object with the string that
|
||||
@ -152,7 +152,7 @@ class SimpleAxis:
|
||||
|
||||
|
||||
class TypeAxis:
|
||||
""" An axis which matches the class and super classes of an object in
|
||||
"""An axis which matches the class and super classes of an object in
|
||||
method resolution order.
|
||||
"""
|
||||
|
||||
|
@ -59,3 +59,12 @@ commands =
|
||||
poetry install -v
|
||||
xvfb-run -a pytest
|
||||
"""
|
||||
|
||||
[tool.isort]
|
||||
multi_line_output = 3
|
||||
include_trailing_comma = true
|
||||
force_grid_wrap = 0
|
||||
use_parentheses = true
|
||||
line_length = 88
|
||||
known_third_party = ["pytest"]
|
||||
skip = ".venv,build,dist"
|
||||
|
@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Callable, List
|
||||
|
||||
from generic.event import Manager
|
||||
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
""" Tests for :module:`generic.multidispatch`."""
|
||||
|
||||
from inspect import FullArgSpec
|
||||
|
||||
import pytest
|
||||
|
||||
from inspect import FullArgSpec
|
||||
from generic.multidispatch import multidispatch, FunctionDispatcher
|
||||
from generic.multidispatch import FunctionDispatcher, multidispatch
|
||||
|
||||
|
||||
def create_dispatcher(
|
||||
|
@ -1,8 +1,9 @@
|
||||
""" Tests for :module:`generic.registry`."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
import pytest
|
||||
|
||||
from typing import Union
|
||||
from generic.registry import Registry, SimpleAxis, TypeAxis
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user