Skip to content

Commit

Permalink
Update mypy config (#1791)
Browse files Browse the repository at this point in the history
* Update mypy config

* Fix isort

* Fix isort

* Fix pytest_ignore_collect

* Fix CI

* Fix mypy

* Fix mypy

* No cache

* Fix docs

* Speed up builds

* Speed up builds
  • Loading branch information
sobolevn committed Mar 4, 2024
1 parent d88290b commit 638c614
Show file tree
Hide file tree
Showing 8 changed files with 845 additions and 974 deletions.
62 changes: 40 additions & 22 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@ concurrency:
cancel-in-progress: true

jobs:
build:
tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
task: ['tests', 'typesafety']
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v4
Expand All @@ -42,24 +41,14 @@ jobs:
# Adding `poetry` to `$PATH`:
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
- name: Set up cache
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}
restore-keys: |
venv-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}
venv-${{ matrix.python-version }}-
- name: Install dependencies
run: |
poetry config virtualenvs.in-project true
poetry install --extras=compatible-mypy
poetry install --all-extras
poetry run pip install -U pip
- name: Run tests
if: matrix.task == 'tests'
run: |
poetry run flake8 .
Expand All @@ -76,17 +65,46 @@ jobs:
poetry run poetry check
poetry run pip check
poetry run safety check --full-report
poetry run python -m slotscheck returns --verbose
- name: Run typesafety tests
if: matrix.task == 'typesafety'
run: |
# We do this to speed up the build:
poetry run pytest typesafety -p no:cov -o addopts="" --mypy-ini-file=setup.cfg
- name: Upload coverage to Codecov
if: "matrix.task == 'tests' && matrix.python-version == 3.11"
if: matrix.python-version == 3.11
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml

typesafety-tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
shard: [0, 1, 2, 3]

steps:
- uses: actions/checkout@v4

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

- name: Install poetry
run: |
curl -sSL "https://install.python-poetry.org" | python
# Adding `poetry` to `$PATH`:
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
poetry config virtualenvs.in-project true
poetry install --all-extras
poetry run pip install -U pip
- name: Run typesafety tests
run: |
poetry run pytest typesafety \
--num-shards=4 --shard-id=${{ matrix.shard }} \
-p no:cov -o addopts="" --mypy-ini-file=setup.cfg
7 changes: 4 additions & 3 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ version: 2

# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools: {python: "3.9"}
os: ubuntu-lts-latest
tools: {python: "3.11"}
jobs:
pre_create_environment:
- asdf plugin add poetry
- asdf install poetry latest
- asdf global poetry latest
- poetry config virtualenvs.create false
- poetry export --with dev --format=requirements.txt --output=requirements.txt
- poetry self add poetry-plugin-export
- poetry export --only main --only docs --extras check_laws --format=requirements.txt --output=requirements.txt

python:
install:
Expand Down
1,678 changes: 768 additions & 910 deletions poetry.lock

Large diffs are not rendered by default.

22 changes: 14 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ _ = "returns.contrib.hypothesis._entrypoint"


[tool.poetry.dependencies]
python = ">= 3.8.1,<4.0"
python = "^3.9"

typing-extensions = ">=4.0,<5.0"
mypy = { version = ">=1.5,<1.6", optional = true }
pytest = { version = "^8.0", optional = true }
hypothesis = { version = "^6.98", optional = true }

[tool.poetry.dev-dependencies]
[tool.poetry.group.dev.dependencies]
anyio = "^4.3"
trio = "^0.24"
attrs = "^23.2"
Expand All @@ -64,30 +66,34 @@ nitpick = "^0.35"
codespell = "^2.2"
slotscheck = "^0.17"

safety = "^3.0"

pytest = "^8.0"
pytest-cov = "^4.1"
pytest-randomly = "^3.12"
pytest-mypy-plugins = "^3.0"
pytest-subtests = "^0.11"
hypothesis = "^6.98"
pytest-shard = "^0.1"

doc8 = "^1.1"

[tool.poetry.group.docs]
optional = true

[tool.poetry.group.docs.dependencies]

sphinx = "^5.2"
sphinx-autodoc-typehints = "^1.23"
sphinxcontrib-mermaid = "0.8.1"
sphinx-typlog-theme = "^0.8"
sphinx-hoverxref = "^1.3"
doc8 = "^1.0"
m2r2 = "^0.3"
tomlkit = "^0.12"

