Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pyprojectification #1079

Merged
merged 4 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .coveragerc

This file was deleted.

2 changes: 1 addition & 1 deletion docs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ but please don't include them in your pull requests.

After this short initial setup you're ready to run tests::

$ COVERAGE_PROCESS_START=`pwd`/.coveragerc COVERAGE_FILE=`pwd`/.coverage PYTHONPATH=`pwd` pytest --ds=pytest_django_test.settings_postgres
$ COVERAGE_PROCESS_START=`pwd`/pyproject.toml COVERAGE_FILE=`pwd`/.coverage PYTHONPATH=`pwd` pytest --ds=pytest_django_test.settings_postgres

You should repeat the above step for sqlite and mysql before the next step.
This step will create a lot of ``.coverage`` files with additional suffixes for
Expand Down
57 changes: 57 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,60 @@ build-backend = "setuptools.build_meta"

[tool.setuptools_scm]
write_to = "pytest_django/_version.py"

[tool.pytest.ini_options]
addopts = [
# Error on using unregistered marker.
"--strict-markers",
# Show extra test summary info for everything.
"-ra",
]
DJANGO_SETTINGS_MODULE = "pytest_django_test.settings_sqlite_file"
testpaths = ["tests"]

[tool.mypy]
strict = true
disallow_incomplete_defs = false
disallow_untyped_defs = false
disallow_subclassing_any = false
files = [
"pytest_django",
"pytest_django_test",
"tests",
]
[[tool.mypy.overrides]]
module = [
"django.*",
"configurations.*",
"psycopg2cffi.*",
]
ignore_missing_imports = true

[tool.coverage.run]
parallel = true
source = ["${PYTESTDJANGO_COVERAGE_SRC}."]
branch = true
[tool.coverage.report]
include = [
"pytest_django/*",
"pytest_django_test/*",
"tests/*",
]
skip_covered = true
exclude_lines = [
"pragma: no cover",
"if TYPE_CHECKING:",
]

[tool.isort]
forced_separate = [
"tests",
"pytest_django",
"pytest_django_test",
]
combine_as_imports = true
include_trailing_comma = true
line_length = 79
multi_line_output = 5
lines_after_imports = 2
extend_skip = ["pytest_django/_version.py"]
9 changes: 6 additions & 3 deletions pytest_django/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,14 @@ def django_db_use_migrations(request: pytest.FixtureRequest) -> bool:

@pytest.fixture(scope="session")
def django_db_keepdb(request: pytest.FixtureRequest) -> bool:
return request.config.getvalue("reuse_db")
reuse_db: bool = request.config.getvalue("reuse_db")
return reuse_db


@pytest.fixture(scope="session")
def django_db_createdb(request: pytest.FixtureRequest) -> bool:
return request.config.getvalue("create_db")
create_db: bool = request.config.getvalue("create_db")
return create_db


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -407,7 +409,8 @@ def django_user_model(db: None):
@pytest.fixture()
def django_username_field(django_user_model) -> str:
"""The fieldname for the username used with Django's user model."""
return django_user_model.USERNAME_FIELD
field: str = django_user_model.USERNAME_FIELD
return field


@pytest.fixture()
Expand Down
5 changes: 3 additions & 2 deletions pytest_django/lazy_django.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@

if not ret and "django.conf" in sys.modules:
django_conf: Any = sys.modules["django.conf"]
return django_conf.settings.configured
ret = django_conf.settings.configured

return ret


def get_django_version() -> Tuple[int, int, int, str, int]:
import django

return django.VERSION
version: Tuple[int, int, int, str, int] = django.VERSION
return version

Check warning on line 37 in pytest_django/lazy_django.py

View check run for this annotation

Codecov / codecov/patch

pytest_django/lazy_django.py#L36-L37

Added lines #L36 - L37 were not covered by tests
19 changes: 11 additions & 8 deletions pytest_django/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,14 +491,14 @@
self._testcase(result=self)

