Skip to content

Commit

Permalink
FEAT: merge dev tool configurations into pyproject.toml (#146)
Browse files Browse the repository at this point in the history
* FEAT: merge mypy configuration into pyproject.toml
* FEAT: merge pyright configuration into pyproject.toml
* FEAT: merge pytest config into pyproject.toml
  • Loading branch information
redeboer authored Jul 1, 2023
1 parent 27a41a5 commit a85f1eb
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 98 deletions.
20 changes: 0 additions & 20 deletions .mypy.ini

This file was deleted.

79 changes: 79 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,85 @@ target-version = [
"py39",
]

[tool.coverage.run]
branch = true
source = ["src"]

[tool.mypy]
disallow_incomplete_defs = true
disallow_untyped_defs = true
exclude = '.*/repoma/__init__\.py'
files = ["**/*.py"]
show_error_codes = true
warn_unused_configs = true

[[tool.mypy.overrides]]
check_untyped_defs = true
disallow_incomplete_defs = false
disallow_untyped_defs = false
module = ["tests.*"]

[[tool.mypy.overrides]]
ignore_errors = true
module = ["typings.*"]

[[tool.mypy.overrides]]
ignore_missing_imports = true
module = ["ruamel.*"]

[[tool.mypy.overrides]]
ignore_missing_imports = true
module = ["nbformat.*"]


[tool.pyright]
exclude = [
"**/.git",
"**/.ipynb_checkpoints",
"**/.mypy_cache",
"**/.pytest_cache",
"**/.tox",
"**/__pycache__",
"**/_build",
]
reportGeneralTypeIssues = false
reportIncompatibleMethodOverride = false
reportMissingParameterType = false
reportMissingTypeArgument = false
reportMissingTypeStubs = false
reportOverlappingOverload = false
reportPrivateImportUsage = false
reportPrivateUsage = false
reportUnboundVariable = false
reportUnknownArgumentType = false
reportUnknownMemberType = false
reportUnknownParameterType = false
reportUnknownVariableType = false
reportUnnecessaryComparison = false
reportUnnecessaryContains = false
reportUnnecessaryIsInstance = false
reportUntypedFunctionDecorator = false
reportUnusedClass = true
reportUnusedFunction = true
reportUnusedImport = true
reportUnusedVariable = true
typeCheckingMode = "strict"


[tool.pytest.ini_options]
addopts = """
--color=yes
--doctest-continue-on-failure
--doctest-modules
--durations=3
"""
filterwarnings = ["error"]
markers = ["slow: marks tests as slow (deselect with '-m \"not slow\"')"]
testpaths = [
"src",
"tests",
]

[tool.ruff]
extend-select = [
"A",
Expand Down
33 changes: 0 additions & 33 deletions pyrightconfig.json

This file was deleted.

17 changes: 0 additions & 17 deletions pytest.ini

This file was deleted.

1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ setup_requires =
setuptools_scm
install_requires =
attrs >=20.1.0 # https://www.attrs.org/en/stable/changelog.html#id82
ini2toml
nbformat
pip-tools
PyYAML
Expand Down
8 changes: 6 additions & 2 deletions src/repoma/check_dev_files/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@
github_templates,
github_workflows,
gitpod,
mypy,
nbstripout,
precommit,
prettier,
pyright,
pytest,
pyupgrade,
release_drafter,
ruff,
setup_cfg,
toml,
tox,
update_pip_constraints,
vscode,
)
Expand Down Expand Up @@ -171,10 +173,12 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
update_pip_constraints.main,
cron_frequency=args.pin_requirements,
)
executor(mypy.main)
executor(pytest.main)
executor(pyright.main)
executor(pyupgrade.main)
executor(ruff.main)
executor(setup_cfg.main, args.ignore_author)
executor(tox.main)
executor(precommit.main)
executor(remove_deprecated_tools)
executor(vscode.main)
Expand Down
30 changes: 30 additions & 0 deletions src/repoma/check_dev_files/mypy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Check and update :code:`mypy` settings."""
import os

import tomlkit
from ini2toml.api import Translator

from repoma.errors import PrecommitError
from repoma.utilities import CONFIG_PATH
from repoma.utilities.pyproject import get_sub_table, load_pyproject, write_pyproject


def main() -> None:
_merge_mypy_into_pyproject()


def _merge_mypy_into_pyproject() -> None:
config_path = ".mypy.ini"
if not os.path.exists(config_path):
return
with open(config_path) as stream:
original_contents = stream.read()
toml_str = Translator().translate(original_contents, profile_name=config_path)
mypy_config = tomlkit.parse(toml_str)
pyproject = load_pyproject()
tool_table = get_sub_table(pyproject, "tool", create=True)
tool_table.update(mypy_config)
write_pyproject(pyproject)
os.remove(config_path)
msg = f"Moved mypy configuration to {CONFIG_PATH.pyproject}"
raise PrecommitError(msg)
52 changes: 52 additions & 0 deletions src/repoma/check_dev_files/pyright.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Check and update :code:`mypy` settings."""
import json
import os

