Skip to content

Commit

Permalink
fix(spy): use classmethod __func__ source for async detection (#148)
Browse files Browse the repository at this point in the history
Closes #146
  • Loading branch information
mcous authored Dec 22, 2022
1 parent 799f511 commit 0dfc38c
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 28 deletions.
56 changes: 28 additions & 28 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
name: "Continuous integration"
name: 'Continuous integration'

on: [push, pull_request]

env:
PIP_CACHE_DIR: ${{ github.workspace }}/.cache/pip
POETRY_CACHE_DIR: ${{ github.workspace }}/.cache/pypoetry
DEFAULT_PYTHON: "3.8"
DEFAULT_PYTHON: '3.8'

jobs:
test:
name: "Test Python ${{ matrix.python-version }} on ${{ matrix.os }}"
name: 'Test Python ${{ matrix.python-version }} on ${{ matrix.os }}'
runs-on: ${{ matrix.os }}-latest
strategy:
matrix:
os: [Ubuntu, Windows, macOS]
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ['3.7', '3.8', '3.9', '3.10']
steps:
- name: "Check out repository"
- name: 'Check out repository'
uses: actions/checkout@v3

- name: "Set up Python"
- name: 'Set up Python'
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: "Set up dependency cache"
- name: 'Set up dependency cache'
uses: actions/cache@v3
# poetry venv restore is buggy on windows
# https://github.com/python-poetry/poetry/issues/2629
Expand All @@ -35,89 +35,89 @@ jobs:
${{ env.PIP_CACHE_DIR }}
${{ env.POETRY_CACHE_DIR }}
- name: "Install poetry"
- name: 'Install poetry'
run: pip install "poetry==1.1.11"

- name: "Install dependencies"
- name: 'Install dependencies'
run: poetry install

- name: "Run tests"
- name: 'Run tests'
run: poetry run coverage run --branch --source=decoy -m pytest --mypy-same-process

- name: "Generate coverage report"
- name: 'Generate coverage report'
run: poetry run coverage xml

- name: "Upload coverage report"
- name: 'Upload coverage report'
uses: codecov/codecov-action@v3

check:
name: "Lint and type checks"
name: 'Lint and type checks'
runs-on: ubuntu-latest
steps:
- name: "Check out repository"
- name: 'Check out repository'
uses: actions/checkout@v3

- name: "Set up Python"
- name: 'Set up Python'
uses: actions/setup-python@v4
with:
python-version: ${{ env.DEFAULT_PYTHON }}

- name: "Set up dependency cache"
- name: 'Set up dependency cache'
uses: actions/cache@v3
with:
key: deps-${{ secrets.GH_CACHE }}-${{ runner.os }}-python${{ env.DEFAULT_PYTHON }}-${{ hashFiles('**/*.lock') }}
path: |
${{ env.PIP_CACHE_DIR }}
${{ env.POETRY_CACHE_DIR }}
- name: "Install poetry"
- name: 'Install poetry'
run: pip install "poetry==1.1.11"

- name: "Install dependencies"
- name: 'Install dependencies'
run: poetry install

- name: "Check formatting"
- name: 'Check formatting'
run: poetry run black --check .

- name: "Check linter"
- name: 'Check linter'
run: poetry run flake8

- name: "Checks types"
- name: 'Checks types'
run: poetry run mypy

build:
name: Build assets and deploy on tags
runs-on: ubuntu-latest
needs: [test, check]
steps:
- name: "Check out repository"
- name: 'Check out repository'
uses: actions/checkout@v3

- name: "Set up Python"
- name: 'Set up Python'
uses: actions/setup-python@v4
with:
python-version: ${{ env.DEFAULT_PYTHON }}

- name: "Set up dependency cache"
- name: 'Set up dependency cache'
uses: actions/cache@v3
with:
key: deps-${{ secrets.GH_CACHE }}-${{ runner.os }}-python${{ env.DEFAULT_PYTHON }}-${{ hashFiles('**/*.lock') }}
path: |
${{ env.PIP_CACHE_DIR }}
${{ env.POETRY_CACHE_DIR }}
- name: "Install poetry"
- name: 'Install poetry'
run: pip install "poetry==1.1.11"

- name: "Install dependencies"
- name: 'Install dependencies'
run: poetry install

- name: "Build artifacts"
- name: 'Build artifacts'
run: |
poetry build
poetry run mkdocs build
- name: "Deploy to PyPI and GitHub Pages"
- name: 'Deploy to PyPI and GitHub Pages'
if: startsWith(github.ref, 'refs/tags/v')
env:
USER_NAME: ${{ github.actor }}
Expand Down
3 changes: 3 additions & 0 deletions decoy/spy_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ def create_child_core(self, name: str, is_async: bool) -> "SpyCore":
child_source = child_source.__func__

else:
if isinstance(child_source, classmethod):
child_source = child_source.__func__

child_source = inspect.unwrap(child_source)

if inspect.isfunction(child_source):
Expand Down
8 changes: 8 additions & 0 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ async def bar(self, a: int, b: float, c: str) -> bool:
async def do_the_thing(self, *, flag: bool) -> None:
"""Perform a side-effect without a return value."""

@classmethod
async def async_class_method(cls) -> int:
"""An async class method."""

@staticmethod
async def async_static_method() -> int:
"""An async static method."""


class SomeAsyncCallableClass:
"""Async callable class."""
Expand Down
12 changes: 12 additions & 0 deletions tests/test_spy_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,18 @@ class GetIsAsyncSpec(NamedTuple):
),
expected_is_async=True,
),
GetIsAsyncSpec(
subject=SpyCore(source=SomeAsyncClass, name=None).create_child_core(
"async_class_method", is_async=False
),
expected_is_async=True,
),
GetIsAsyncSpec(
subject=SpyCore(source=SomeAsyncClass, name=None).create_child_core(
"async_static_method", is_async=False
),
expected_is_async=True,
),
],
)
def test_get_is_async(subject: SpyCore, expected_is_async: bool) -> None:
Expand Down

0 comments on commit 0dfc38c

Please sign in to comment.