Skip to content

Commit

Permalink
fix: officially support Python 3.6 (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcous authored Jul 12, 2021
1 parent 6b87835 commit 2412e62
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 31 deletions.
22 changes: 16 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ env:
jobs:
test:
name: "Test Python ${{ matrix.python-version }} on ${{ matrix.os }}"
runs-on: ${{ matrix.os }}
runs-on: ${{ matrix.os }}-latest
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.7", "3.8", "3.9"]
os: [Ubuntu, Windows, macOS]
python-version: ["3.6", "3.7", "3.8", "3.9"]
steps:
- name: "Check out repository"
uses: actions/checkout@v2
Expand All @@ -26,14 +26,18 @@ jobs:

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

- name: "Install dependencies"
run: pip install poetry && poetry install
run: poetry install

- name: "Run tests"
run: poetry run pytest
Expand All @@ -58,8 +62,11 @@ jobs:
${{ env.PIP_CACHE_DIR }}
${{ env.POETRY_CACHE_DIR }}
- name: "Install poetry"
run: pip install poetry

- name: "Install dependencies"
run: pip install poetry && poetry install
run: poetry install

- name: "Check formatting"
run: poetry run black --check .
Expand Down Expand Up @@ -91,8 +98,11 @@ jobs:
${{ env.PIP_CACHE_DIR }}
${{ env.POETRY_CACHE_DIR }}
- name: "Install poetry"
run: pip install poetry

- name: "Install dependencies"
run: pip install poetry && poetry install
run: poetry install

- name: "Build artifacts"
run: |
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Development Setup

This project uses [poetry][] to manage dependencies and builds, and you will need to install it before working on Decoy.
This project uses [Poetry][] to manage dependencies and builds, and you will need to install it before working on Decoy.

Once poetry is installed, you should be good to set up a virtual environment and install development dependencies. While Decoy is supported on Python >= 3.7, Python >= 3.8 is recommended for development.
Once Poetry is installed, you should be good to set up a virtual environment and install development dependencies. While Decoy supports Python >= 3.6, Python >= 3.8 is recommended for development.

```bash
git clone https://github.com/mcous/decoy.git
Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
<img src="https://mike.cousins.io/decoy/img/decoy.png" width="256px">
<p>Opinionated mocking library for Python</p>
<p>
<a href="https://github.com/mcous/decoy/actions">
<img title="CI Status" src="https://flat.badgen.net/github/checks/mcous/decoy/main">
<a title="CI Status" href="https://github.com/mcous/decoy/actions">
<img src="https://flat.badgen.net/github/checks/mcous/decoy/main">
</a>
<a href="https://pypi.org/project/decoy/">
<img title="PyPI Version" src="https://flat.badgen.net/pypi/v/decoy">
<a title="License" href="https://github.com/mcous/decoy/blob/main/LICENSE">
<img src="https://flat.badgen.net/github/license/mcous/decoy">
</a>
<a href="https://github.com/mcous/decoy/blob/main/LICENSE">
<img title="License" src="https://flat.badgen.net/github/license/mcous/decoy">
<a title="PyPI Version"href="https://pypi.org/project/decoy/">
<img src="https://flat.badgen.net/pypi/v/decoy">
</a>
<a title="Supported Python Versions" href="https://pypi.org/project/decoy/">
<img src="https://flat.badgen.net/pypi/python/decoy">
</a>
</p>
<p>
Expand Down
3 changes: 1 addition & 2 deletions decoy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Decoy stubbing and spying library."""
from __future__ import annotations
from typing import Any, Callable, Generic, Optional, cast, overload

from . import matchers, errors, warnings
Expand Down Expand Up @@ -88,7 +87,7 @@ def create_decoy_func(
spy = self._core.mock(spec=spec, is_async=is_async)
return cast(FuncT, spy)

def when(self, _rehearsal_result: ReturnT) -> Stub[ReturnT]:
def when(self, _rehearsal_result: ReturnT) -> "Stub[ReturnT]":
"""Create a [Stub][decoy.Stub] configuration using a rehearsal call.
See [stubbing usage guide](../usage/when) for more details.
Expand Down
3 changes: 1 addition & 2 deletions decoy/core.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Decoy implementation logic."""
from __future__ import annotations
from typing import Any, Callable, Optional

from .spy import SpyConfig, SpyFactory, create_spy as default_create_spy
Expand Down Expand Up @@ -44,7 +43,7 @@ def mock(self, *, spec: Optional[Any] = None, is_async: bool = False) -> Any:
)
return self._create_spy(config)

def when(self, _rehearsal: ReturnT) -> StubCore:
def when(self, _rehearsal: ReturnT) -> "StubCore":
"""Create a new stub from the last spy rehearsal."""
rehearsal = self._call_stack.consume_when_rehearsal()
return StubCore(rehearsal=rehearsal, stub_store=self._stub_store)
Expand Down
1 change: 0 additions & 1 deletion decoy/spy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
Classes in this module are heavily inspired by the
[unittest.mock library](https://docs.python.org/3/library/unittest.mock.html).
"""
from __future__ import annotations
from inspect import isclass, iscoroutinefunction, isfunction, signature
from functools import partial
from typing import get_type_hints, Any, Callable, Dict, NamedTuple, Optional
Expand Down
18 changes: 16 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]
name = "decoy"
version = "1.6.0"
description = "Opinionated, typed stubbing and verification library for Python"
description = "Opinionated mocking library for Python"
authors = ["Mike Cousins <[email protected]>"]
license = "MIT"
readme = "README.md"
Expand All @@ -18,8 +18,11 @@ classifiers = [
"Typing :: Typed",
]

[tool.poetry.urls]
"Changelog" = "https://github.com/mcous/decoy/releases"

[tool.poetry.dependencies]
python = "^3.7"
python = "^3.6.2"

[tool.poetry.dev-dependencies]
black = "^21.5b1"
Expand Down Expand Up @@ -48,5 +51,5 @@ strict = true
show_error_codes = true

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
requires = ["poetry_core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
2 changes: 1 addition & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async def do_the_thing(self, flag: bool) -> None:


# NOTE: these `Any`s are forward references for call signature testing purposes
def noop(*args: "Any", **kwargs: "Any") -> "Any":
def noop(*args: Any, **kwargs: Any) -> Any:
"""No-op."""
pass

Expand Down
6 changes: 2 additions & 4 deletions tests/test_matchers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
"""Matcher tests."""
import pytest
from collections import namedtuple
from dataclasses import dataclass
from decoy import matchers
from typing import Any, List
from typing import Any, List, NamedTuple
from .common import SomeClass


@dataclass
class _HelloClass:
class _HelloClass(NamedTuple):
hello: str = "world"

@property
Expand Down
17 changes: 16 additions & 1 deletion tests/test_spy.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,22 @@ def test_spy_matches_signature() -> None:
assert inspect.signature(func_spy) == inspect.signature(some_func)

spy = create_spy(SpyConfig(handle_call=noop))
assert inspect.signature(spy) == inspect.signature(noop)

assert inspect.signature(spy) == inspect.Signature(
parameters=(
inspect.Parameter(
name="args",
annotation=Any,
kind=inspect.Parameter.VAR_POSITIONAL,
),
inspect.Parameter(
name="kwargs",
annotation=Any,
kind=inspect.Parameter.VAR_KEYWORD,
),
),
return_annotation=Any,
)


def test_spy_repr() -> None:
Expand Down

0 comments on commit 2412e62

Please sign in to comment.