Skip to content

Commit

Permalink
Merge pull request #30 from last-partizan/22-stubtest
Browse files Browse the repository at this point in the history
feat: Use stubtest to verify stub correctness
  • Loading branch information
smarie authored Jul 6, 2022
2 parents ffa1e51 + af1e28c commit b39aeb2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 16 deletions.
21 changes: 20 additions & 1 deletion .github/workflows/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,27 @@ jobs:
name: reports_dir
path: ./docs/reports

run_stubtest:
runs-on: ubuntu-latest
defaults:
run:
shell: bash -l {0} # so that conda works
steps:
- uses: actions/checkout@v2

- name: Install conda v3.7
uses: conda-incubator/setup-miniconda@v2
with:
python-version: '3.10'
activate-environment: noxenv

- name: Install noxfile requirements
run: pip install -r noxfile-requirements.txt

- run: nox -s stubtest

publish_release:
needs: run_all_tests
needs: [run_stubtest, run_all_tests]
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
Expand Down
10 changes: 10 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ def tests(session: PowerSession, coverage, pkg_specs):
session.run2("genbadge coverage -i %s -o %s" % (Folders.coverage_xml, Folders.coverage_badge))


@power_session(python=PY310, logsdir=Folders.runlogs)
def stubtest(session: PowerSession):
"""Verify type stubs correctness."""

session.install_reqs(setup=True, install=True, tests=True)
session.run2("pip install -e . --no-deps")

session.run2("stubtest decopatch.main")


@power_session(python=PY38, logsdir=Folders.runlogs)
def flake8(session: PowerSession):
"""Launch flake8 qualimetry."""
Expand Down
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ install_requires =
tests_require =
pytest
pytest_cases
# syrupy and pyright is used for testing type correctness.
# syrupy, pyright and mypy is used for testing type correctness.
syrupy>2;python_version>'3.6'
pyright;python_version>'3.6'
mypy;python_version>'3.6'
# for some reason these pytest dependencies were not declared in old versions of pytest
six;python_version<'3.6'
attr;python_version<'3.6'
Expand Down
29 changes: 15 additions & 14 deletions src/decopatch/main.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,56 +10,57 @@ except ImportError:
from decopatch.utils_disambiguation import FirstArgDisambiguation
from decopatch.utils_modes import SignatureInfo

P = ParamSpec("P")
F = TypeVar("F", bound=Callable[..., Any])
_P = ParamSpec("_P")
_F = TypeVar("_F", bound=Callable[..., Any])
_CustomDisambugatorT = Optional[Callable[[Any], FirstArgDisambiguation]]

class _Decorator(Protocol[P]):
class _Decorator(Protocol[_P]):
"""
This is callable Protocol, to distinguish between cases where
created decorator is called as `@decorator` or `@decorator()`
"""

# decorator is called without parenthesis: @decorator
@overload
def __call__(self, func: F) -> F: ...
def __call__(self, func: _F) -> _F: ...
# decorator is called with options or parenthesis: @decorator(some_option=...)
@overload
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Callable[[F], F]: ...
def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> Callable[[_F], _F]: ...

# @function_decorator is called without options or parenthesis
@overload
def function_decorator(
enable_stack_introspection: Callable[P, Any],
custom_disambiguator: Callable[[Any], FirstArgDisambiguation] = ...,
enable_stack_introspection: Callable[_P, Any],
custom_disambiguator: _CustomDisambugatorT = ...,
flat_mode_decorated_name: Optional[str] = ...,
) -> _Decorator[P]: ...
) -> _Decorator[_P]: ...

# @function_decorator() is called with options or parenthesis.
@overload
def function_decorator(
enable_stack_introspection: bool = ...,
custom_disambiguator: Callable[[Any], FirstArgDisambiguation] = ...,
custom_disambiguator: _CustomDisambugatorT = ...,
flat_mode_decorated_name: Optional[str] = ...,
) -> Callable[[Callable[P, Any]], _Decorator[P]]: ...
) -> Callable[[Callable[_P, Any]], _Decorator[_P]]: ...
def class_decorator(
enable_stack_introspection: bool = ...,
custom_disambiguator: Callable[[Any], FirstArgDisambiguation] = ...,
custom_disambiguator: _CustomDisambugatorT = ...,
flat_mode_decorated_name: Optional[str] = ...,
): ...
def decorator(
is_function_decorator: bool = ...,
is_class_decorator: bool = ...,
enable_stack_introspection: bool = ...,
custom_disambiguator: Callable[[Any], FirstArgDisambiguation] = ...,
custom_disambiguator: _CustomDisambugatorT = ...,
use_signature_trick: bool = ...,
flat_mode_decorated_name: str = ...,
flat_mode_decorated_name: Optional[str] = ...,
): ...
def create_decorator(
impl_function,
is_function_decorator: bool = ...,
is_class_decorator: bool = ...,
enable_stack_introspection: bool = ...,
custom_disambiguator: Callable[[Any], FirstArgDisambiguation] = ...,
custom_disambiguator: _CustomDisambugatorT = ...,
use_signature_trick: bool = ...,
flat_mode_decorated_name: Optional[str] = ...,
): ...
Expand Down

0 comments on commit b39aeb2

Please sign in to comment.