try:
TestCaseFunction.runtest = non_debugging_runtest # type: ignore[assignment]
TestCaseFunction.runtest = non_debugging_runtest # type: ignore[method-assign]

request.getfixturevalue("django_db_setup")

with django_db_blocker.unblock():
yield
finally:
TestCaseFunction.runtest = original_runtest # type: ignore[assignment]
TestCaseFunction.runtest = original_runtest # type: ignore[method-assign]


@pytest.fixture(scope="function", autouse=True)
Expand All @@ -521,7 +521,7 @@

from django.core import mail

return mail.outbox
return mail.outbox # type: ignore[no-any-return]


@pytest.fixture(scope="function")
Expand Down Expand Up @@ -589,7 +589,7 @@
return key == "%s"

@staticmethod
def _get_origin():
def _get_origin() -> Optional[str]:
stack = inspect.stack()

# Try to use topmost `self.origin` first (Django 1.9+, and with
Expand All @@ -598,10 +598,11 @@
func = f[3]
if func == "render":
frame = f[0]
origin: Optional[str]
try:
origin = frame.f_locals["self"].origin
except (AttributeError, KeyError):
continue
origin = None

Check warning on line 605 in pytest_django/plugin.py

View check run for this annotation

Codecov / codecov/patch

pytest_django/plugin.py#L605

Added line #L605 was not covered by tests
if origin is not None:
return origin

Expand All @@ -620,7 +621,9 @@
# ``django.template.base.Template``
template = f_locals["self"]
if isinstance(template, Template):
return template.name
name: str = template.name
return name
return None

Check warning on line 626 in pytest_django/plugin.py

View check run for this annotation

Codecov / codecov/patch

pytest_django/plugin.py#L624-L626

Added lines #L624 - L626 were not covered by tests

