Skip to content
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: 3 additions & 3 deletions .importlinter
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ containers =
usethis._tool.impl.base
layers =
pyproject_toml
codespell | deptry | import_linter | mkdocs | pyproject_fmt | requirements_txt
codespell | deptry | import_linter | mkdocs | pyproject_fmt | requirements_txt | ty
ruff
pytest : coverage_py
pre_commit
Expand All @@ -93,7 +93,7 @@ containers =
usethis._tool.impl.spec
layers =
pyproject_toml
codespell | deptry | import_linter | mkdocs | pyproject_fmt | requirements_txt
codespell | deptry | import_linter | mkdocs | pyproject_fmt | requirements_txt | ty
ruff
pytest : coverage_py
pre_commit
Expand Down Expand Up @@ -128,7 +128,7 @@ type = layers
containers =
usethis._ui.interface
layers =
author | badge | browse | ci | doc | docstyle | format_ | init | lint | list | readme | rule | show | spellcheck | status | test | tool | version
author | badge | browse | ci | doc | docstyle | format_ | init | lint | list | readme | rule | show | spellcheck | status | test | tool | typecheck | version
exhaustive = true

[importlinter:contract:pipeweld]
Expand Down
9 changes: 7 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,14 @@ Tool implementations are defined in classes in the `usethis._tool.impl` module.

- You should write tests in `tests/usethis/_core/test_core_tool` for the `use_*` function, following the pattern of the other tests in that module for other tools.

#### Pass tests
#### Register the tool as a peer in `PyprojectTOMLTool`

- Some tests may break as a result of new test registration, for example the `TestGetUsageTable` tests for the `usethis list` command. You should run the test suite (via CI if you like) and address any failing tests.
- Add your `Tool` subclass instance to the `OTHER_TOOLS` list in `usethis._tool.impl.base.pyproject_toml`. This list tracks all tools other than `pyproject.toml` itself, and is used by `PyprojectTOMLTool` to detect active configuration. A corresponding test `test_in_sync_with_all_tools` will fail if this step is missed.

#### Update tests

- Some tests may need updating as a result of new tool registration. In particular:
- `TestGetUsageTable` tests in `tests/usethis/_core/test_list.py` — these enumerate all tools and their statuses. Add a `UsageRow` for your new tool.

#### Update the README and documentation