from repoma.errors import PrecommitError
from repoma.utilities import CONFIG_PATH
from repoma.utilities.executor import Executor
from repoma.utilities.pyproject import (
complies_with_subset,
get_sub_table,
load_pyproject,
to_toml_array,
write_pyproject,
)


def main() -> None:
executor = Executor()
executor(_merge_config_into_pyproject)
executor(_update_settings)
executor.finalize()


def _merge_config_into_pyproject() -> None:
config_path = "pyrightconfig.json" # cspell:ignore pyrightconfig
if not os.path.exists(config_path):
return
with open(config_path) as stream:
existing_config = json.load(stream)
for key, value in existing_config.items():
if isinstance(value, list):
existing_config[key] = to_toml_array(sorted(value))
pyproject = load_pyproject()
tool_table = get_sub_table(pyproject, "tool.pyright", create=True)
tool_table.update(existing_config)
write_pyproject(pyproject)
os.remove(config_path)
msg = f"Moved pyright configuration to {CONFIG_PATH.pyproject}"
raise PrecommitError(msg)


def _update_settings() -> None:
pyproject = load_pyproject()
settings = get_sub_table(pyproject, "tool.pyright", create=True)
minimal_settings = {
"typeCheckingMode": "strict",
}
if not complies_with_subset(settings, minimal_settings):
settings.update(minimal_settings)
write_pyproject(pyproject)
msg = f"Updated black configuration in {CONFIG_PATH.pyproject}"
raise PrecommitError(msg)
67 changes: 67 additions & 0 deletions src/repoma/check_dev_files/pytest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Check and update :code:`pytest` settings."""
import os
from typing import Dict

import tomlkit
from ini2toml.api import Translator

from repoma.errors import PrecommitError
from repoma.utilities import CONFIG_PATH
from repoma.utilities.cfg import open_config
from repoma.utilities.executor import Executor
from repoma.utilities.pyproject import get_sub_table, load_pyproject, write_pyproject

__PYTEST_INI_PATH = "pytest.ini"


def main() -> None:
executor = Executor()
executor(_merge_coverage_into_pyproject)
executor(_merge_pytest_into_pyproject)
executor(_remove_pytest_ini)
executor.finalize()


def _merge_coverage_into_pyproject() -> None:
if not os.path.exists(__PYTEST_INI_PATH):
return
pytest_ini = open_config(__PYTEST_INI_PATH)
section_name = "coverage:run"
if not pytest_ini.has_section(section_name):
return
coverage_config: Dict = dict(pytest_ini[section_name])
for key, value in coverage_config.items():
if value in {"False", "True"}:
coverage_config[key] = bool(value)
if key == "source" and isinstance(value, str):
coverage_config[key] = [value]
pyproject = load_pyproject()
tool_table = get_sub_table(pyproject, "tool.coverage.run", create=True)
tool_table.update(coverage_config)
write_pyproject(pyproject)
msg = f"Moved Coverage.py configuration to {CONFIG_PATH.pyproject}"
raise PrecommitError(msg)


def _merge_pytest_into_pyproject() -> None:
if not os.path.exists(__PYTEST_INI_PATH):
return
with open(__PYTEST_INI_PATH) as stream:
original_contents = stream.read()
toml_str = Translator().translate(original_contents, profile_name=__PYTEST_INI_PATH)
config = tomlkit.parse(toml_str)
config.pop("coverage:run", None)
pyproject = load_pyproject()
tool_table = get_sub_table(pyproject, "tool", create=True)
tool_table.update(config)
write_pyproject(pyproject)
msg = f"Moved pytest configuration to {CONFIG_PATH.pyproject}"
raise PrecommitError(msg)


def _remove_pytest_ini() -> None:
if not os.path.exists(__PYTEST_INI_PATH):
return
os.remove(__PYTEST_INI_PATH)
msg = f"Removed {__PYTEST_INI_PATH}"
raise PrecommitError(msg)
18 changes: 0 additions & 18 deletions src/repoma/check_dev_files/tox.py

This file was deleted.

1 change: 0 additions & 1 deletion src/repoma/utilities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class _ConfigFilePaths(NamedTuple):
prettier: Path = Path(".prettierrc")
prettier_ignore: Path = Path(".prettierignore")
pyproject: Path = Path("pyproject.toml")
pytest: Path = Path("pytest.ini")
readme: Path = Path("README.md")
readthedocs: Path = Path(".readthedocs.yml")
release_drafter_config: Path = Path(".github/release-drafter.yml")
Expand Down
Loading

0 comments on commit a85f1eb

Please sign in to comment.