def __mod__(self, var: str) -> str:
origin = self._get_origin()
Expand Down Expand Up @@ -704,8 +707,8 @@
This is the object returned by django_db_blocker.
"""

def __init__(self):
self._history = []
def __init__(self) -> None:
self._history = [] # type: ignore[var-annotated]
self._real_ensure_connection = None

@property
Expand Down
30 changes: 16 additions & 14 deletions pytest_django_test/db_helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import sqlite3
import subprocess
from typing import Mapping, Optional

import pytest
from django.conf import settings
Expand All @@ -10,8 +11,8 @@
# Construct names for the "inner" database used in runpytest tests
_settings = settings.DATABASES["default"]

DB_NAME = _settings["NAME"]
TEST_DB_NAME = _settings["TEST"]["NAME"]
DB_NAME: str = _settings["NAME"]
TEST_DB_NAME: str = _settings["TEST"]["NAME"]

if _settings["ENGINE"] == "django.db.backends.sqlite3" and TEST_DB_NAME is None:
TEST_DB_NAME = ":memory:"
Expand All @@ -31,18 +32,19 @@
SECOND_TEST_DB_NAME = TEST_DB_NAME + '_second' if DB_NAME is not None else None


def get_db_engine():
return _settings["ENGINE"].split(".")[-1]
def get_db_engine() -> str:
db_engine: str = _settings["ENGINE"].split(".")[-1]
return db_engine


class CmdResult:
def __init__(self, status_code, std_out, std_err):
def __init__(self, status_code: int, std_out: bytes, std_err: bytes) -> None:
self.status_code = status_code
self.std_out = std_out
self.std_err = std_err


def run_cmd(*args, env=None):
def run_cmd(*args: str, env: Optional[Mapping[str, str]] = None) -> CmdResult:
r = subprocess.Popen(
args,
stdout=subprocess.PIPE,
Expand All @@ -54,7 +56,7 @@ def run_cmd(*args, env=None):
return CmdResult(ret, stdoutdata, stderrdata)


def run_psql(*args):
def run_psql(*args: str) -> CmdResult:
env = {}
user = _settings.get("USER")
if user: # pragma: no branch
Expand All @@ -68,7 +70,7 @@ def run_psql(*args):
return run_cmd("psql", *args, env=env)


def run_mysql(*args):
def run_mysql(*args: str) -> CmdResult:
user = _settings.get("USER")
if user: # pragma: no branch
args = ("-u", user, *args)
Expand All @@ -82,22 +84,22 @@ def run_mysql(*args):
return run_cmd("mysql", *args)


def skip_if_sqlite_in_memory():
def skip_if_sqlite_in_memory() -> None:
if (
_settings["ENGINE"] == "django.db.backends.sqlite3"
and _settings["TEST"]["NAME"] is None
):
pytest.skip("Do not test db reuse since database does not support it")


def _get_db_name(db_suffix=None):
def _get_db_name(db_suffix: Optional[str] = None) -> str:
name = TEST_DB_NAME
if db_suffix:
name = f"{name}_{db_suffix}"
return name


def drop_database(db_suffix=None):
def drop_database(db_suffix: Optional[str] = None) -> None:
name = _get_db_name(db_suffix)
db_engine = get_db_engine()

Expand All @@ -119,7 +121,7 @@ def drop_database(db_suffix=None):
os.unlink(name)


def db_exists(db_suffix=None):
def db_exists(db_suffix: Optional[str] = None) -> bool:
name = _get_db_name(db_suffix)
db_engine = get_db_engine()

Expand All @@ -137,7 +139,7 @@ def db_exists(db_suffix=None):
return os.path.exists(name)


def mark_database():
def mark_database() -> None:
db_engine = get_db_engine()

if db_engine == "postgresql":
Expand All @@ -162,7 +164,7 @@ def mark_database():
conn.close()


def mark_exists():
def mark_exists() -> bool:
db_engine = get_db_engine()

if db_engine == "postgresql":
Expand Down
35 changes: 0 additions & 35 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -53,43 +53,8 @@ testing =
[options.package_data]
pytest_django = py.typed

[tool:pytest]
# --strict-markers: error on using unregistered marker.
# -ra: show extra test summary info for everything.
addopts = --strict-markers -ra
DJANGO_SETTINGS_MODULE = pytest_django_test.settings_sqlite_file
testpaths = tests

[flake8]
# W503 line break before binary operator
ignore = W503
max-line-length = 99
exclude = lib/,src/,docs/,bin/,pytest_django/_version.py

[isort]
forced_separate = tests,pytest_django,pytest_django_test
combine_as_imports = true
default_section = THIRDPARTY
include_trailing_comma = true
line_length = 79
multi_line_output = 5
lines_after_imports = 2
extend_skip = pytest_django/_version.py

[mypy]
check_untyped_defs = True
disallow_any_generics = True
no_implicit_optional = True
show_error_codes = True
strict_equality = True
warn_redundant_casts = True
warn_unreachable = True
warn_unused_configs = True
no_implicit_reexport = True

[mypy-django.*]
ignore_missing_imports = True
[mypy-configurations.*]
ignore_missing_imports = True
[mypy-psycopg2cffi.*]
ignore_missing_imports = True
11 changes: 6 additions & 5 deletions tests/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

def db_supports_reset_sequences() -> bool:
"""Return if the current db engine supports `reset_sequences`."""
return (
ret: bool = (
connection.features.supports_transactions
and connection.features.supports_sequence_reset
)
return ret


def test_noaccess() -> None:
Expand Down Expand Up @@ -57,13 +58,13 @@ class TestDatabaseFixtures:
])
def all_dbs(self, request: pytest.FixtureRequest) -> None:
if request.param == "django_db_reset_sequences":
return request.getfixturevalue("django_db_reset_sequences")
request.getfixturevalue("django_db_reset_sequences")
elif request.param == "transactional_db":
return request.getfixturevalue("transactional_db")
request.getfixturevalue("transactional_db")
elif request.param == "db":
return request.getfixturevalue("db")
request.getfixturevalue("db")
elif request.param == "django_db_serialized_rollback":
return request.getfixturevalue("django_db_serialized_rollback")
request.getfixturevalue("django_db_serialized_rollback")
else:
assert False # pragma: no cover

Expand Down
Loading