Expand Down
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ Additionally, the command line reference documentation can be viewed with `useth
- [`usethis lint`](https://usethis.readthedocs.io/en/stable/cli/reference#usethis-lint) — Add/Configure recommended linters (namely, [Ruff](https://docs.astral.sh/ruff/linter) and [deptry](https://github.com/fpgmaas/deptry)).
- [`usethis spellcheck`](https://usethis.readthedocs.io/en/stable/cli/reference#usethis-spellcheck) — Add/Configure recommended spellcheckers (namely, [codespell](https://github.com/codespell-project/codespell)).
- [`usethis test`](https://usethis.readthedocs.io/en/stable/cli/reference#usethis-test) — Add/Configure a recommended testing framework (namely, [pytest](https://github.com/pytest-dev/pytest) with [Coverage.py](https://github.com/nedbat/coveragepy)).
- [`usethis typecheck`](https://usethis.readthedocs.io/en/stable/cli/reference#usethis-typecheck) — Add/Configure a recommended type checker (namely, [ty](https://docs.astral.sh/ty/)).
- [`usethis tool`](https://usethis.readthedocs.io/en/stable/cli/reference#usethis-tool) — Add/Configure specific tools individually.
- [`usethis tool codespell`](https://usethis.readthedocs.io/en/stable/cli/reference#code-quality-tools) - Use the [codespell spellchecker](https://github.com/codespell-project/codespell): detect common spelling mistakes.
- [`usethis tool deptry`](https://usethis.readthedocs.io/en/stable/cli/reference#code-quality-tools) - Use the [deptry linter](https://github.com/fpgmaas/deptry): avoid missing or superfluous dependency declarations.
- [`usethis tool import-linter`](https://usethis.readthedocs.io/en/stable/cli/reference#code-quality-tools) - Use [Import Linter](https://import-linter.readthedocs.io/en/stable/): enforce a self-imposed architecture on imports.
- [`usethis tool pre-commit`](https://usethis.readthedocs.io/en/stable/cli/reference#code-quality-tools) - Use the [pre-commit](https://github.com/pre-commit/pre-commit) framework to manage and maintain Git hooks. Note that this will also install all the hooks to Git.
- [`usethis tool pyproject-fmt`](https://usethis.readthedocs.io/en/stable/cli/reference#code-quality-tools) - Use the [pyproject-fmt formatter](https://github.com/tox-dev/toml-fmt/tree/main/pyproject-fmt): opinionated formatting of 'pyproject.toml' files.
- [`usethis tool ruff`](https://usethis.readthedocs.io/en/stable/cli/reference#code-quality-tools) - Use [Ruff](https://github.com/astral-sh/ruff): an extremely fast Python linter and code formatter.
- [`usethis tool ty`](https://usethis.readthedocs.io/en/stable/cli/reference#code-quality-tools) - Use [ty](https://docs.astral.sh/ty/): an extremely fast Python type checker.
- [`usethis tool coverage.py`](https://usethis.readthedocs.io/en/stable/cli/reference#testing) - Use [Coverage.py](https://github.com/nedbat/coveragepy): a code coverage measurement tool.
- [`usethis tool pytest`](https://usethis.readthedocs.io/en/stable/cli/reference#testing) - Use the [pytest](https://github.com/pytest-dev/pytest) testing framework.
- [`usethis tool mkdocs`](https://usethis.readthedocs.io/en/stable/cli/reference#documentation) - Use [MkDocs](https://www.mkdocs.org/): Generate project documentation sites with Markdown.
Expand Down Expand Up @@ -173,13 +175,7 @@ If you're not interested in templating automations, then [configurator](https://
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Socket](https://badge.socket.dev/pypi/package/usethis)](https://socket.dev/pypi/package/usethis/overview)

### Roadmap

Major features planned are:

- Support for a typechecker (likely ty, [#838](https://github.com/usethis-python/usethis-python/issues/838)).

Other features are tracked in the [GitHub Issues](https://github.com/usethis-python/usethis-python/issues) page.
Feature requests are tracked in the [GitHub Issues](https://github.com/usethis-python/usethis-python/issues) page.

### Contributing

Expand Down
2 changes: 2 additions & 0 deletions docs/cli/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
- [`usethis lint`](reference.md#usethis-lint) — Add/Configure recommended linters (namely, [Ruff](https://docs.astral.sh/ruff/linter) and [deptry](https://github.com/fpgmaas/deptry)).
- [`usethis spellcheck`](reference.md#usethis-spellcheck) — Add/Configure recommended spellcheckers (namely, [codespell](https://github.com/codespell-project/codespell)).
- [`usethis test`](reference.md#usethis-test) — Add/Configure a recommended testing framework (namely, [pytest](https://github.com/pytest-dev/pytest) with [Coverage.py](https://github.com/nedbat/coveragepy)).
- [`usethis typecheck`](reference.md#usethis-typecheck) — Add/Configure a recommended type checker (namely, [ty](https://docs.astral.sh/ty/)).
- [`usethis tool`](reference.md#usethis-tool) — Add/Configure specific tools individually.
- [`usethis tool codespell`](reference.md#code-quality-tools) - Use the [codespell spellchecker](https://github.com/codespell-project/codespell): detect common spelling mistakes.
- [`usethis tool deptry`](reference.md#code-quality-tools) - Use the [deptry linter](https://github.com/fpgmaas/deptry): avoid missing or superfluous dependency declarations.
- [`usethis tool import-linter`](reference.md#code-quality-tools) - Use [Import Linter](https://import-linter.readthedocs.io/en/stable/): enforce a self-imposed architecture on imports.
- [`usethis tool pre-commit`](reference.md#code-quality-tools) - Use the [pre-commit](https://github.com/pre-commit/pre-commit) framework to manage and maintain Git hooks. Note that this will also install all the hooks to Git.
- [`usethis tool pyproject-fmt`](reference.md#code-quality-tools) - Use the [pyproject-fmt formatter](https://github.com/tox-dev/toml-fmt/tree/main/pyproject-fmt): opinionated formatting of 'pyproject.toml' files.
- [`usethis tool ruff`](reference.md#code-quality-tools) - Use [Ruff](https://github.com/astral-sh/ruff): an extremely fast Python linter and code formatter.
- [`usethis tool ty`](reference.md#code-quality-tools) - Use [ty](https://docs.astral.sh/ty/): an extremely fast Python type checker.
- [`usethis tool coverage.py`](reference.md#testing) - Use [Coverage.py](https://github.com/nedbat/coveragepy): a code coverage measurement tool.
- [`usethis tool pytest`](reference.md#testing) - Use the [pytest](https://github.com/pytest-dev/pytest) testing framework.
- [`usethis tool mkdocs`](reference.md#documentation) - Use [MkDocs](https://www.mkdocs.org/): Generate project documentation sites with Markdown.
Expand Down
30 changes: 29 additions & 1 deletion docs/cli/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Initialize a new Python project with recommended defaults, including:

- a `pyproject.toml` file and relevant configuration,
- recommended linters, formatters, spellcheckers, and test frameworks (all opt-out),
- recommended linters, formatters, spellcheckers, type checkers, and test frameworks (all opt-out),
- docstring style enforcement (opt-in),
- the pre-commit framework (opt-in),
- CI services (opt-in),
Expand All @@ -19,6 +19,7 @@ Supported options:
- `--lint` to add recommended linters (default; or `--no-lint` to opt-out)
- `--spellcheck` to add a recommended spellchecker (default; or `--no-spellcheck` to opt-out)
- `--test` to add a recommended testing framework (default; or `--no-test` to opt-out)
- `--typecheck` to add a recommended type checker (default; or `--no-typecheck` to opt-out)
- `--pre-commit` to add the pre-commit framework for git hooks (but the default is `--no-pre-commit`)
- `--ci` to add a CI service configuration

Expand Down Expand Up @@ -172,6 +173,32 @@ Possible values:

See [`usethis tool`](#usethis-tool) for more information.

## `usethis typecheck`

Add a recommended type checker to the project (namely, [ty](https://docs.astral.sh/ty/)), including:

- declared & installed dependencies with `uv add`,
- relevant configuration, and
- any other relevant directories or tool-bespoke configuration files.

Note if `pyproject.toml` is not present, it will be created, since this is required for declaring dependencies with `uv add`.

Supported options:

- `--remove` to remove the tool instead of adding it
- `--how` to only print how to use the tool, with no other side effects
- `--offline` to disable network access and rely on caches
- `--frozen` to leave the virtual environment and lockfile unchanged
- `--quiet` to suppress output
- `--backend` to specify a package manager backend to use. The default is to auto-detect.

Possible values:
- `auto` to auto-detect the backend (default)
- `uv` to use the [uv](https://docs.astral.sh/uv) package manager
- `none` to not use a package manager backend and display messages for some operations.

See [`usethis tool`](#usethis-tool) for more information.

## `usethis tool`

Add a new tool to a Python project, including:
Expand All @@ -192,6 +219,7 @@ declaring dependencies with `uv add`.
- `usethis tool pre-commit` - Use the [pre-commit](https://github.com/pre-commit/pre-commit) framework to manage and maintain Git hooks. Note that this will also install all the hooks to Git.
- `usethis tool pyproject-fmt` - Use the [pyproject-fmt formatter](https://github.com/tox-dev/toml-fmt/tree/main/pyproject-fmt): opinionated formatting of 'pyproject.toml' files.
- `usethis tool ruff` - Use [Ruff](https://github.com/astral-sh/ruff): an extremely fast Python linter and code formatter.
- `usethis tool ty` - Use [ty](https://docs.astral.sh/ty/): an extremely fast Python type checker.

### Testing

Expand Down
2 changes: 1 addition & 1 deletion src/usethis/_backend/uv/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from usethis._backend.uv.call import call_uv_subprocess
from usethis._backend.uv.errors import UVSubprocessFailedError

FALLBACK_UV_VERSION = "0.10.8"
FALLBACK_UV_VERSION = "0.10.12"


def get_uv_version() -> str:
Expand Down
18 changes: 18 additions & 0 deletions src/usethis/_config_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ def files_manager() -> Iterator[None]:
DotCoverageRCManager(),
DotCoverageRCTOMLManager(),
DotRuffTOMLManager(),
DotTyTOMLManager(),
DotPytestINIManager(),
DotImportLinterManager(),
MkDocsYMLManager(),
PreCommitConfigYAMLManager(),
PytestINIManager(),
RuffTOMLManager(),
ToxINIManager(),
TyTOMLManager(),
UVTOMLManager(),
):
yield
Expand Down Expand Up @@ -117,3 +119,19 @@ class ToxINIManager(INIFileManager):
@property
def relative_path(self) -> Path:
return Path("tox.ini")


class DotTyTOMLManager(TOMLFileManager):
"""Class to manage the .ty.toml file."""

@property
def relative_path(self) -> Path:
return Path(".ty.toml")


class TyTOMLManager(TOMLFileManager):
"""Class to manage the ty.toml file."""

@property
def relative_path(self) -> Path:
return Path("ty.toml")
29 changes: 28 additions & 1 deletion src/usethis/_core/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from usethis._tool.impl.base.pytest import PytestTool
from usethis._tool.impl.base.requirements_txt import RequirementsTxtTool
from usethis._tool.impl.base.ruff import RuffTool
from usethis._tool.impl.base.ty import TyTool
from usethis._tool.rule import RuleConfig
from usethis._types.backend import BackendEnum

Expand Down Expand Up @@ -513,7 +514,31 @@ def _get_basic_rule_config() -> RuleConfig:
return rule_config


def use_tool(
def use_ty(*, remove: bool = False, how: bool = False) -> None:
tool = TyTool()

if how:
tool.print_how_to_use()
return

if not remove:
ensure_dep_declaration_file()

tool.add_dev_deps()
tool.update_bitbucket_steps()
tool.add_pre_commit_config()

tool.add_configs()
tool.print_how_to_use()
else:
tool.remove_bitbucket_steps()
tool.remove_configs()
tool.remove_pre_commit_repo_configs()
tool.remove_dev_deps()
tool.remove_managed_files()


def use_tool( # noqa: PLR0912
tool: SupportedToolType,
*,
remove: bool = False,
Expand Down Expand Up @@ -553,6 +578,8 @@ def use_tool(
use_requirements_txt(remove=remove, how=how)
elif isinstance(tool, RuffTool):
use_ruff(remove=remove, how=how)
elif isinstance(tool, TyTool):
use_ty(remove=remove, how=how)
else:
# Having the assert_never here is effectively a way of testing cases are
# exhaustively handled, which ensures it is kept up to date with ALL_TOOLS,
Expand Down
1 change: 1 addition & 0 deletions src/usethis/_integrations/pre_commit/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"ruff", # Alias used for ruff-check
"ruff-check", # ruff-check followed by ruff-format seems to be the recommended way by Astral
"ruff-format",
"ty",
"deptry",
"lint_imports", # Alias used for import-linter used in the Import Linter docs, see https://github.com/usethis-python/usethis-python/issues/1022
"import-linter",
Expand Down
3 changes: 3 additions & 0 deletions src/usethis/_tool/all_.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from usethis._tool.impl.base.pytest import PytestTool
from usethis._tool.impl.base.requirements_txt import RequirementsTxtTool
from usethis._tool.impl.base.ruff import RuffTool
from usethis._tool.impl.base.ty import TyTool

SupportedToolType: TypeAlias = (
CodespellTool
Expand All @@ -26,6 +27,7 @@
| PytestTool
| RequirementsTxtTool
| RuffTool
| TyTool
)

ALL_TOOLS: list[SupportedToolType] = [
Expand All @@ -41,4 +43,5 @@
PytestTool(),
RequirementsTxtTool(),
RuffTool(),
TyTool(),
]
2 changes: 2 additions & 0 deletions src/usethis/_tool/impl/base/pyproject_toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from usethis._tool.impl.base.pytest import PytestTool
from usethis._tool.impl.base.requirements_txt import RequirementsTxtTool
from usethis._tool.impl.base.ruff import RuffTool
from usethis._tool.impl.base.ty import TyTool
from usethis._tool.impl.spec.pyproject_toml import PyprojectTOMLToolSpec

OTHER_TOOLS: list[Tool] = [
Expand All @@ -28,6 +29,7 @@
PytestTool(),
RequirementsTxtTool(),
RuffTool(),
TyTool(),
]


Expand Down
2 changes: 1 addition & 1 deletion src/usethis/_tool/impl/base/ruff.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from usethis._io import KeyValueFileManager
from usethis._tool.rule import RuleConfig

_RUFF_VERSION = "v0.15.4" # Manually bump this version when necessary
_RUFF_VERSION = "v0.15.7" # Manually bump this version when necessary


class RuffTool(RuffToolSpec, Tool):
Expand Down
13 changes: 13 additions & 0 deletions src/usethis/_tool/impl/base/ty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from __future__ import annotations

from typing import final

from usethis._console import how_print
from usethis._tool.base import Tool
from usethis._tool.impl.spec.ty import TyToolSpec


class TyTool(TyToolSpec, Tool):
@final
def print_how_to_use(self) -> None:
how_print(f"Run '{self.how_to_use_cmd()}' to run the {self.name} type checker.")
2 changes: 1 addition & 1 deletion src/usethis/_tool/impl/spec/codespell.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
if TYPE_CHECKING:
from usethis._io import KeyValueFileManager

_CODESPELL_VERSION = "v2.4.1" # Manually bump this version when necessary
_CODESPELL_VERSION = "v2.4.2" # Manually bump this version when necessary


class CodespellToolSpec(ToolSpec):
Expand Down
2 changes: 1 addition & 1 deletion src/usethis/_tool/impl/spec/pyproject_fmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from usethis._tool.pre_commit import PreCommitConfig
from usethis._types.deps import Dependency

_PYPROJECT_FMT_VERSION = "v2.16.2" # Manually bump this version when necessary
_PYPROJECT_FMT_VERSION = "v2.20.0" # Manually bump this version when necessary


class PyprojectFmtToolSpec(ToolSpec):
Expand Down
Loading
Loading