[tool.poetry.extras]
compatible-mypy = ["mypy"]
check-laws = ["pytest", "hypothesis"]


[build-system]
requires = ["poetry-core>=1.6.0"]
requires = ["poetry-core>=1.9.0"]
build-backend = "poetry.core.masonry.api"


Expand Down
35 changes: 12 additions & 23 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ per-file-ignores =
# isort configuration:
# https://pycqa.github.io/isort/docs/configuration/profiles.html
profile = wemake
line_length = 80


[tool:pytest]
Expand Down Expand Up @@ -165,46 +166,34 @@ plugins =

enable_error_code =
truthy-bool,
truthy-iterable,
redundant-expr,
# We don't want "Are you missing an await?" errors,
# because we can't disable them for tests only.
# It is passed as a CLI arg in CI.
# unused-awaitable,
redundant-expr
# ignore-without-code,
possibly-undefined,
redundant-self,

# We run mypy on all python versions, but only 3.10+ supports pattern matching:
exclude = .*test_.*pattern_matching

disable_error_code = empty-body
disable_error_code = empty-body, no-untyped-def

# We cannot work without explicit `Any` types and plain generics:
# disallow_any_explicit = True
# disallow_any_generics = True
disallow_any_explicit = false
disallow_any_generics = false

allow_redefinition = False
check_untyped_defs = True
disallow_untyped_calls = True
follow_imports = silent
ignore_errors = False
ignore_missing_imports = True
implicit_reexport = False
strict_optional = True
strict_equality = True
no_implicit_optional = True
local_partial_types = True
warn_no_return = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_return_any = True
warn_unused_configs = True
warn_unreachable = True
ignore_missing_imports = true
strict = true
warn_unreachable = true

# TODO: update our output assertions to match a new syntax
force_uppercase_builtins = true
force_union_syntax = true

# We need this to debug `mypy` plugin:
show_traceback = True

# TODO: Enable this later, it's disabled temporarily while we don't discover why
# the explicit restriction on `typeshed.stdlib.unittest.mock`,
# which is the next section, is not working properly when running
Expand Down
5 changes: 2 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from typing import Final, Optional

from _pytest.config import Config
from py import path as pypath

# See https://github.com/HypothesisWorks/hypothesis/pull/2567
pytest_plugins = ['hypothesis.extra.pytestplugin']
Expand All @@ -27,7 +26,7 @@


def pytest_ignore_collect(
path: pypath.local,
collection_path: Path,
config: Config,
) -> Optional[bool]:
"""
Expand All @@ -36,4 +35,4 @@ def pytest_ignore_collect(
This hook is consulted for all files and directories prior to calling
more specific hooks. Stops at first non-None result.
"""
return Path(path) in PATHS_TO_IGNORE_NOW
return collection_path in PATHS_TO_IGNORE_NOW
6 changes: 3 additions & 3 deletions tests/test_context/test_requires_context/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
from returns.primitives.exceptions import ImmutableStateError


def test_requires_context_immutable():
def test_requires_context_immutable() -> None:
"""Ensures that Context is immutable."""
with pytest.raises(ImmutableStateError):
RequiresContext.from_value(1).abc = 1


def test_requires_context_immutable_copy():
def test_requires_context_immutable_copy() -> None:
"""Ensures that Context returns it self when passed to copy function."""
context = RequiresContext.from_value(1)
assert context is copy(context)


def test_requires_context_immutable_deepcopy():
def test_requires_context_immutable_deepcopy() -> None:
"""Ensures that Context returns it self when passed to deepcopy function."""
context = RequiresContext.from_value(1)
assert context is deepcopy(context)
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ def _same_function(some_arg: int) -> Callable[[float], float]:
return lambda other: other / some_arg


def test_equality():
def test_equality() -> None:
"""Ensures that containers can be compared."""
assert RequiresContext(_same_function) == RequiresContext(_same_function)


def test_nonequality():
def test_nonequality() -> None:
"""Ensures that containers can be compared."""
assert RequiresContext(_same_function) != RequiresContext(str)
assert RequiresContext.from_value(1) != RequiresContext.from_value(1)

0 comments on commit 638c614

Please sign in to comment.