diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7c50bae..5d988f5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,23 +1,24 @@ exclude: ^(.idea/) repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.6" + rev: "v0.16.7" hooks: - id: ruff name: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/PyCQA/isort - rev: 5.13.2 + rev: 9.0.1 hooks: - id: isort - repo: https://github.com/psf/black - rev: 26.3.1 + rev: 26.5.1 hooks: - id: black args: - "--line-length=120" + - "--target-version=py311" - "--target-version=py312" - "--target-version=py313" - "--target-version=py314" @@ -27,8 +28,10 @@ repos: rev: 1.20.0 hooks: - id: blacken-docs + # Use the same Black as the hook above so docstring/code-block formatting + # matches the rest of the codebase (the old 23.3.0 pin disagreed with Black 26). additional_dependencies: - - "black==23.3.0" + - "black==26.5.1" args: - "--line-length=120" @@ -59,7 +62,7 @@ repos: exclude: \.(html|svg)$ - repo: https://github.com/fredrikaverpil/creosote.git - rev: v5.1.1 + rev: v5.2.0 hooks: - id: creosote files: ^quickup/ @@ -67,12 +70,12 @@ repos: exclude: ^tests/ - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: v2.4.3 hooks: - id: codespell - repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.408 + rev: v1.1.414 hooks: - id: pyright additional_dependencies: @@ -87,4 +90,4 @@ repos: rev: v3.21.2 hooks: - id: pyupgrade - args: ["--py312-plus"] + args: ["--py311-plus"] diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 6463e4a..18c4a72 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -4,7 +4,7 @@ version: 2 build: - os: "ubuntu-22.04" + os: "ubuntu-24.04" tools: python: "3.14" jobs: diff --git a/pyproject.toml b/pyproject.toml index 1019cfb..2452f34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,18 +30,30 @@ classifiers = [ "Topic :: Software Development", ] dependencies = [ - "python-dotenv", "colorist", "pyclickup", "inquirer", "cyclopts" + "python-dotenv>=1.2.3,<2", + "colorist>=1.8.15,<2", + # pyclickup is unmaintained (0.1.4, last release 2019, classifiers stop at 3.7). + # Upper-bound pinned so an unexpected release cannot silently break the client. + "pyclickup>=0.1.4,<0.2", + "inquirer>=3.4.1,<4", + # 5.0 is in beta with breaking changes; stay on the 4.x line. + "cyclopts>=4.25.2,<5", ] [project.optional-dependencies] dev = [ - "pytest", "pytest-mock", "pytest-cov", "coverage", + "pytest>=9.1.1,<10", + "pytest-mock>=3.15.1,<4", + "pytest-cov>=7.1.0,<8", + "coverage>=7.16.1,<8", + "pre-commit>=4.6.2,<5", ] docs = [ - "sphinx>=7.1.2,<8", - "sphinx_rtd_theme>=2.0.0", - "gitpython>=3.1.31", - "sphinx-copybutton>=0.5.2", + # Sphinx 9.1+ requires Python 3.12; 9.0.x is the last line supporting the 3.11 floor. + "sphinx>=9.0.4,<10", + "sphinx_rtd_theme>=3.1.0,<4", + "gitpython>=3.1.62,<4", + "sphinx-copybutton>=0.5.2,<1", ] [project.scripts] @@ -59,12 +71,12 @@ path = "__about__.py" [tool.hatch.envs.default] dependencies = [ - "ipython", "ipdb" + "ipython>=9.17.1,<10", "ipdb>=0.13.13,<0.14" ] [tool.hatch.envs.test] dependencies = [ - "pytest", "pytest-mock", "pytest-cov" + "pytest>=9.1.1,<10", "pytest-mock>=3.15.1,<4", "pytest-cov>=7.1.0,<8" ] [tool.hatch.envs.default.scripts] @@ -73,10 +85,10 @@ install = "pip install -e .[dev]" [tool.hatch.envs.docs] dependencies = [ - "sphinx>=7.1.2,<8", - "sphinx_rtd_theme>=2.0.0", - "gitpython>=3.1.31", - "sphinx-copybutton>=0.5.2", + "sphinx>=9.0.4,<10", + "sphinx_rtd_theme>=3.1.0,<4", + "gitpython>=3.1.62,<4", + "sphinx-copybutton>=0.5.2,<1", ] [tool.hatch.envs.docs.scripts] @@ -84,7 +96,7 @@ build = "sphinx-build -b html docs/source docs/build" serve = "python -m http.server 8000 --directory docs/build" [tool.hatch.envs.debug] -dependencies = ["ipdb>=0.13.9", "line_profiler>=3.5.1"] +dependencies = ["ipdb>=0.13.13", "line_profiler>=5.0.2"] [[tool.hatch.envs.test.matrix]] python = ["3.11", "3.12", "3.13", "3.14"] @@ -97,6 +109,7 @@ cov = ["test-cov", "cov-report"] app = "python quickup.py" [tool.ruff] +target-version = "py311" line-length = 120 [tool.ruff.lint] diff --git a/quickup/cli/auth.py b/quickup/cli/auth.py index 61c9d42..f89d118 100644 --- a/quickup/cli/auth.py +++ b/quickup/cli/auth.py @@ -105,14 +105,19 @@ def _respond(self, status: int, message: str) -> None: self.send_response(status) self.send_header("Content-Type", "text/html") self.end_headers() + # NOTE: keep the emoji choice out of the f-string. pyupgrade corrupts + # multi-line f-strings that embed `{'x' if cond else 'y'}` with non-ASCII + # literals: it re-emits the literal with shifted offsets and appends junk + # to the closing quote on every run (pyupgrade 3.21.2, all --pyNN-plus tiers). + icon = "✅" if status == 200 else "❌" html = f"""