diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8877a11..91ff355 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,10 +13,10 @@ jobs: permissions: id-token: write steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 with: - python-version: 3.13 + python-version: 3.14 - run: | python -m pip install --upgrade build python -m build diff --git a/.github/workflows/tests-macos.yml b/.github/workflows/tests-macos.yml index e6c5989..307c93f 100644 --- a/.github/workflows/tests-macos.yml +++ b/.github/workflows/tests-macos.yml @@ -7,13 +7,13 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14.0-rc.1"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/tests-ubuntu.yml b/.github/workflows/tests-ubuntu.yml index ea8d111..f706735 100644 --- a/.github/workflows/tests-ubuntu.yml +++ b/.github/workflows/tests-ubuntu.yml @@ -8,9 +8,6 @@ jobs: fail-fast: false matrix: include: - - python-version: "3.9" - env: - TOXENV: py - python-version: "3.10" env: TOXENV: py @@ -23,28 +20,28 @@ jobs: - python-version: "3.13" env: TOXENV: py - - python-version: "3.14.0-rc.1" + - python-version: "3.14" env: TOXENV: py # PyPy - - python-version: pypy3.10 - env: - TOXENV: pypy3 - python-version: pypy3.11 env: - TOXENV: pypy3 + TOXENV: py # checks - - python-version: "3.13" + - python-version: "3.14" env: TOXENV: twinecheck + - python-version: "3.14" + env: + TOXENV: typing steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/tests-windows.yml b/.github/workflows/tests-windows.yml index 3fec57d..cd0fefd 100644 --- a/.github/workflows/tests-windows.yml +++ b/.github/workflows/tests-windows.yml @@ -7,13 +7,13 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14.0-rc.1"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ea127bf..96e8793 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,13 +1,13 @@ exclude: tests/test_data repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.5 + rev: v0.14.4 hooks: - id: ruff-check args: [ --fix ] - id: ruff-format - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: end-of-file-fixer - id: trailing-whitespace diff --git a/pyproject.toml b/pyproject.toml index e128c2e..a3b6017 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,6 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -35,7 +34,7 @@ keywords = [ license = "BSD-3-Clause" license-files = ["LICENSE"] readme = "README.rst" -requires-python = ">=3.9" +requires-python = ">=3.10" [project.urls] Homepage = "https://github.com/scrapy/protego" @@ -65,10 +64,8 @@ regex = true [tool.coverage.run] branch = true -[tool.coverage.report] -exclude_also = [ - "if TYPE_CHECKING:", -] +[tool.mypy] +strict = true [[tool.mypy.overrides]] module = "tests.*" diff --git a/src/protego/_utils.py b/src/protego/_utils.py index 5502d27..8ca2828 100644 --- a/src/protego/_utils.py +++ b/src/protego/_utils.py @@ -45,10 +45,7 @@ def _unquote(url: str, ignore: str = "", errors: str = "replace") -> str: def _hexescape(char: str) -> str: """Escape char as RFC 2396 specifies""" - hex_repr = hex(ord(char))[2:].upper() - if len(hex_repr) == 1: - hex_repr = f"0{hex_repr}" - return f"%{hex_repr}" + return f"%{ord(char):02X}" def _quote_path(path: str) -> str: diff --git a/tests/test_protego.py b/tests/test_protego.py index 8ab4a30..245f97f 100644 --- a/tests/test_protego.py +++ b/tests/test_protego.py @@ -1012,7 +1012,7 @@ def test_disallow_target_url_path_is_missing(self): def test_bytestrings(self): content = b"User-Agent: FootBot\nDisallow: /something" - with pytest.raises(ValueError, match="Protego.parse expects str, got bytes"): + with pytest.raises(ValueError, match=r"Protego\.parse expects str, got bytes"): Protego.parse(content=content) # type: ignore[arg-type] def test_leading_double_slash_in_pattern(self): diff --git a/tox.ini b/tox.ini index 94babdc..fa8b136 100644 --- a/tox.ini +++ b/tox.ini @@ -4,15 +4,10 @@ envlist = py [testenv] deps = pytest - pytest-cov + pytest-cov >= 7.0.0 commands = pytest --cov=protego --cov-report=xml --cov-report= {posargs:tests} -[testenv:pypy3] -basepython = pypy3 -commands = - pypy -m pytest {posargs:tests} - [testenv:pre-commit] deps = pre-commit commands = pre-commit run --all-files --show-diff-on-failure @@ -21,8 +16,8 @@ skip_install = true [testenv:twinecheck] basepython = python3 deps = - twine==6.1.0 - build==1.2.2.post1 + twine==6.2.0 + build==1.3.0 commands = python -m build --sdist twine check dist/* @@ -30,8 +25,8 @@ commands = [testenv:typing] basepython = python3 deps = - mypy==1.17.0 + mypy==1.18.2 pytest scrapy==2.13.3 commands = - mypy --strict {posargs: src tests} + mypy {posargs: src tests}