Skip to content

Style/enable more typechecking #1106

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

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
6 changes: 4 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,9 @@ jobs:
- name: Setup | Install dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
pip install -e .[dev,mypy]
pip install -e .[dev,mypy,test]
# needs test because we run mypy over the tests as well and without the dependencies
# mypy will throw import errors

- name: Lint | Ruff Evaluation
id: lint
Expand All @@ -382,7 +384,7 @@ jobs:
id: type-check
if: ${{ always() && steps.lint.outcome != 'skipped' }}
run: |
mypy --ignore-missing-imports src/
mypy .

- name: Format-Check | Ruff Evaluation
id: format-check
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
apidoc_extra_args = ["-d", "3"]


def setup(app): # noqa: ARG001,ANN001,ANN201
def setup(app): # type: ignore[no-untyped-def] # noqa: ARG001,ANN001,ANN201
pass


Expand Down
16 changes: 11 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ dev = [
mypy = [
"mypy == 1.13.0",
"types-requests ~= 2.32.0",
"types-pyyaml ~= 6.0",
]


Expand Down Expand Up @@ -152,7 +153,7 @@ commands =
[testenv:mypy]
deps = .[mypy]
commands =
mypy src/
mypy .

[testenv:coverage]
deps = coverage[toml]
Expand All @@ -175,7 +176,6 @@ pretty = true
error_summary = true
follow_imports = "normal"
enable_error_code = ["ignore-without-code"]
ignore_missing_imports = true # gitpython is very dynamic
disallow_untyped_calls = true
# warn_return_any = true
strict_optional = true
Expand All @@ -191,9 +191,15 @@ plugins = ["pydantic.mypy"]

[[tool.mypy.overrides]]
module = "tests.*"
allow_untyped_defs = true
allow_incomplete_defs = true
allow_untyped_calls = true
disallow_untyped_defs = false

[[tool.mypy.overrides]]
module = "flatdict"
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = "shellingham"
ignore_missing_imports = true

[tool.ruff]
line-length = 88
Expand Down
4 changes: 2 additions & 2 deletions scripts/bump_version_in_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

def update_github_actions_example(filepath: Path, new_version: str) -> None:
psr_regex = RegExp(r"(uses:.*python-semantic-release)@v\d+\.\d+\.\d+")
file_content_lines = filepath.read_text().splitlines()
file_content_lines: list[str] = filepath.read_text().splitlines()

for regex in [psr_regex]:
file_content_lines = list(
map(
lambda line, regex=regex: regex.sub(r"\1@v" + new_version, line),
lambda line, regex=regex: regex.sub(r"\1@v" + new_version, line), # type: ignore[misc]
file_content_lines,
)
)
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,9 @@ def _get_md5_for_set_of_files(files: Sequence[Path | str]) -> str:

@pytest.fixture(scope="session")
def clean_os_environment() -> dict[str, str]:
return dict( # type: ignore
return dict(
filter(
lambda k_v: k_v[1] is not None,
lambda k_v: k_v[1] is not None, # type: ignore[arg-type]
{
"PATH": os.getenv("PATH"),
"HOME": os.getenv("HOME"),
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/cmd_config/test_generate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
if TYPE_CHECKING:
from typing import Any

from tests.command_line.conftest import CliRunner
from click.testing import CliRunner


@pytest.fixture
Expand Down
18 changes: 9 additions & 9 deletions tests/fixtures/git_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def __call__(
self, build_definition: Sequence[RepoActions]
) -> RepoDefinition: ...

RepoDefinition: TypeAlias = dict[VersionStr, RepoVersionDef]
RepoDefinition: TypeAlias = dict[VersionStr, RepoVersionDef] # type: ignore[misc] # mypy is thoroughly confused
"""
A Type alias to define a repositories versions, commits, and changelog sections
for a specific commit convention
Expand Down Expand Up @@ -622,10 +622,10 @@ def _format_squash_commit_msg_github(
pr_number: int,
squashed_commits: list[CommitDef | str],
) -> str:
sq_cmts: list[str] = ( # type: ignore
squashed_commits
if not isinstance(squashed_commits[0], dict)
else [commit["msg"] for commit in squashed_commits] # type: ignore
sq_cmts: list[str] = (
squashed_commits # type: ignore[assignment]
if len(squashed_commits) > 1 and not isinstance(squashed_commits[0], dict)
else [commit["msg"] for commit in squashed_commits] # type: ignore[index]
)
return (
str.join(
Expand Down Expand Up @@ -1015,19 +1015,19 @@ def expand_repo_construction_steps(
*acc,
*(
reduce(
expand_repo_construction_steps,
expand_repo_construction_steps, # type: ignore[arg-type]
step["details"]["pre_actions"],
[], # type: ignore[arg-type]
[],
)
if "pre_actions" in step["details"]
else []
),
step,
*(
reduce(
expand_repo_construction_steps,
expand_repo_construction_steps, # type: ignore[arg-type]
step["details"]["post_actions"],
[], # type: ignore[arg-type]
[],
)
if "post_actions" in step["details"]
else []
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/semantic_release/changelog/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@
"subjects", [("dogs", "cats"), ("stocks", "finance", "politics")]
)
def test_template_env_configurable(format_map: dict[str, Any], subjects: tuple[str]):
template = EXAMPLE_TEMPLATE_FORMAT_STR.format_map(format_map)
template_as_str = EXAMPLE_TEMPLATE_FORMAT_STR.format_map(format_map)
env = environment(**format_map)
template = env.from_string(template)
template = env.from_string(template_as_str)

title = "important"
newline = "\n"
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/semantic_release/cli/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from typing import Any

from tests.fixtures.example_project import ExProjectDir, UpdatePyprojectTomlFn
from tests.fixtures.git_repo import BuildRepoFn
from tests.fixtures.git_repo import BuildRepoFn, CommitConvention


@pytest.mark.parametrize(
Expand Down Expand Up @@ -230,7 +230,7 @@ def test_load_valid_runtime_config(
],
)
def test_load_valid_runtime_config_w_custom_parser(
commit_parser: str,
commit_parser: CommitConvention,
build_configured_base_repo: BuildRepoFn,
example_project_dir: ExProjectDir,
example_pyproject_toml: Path,
Expand Down
14 changes: 7 additions & 7 deletions tests/unit/semantic_release/commit_parser/test_scipy.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
def test_valid_scipy_parsed_chore_commits(
default_scipy_parser: ScipyCommitParser,
make_commit_obj: MakeCommitObjFn,
scipy_chore_commit_parts: list[list[str]],
scipy_chore_commit_parts: list[tuple[str, str, list[str]]],
scipy_chore_commits: list[str],
):
expected_parts = scipy_chore_commit_parts
Expand All @@ -34,7 +34,7 @@ def test_valid_scipy_parsed_chore_commits(
subject,
*[body.rstrip() for body in commit_bodies if body],
]
expected_brk_desc = []
expected_brk_desc: list[str] = []

commit = make_commit_obj(full_commit_msg)
result = default_scipy_parser.parse(commit)
Expand All @@ -50,7 +50,7 @@ def test_valid_scipy_parsed_chore_commits(
def test_valid_scipy_parsed_patch_commits(
default_scipy_parser: ScipyCommitParser,
make_commit_obj: MakeCommitObjFn,
scipy_patch_commit_parts: list[list[str]],
scipy_patch_commit_parts: list[tuple[str, str, list[str]]],
scipy_patch_commits: list[str],
):
expected_parts = scipy_patch_commit_parts
Expand All @@ -63,7 +63,7 @@ def test_valid_scipy_parsed_patch_commits(
subject,
*[body.rstrip() for body in commit_bodies if body],
]
expected_brk_desc = []
expected_brk_desc: list[str] = []

commit = make_commit_obj(full_commit_msg)
result = default_scipy_parser.parse(commit)
Expand All @@ -79,7 +79,7 @@ def test_valid_scipy_parsed_patch_commits(
def test_valid_scipy_parsed_minor_commits(
default_scipy_parser: ScipyCommitParser,
make_commit_obj: MakeCommitObjFn,
scipy_minor_commit_parts: list[list[str]],
scipy_minor_commit_parts: list[tuple[str, str, list[str]]],
scipy_minor_commits: list[str],
):
expected_parts = scipy_minor_commit_parts
Expand All @@ -92,7 +92,7 @@ def test_valid_scipy_parsed_minor_commits(
subject,
*[body for body in commit_bodies if body],
]
expected_brk_desc = []
expected_brk_desc: list[str] = []

commit = make_commit_obj(full_commit_msg)
result = default_scipy_parser.parse(commit)
Expand All @@ -108,7 +108,7 @@ def test_valid_scipy_parsed_minor_commits(
def test_valid_scipy_parsed_major_commits(
default_scipy_parser: ScipyCommitParser,
make_commit_obj: MakeCommitObjFn,
scipy_major_commit_parts: list[list[str]],
scipy_major_commit_parts: list[tuple[str, str, list[str]]],
scipy_major_commits: list[str],
):
expected_parts = scipy_major_commit_parts
Expand Down
118 changes: 4 additions & 114 deletions tests/unit/semantic_release/hvcs/test_gitlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,127 +22,19 @@
if TYPE_CHECKING:
from typing import Generator

gitlab.Gitlab("") # instantiation necessary to discover gitlab ProjectManager

# Note: there's nothing special about the value of these variables,
# they're just constants for easier consistency with the faked objects
A_GOOD_TAG = "v1.2.3"
A_BAD_TAG = "v2.1.1-rc.1"
A_LOCKED_TAG = "v0.9.0"
A_MISSING_TAG = "v1.0.0+missing"
AN_EXISTING_TAG = "v2.3.4+existing"
# But note this is the only ref we're making a "fake" commit for, so
# tests which need to query the remote for "a" ref, the exact sha for
# which doesn't matter, all use this constant
REF = "hashashash"


class _GitlabProject:
def __init__(self, status):
self.commits = {REF: self._Commit(status)}
self.tags = self._Tags()
self.releases = self._Releases()

class _Commit:
def __init__(self, status):
self.statuses = self._Statuses(status)

class _Statuses:
def __init__(self, status):
if status == "pending":
self.jobs = [
{
"name": "good_job",
"status": "passed",
"allow_failure": False,
},
{
"name": "slow_job",
"status": "pending",
"allow_failure": False,
},
]
elif status == "failure":
self.jobs = [
{
"name": "good_job",
"status": "passed",
"allow_failure": False,
},
{"name": "bad_job", "status": "failed", "allow_failure": False},
]
elif status == "allow_failure":
self.jobs = [
{
"name": "notsobad_job",
"status": "failed",
"allow_failure": True,
},
{
"name": "good_job2",
"status": "passed",
"allow_failure": False,
},
]
elif status == "success":
self.jobs = [
{
"name": "good_job1",
"status": "passed",
"allow_failure": True,
},
{
"name": "good_job2",
"status": "passed",
"allow_failure": False,
},
]

def list(self):
return self.jobs

class _Tags:
def __init__(self):
pass

def get(self, tag):
if tag in (A_GOOD_TAG, AN_EXISTING_TAG):
return self._Tag()
if tag == A_LOCKED_TAG:
return self._Tag(locked=True)
raise gitlab.exceptions.GitlabGetError()

class _Tag:
def __init__(self, locked=False):
self.locked = locked

def set_release_description(self, _):
if self.locked:
raise gitlab.exceptions.GitlabUpdateError()

class _Releases:
def __init__(self):
pass

def create(self, input_):
if (
input_["name"]
and input_["tag_name"]
and input_["tag_name"] in (A_GOOD_TAG, A_LOCKED_TAG)
):
return self._Release()
raise gitlab.exceptions.GitlabCreateError()

def update(self, tag, _):
if tag == A_MISSING_TAG:
raise gitlab.exceptions.GitlabUpdateError()
return self._Release()

class _Release:
def __init__(self, locked=False):
pass


@pytest.fixture
def default_gl_project(example_git_https_url: str):
return gitlab.Gitlab(url=example_git_https_url).projects.get(
Expand Down Expand Up @@ -428,12 +320,10 @@ def test_create_release_fails_with_bad_tag(


@pytest.mark.parametrize("tag", (A_GOOD_TAG, A_LOCKED_TAG))
def test_update_release_succeeds(
default_gl_client: Gitlab, default_gl_project: gitlab.v4.objects.Project, tag: str
):
fake_release_obj = gitlab.v4.objects.ProjectReleaseManager(default_gl_project).get(
tag, lazy=True
)
def test_update_release_succeeds(default_gl_client: Gitlab, tag: str):
fake_release_obj = gitlab.v4.objects.ProjectReleaseManager(
default_gl_client._client
).get(tag, lazy=True)
fake_release_obj._attrs["name"] = tag

with mock.patch.object(
Expand Down
Loading