Skip to content

Commit e1a361f

Browse files
authored
Add non-Linux CI jobs. (#240)
1 parent cc15435 commit e1a361f

File tree

10 files changed

+96
-25
lines changed

10 files changed

+96
-25
lines changed

.github/workflows/build.yml renamed to .github/workflows/checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Build
1+
name: Checks
22

33
on:
44
push:

.github/workflows/tests-macos.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: macOS
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- master
10+
11+
jobs:
12+
tests:
13+
14+
runs-on: ubuntu-latest
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Set up Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
28+
- name: Run tests
29+
run: |
30+
pip install --upgrade pip
31+
pip install --upgrade tox
32+
tox -e py
33+
34+
- name: Upload coverage report
35+
uses: codecov/codecov-action@v5

.github/workflows/tests.yml renamed to .github/workflows/tests-ubuntu.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Tests
1+
name: Ubuntu
22

33
on:
44
push:

.github/workflows/tests-windows.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Windows
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- master
10+
11+
jobs:
12+
tests:
13+
14+
runs-on: windows-latest
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Set up Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
28+
- name: Run tests
29+
run: |
30+
pip install --upgrade pip
31+
pip install --upgrade tox
32+
tox -e py
33+
34+
- name: Upload coverage report
35+
uses: codecov/codecov-action@v5

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: v0.9.3
3+
rev: v0.11.2
44
hooks:
55
- id: ruff
66
args: [ --fix ]

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ check_untyped_defs = true
2727
[[tool.mypy.overrides]]
2828
# All non-tests functions must be typed.
2929
module = "w3lib.*"
30-
disallow_untyped_defs = true
30+
allow_untyped_defs = false
3131

3232
[[tool.mypy.overrides]]
3333
# Allow test functions to be untyped
3434
module = "tests.*"
35-
disallow_untyped_defs = false
35+
allow_untyped_defs = true
3636

3737
[tool.pylint.MASTER]
3838
persistent = "no"
@@ -60,6 +60,7 @@ disable = [
6060
"too-many-positional-arguments",
6161
"too-many-public-methods",
6262
"unused-argument",
63+
"unused-import",
6364
"unused-variable",
6465
]
6566

tests/test_url.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ def test_url_query_cleaner_keep_fragments(self):
10701070
def test_path_to_file_uri(self):
10711071
if os.name == "nt":
10721072
assert (
1073-
path_to_file_uri(r"C:\\windows\clock.avi")
1073+
path_to_file_uri(r"C:\windows\clock.avi")
10741074
== "file:///C:/windows/clock.avi"
10751075
)
10761076
else:
@@ -1079,13 +1079,13 @@ def test_path_to_file_uri(self):
10791079
fn = "test.txt"
10801080
x = path_to_file_uri(fn)
10811081
assert x.startswith("file:///")
1082-
assert file_uri_to_path(x).lower() == str(Path(fn).resolve()).lower()
1082+
assert file_uri_to_path(x).lower() == str(Path(fn).absolute()).lower()
10831083

10841084
def test_file_uri_to_path(self):
10851085
if os.name == "nt":
10861086
assert (
10871087
file_uri_to_path("file:///C:/windows/clock.avi")
1088-
== r"C:\\windows\clock.avi"
1088+
== r"C:\windows\clock.avi"
10891089
)
10901090
uri = "file:///C:/windows/clock.avi"
10911091
uri2 = path_to_file_uri(file_uri_to_path(uri))
@@ -1101,9 +1101,7 @@ def test_file_uri_to_path(self):
11011101

11021102
def test_any_to_uri(self):
11031103
if os.name == "nt":
1104-
assert (
1105-
any_to_uri(r"C:\\windows\clock.avi") == "file:///C:/windows/clock.avi"
1106-
)
1104+
assert any_to_uri(r"C:\windows\clock.avi") == "file:///C:/windows/clock.avi"
11071105
else:
11081106
assert any_to_uri("/some/path.txt") == "file:///some/path.txt"
11091107
assert any_to_uri("file:///some/path.txt") == "file:///some/path.txt"

tox.ini

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,15 @@ commands =
2020
[testenv:typing]
2121
basepython = python3
2222
deps =
23-
# mypy would error if pytest (or its stub) not found
2423
pytest
25-
mypy==1.14.1
24+
mypy==1.15.0
2625
commands =
2726
mypy --strict {posargs: w3lib tests}
2827

2928
[testenv:pylint]
3029
deps =
3130
{[testenv]deps}
32-
pylint==3.3.3
31+
pylint==3.3.6
3332
commands =
3433
pylint conftest.py docs setup.py tests w3lib
3534

w3lib/encoding.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
import encodings
99
import re
1010
from re import Match
11-
from typing import Callable, cast
11+
from typing import TYPE_CHECKING, Callable, cast
1212

1313
import w3lib.util
14-
from w3lib._types import AnyUnicodeError
14+
15+
if TYPE_CHECKING:
16+
from w3lib._types import AnyUnicodeError
1517

1618
_HEADER_ENCODING_RE = re.compile(r"charset=([\w-]+)", re.IGNORECASE)
1719

@@ -136,7 +138,7 @@ def _c18n_encoding(encoding: str) -> str:
136138
encoding aliases
137139
"""
138140
normed = encodings.normalize_encoding(encoding).lower()
139-
return cast(str, encodings.aliases.aliases.get(normed, normed))
141+
return cast("str", encodings.aliases.aliases.get(normed, normed))
140142

141143

142144
def resolve_encoding(encoding_alias: str) -> str | None:
@@ -201,7 +203,7 @@ def read_bom(data: bytes) -> tuple[None, None] | tuple[str, bytes]:
201203
# Python decoder doesn't follow unicode standard when handling
202204
# bad utf-8 encoded strings. see http://bugs.python.org/issue8271
203205
codecs.register_error(
204-
"w3lib_replace", lambda exc: ("\ufffd", cast(AnyUnicodeError, exc).end)
206+
"w3lib_replace", lambda exc: ("\ufffd", cast("AnyUnicodeError", exc).end)
205207
)
206208

207209

@@ -283,7 +285,7 @@ def html_to_unicode(
283285
'''
284286
bom_enc, bom = read_bom(html_body_str)
285287
if bom_enc is not None:
286-
bom = cast(bytes, bom)
288+
bom = cast("bytes", bom)
287289
return bom_enc, to_unicode(html_body_str[len(bom) :], bom_enc)
288290

289291
enc = http_content_type_encoding(content_type_header)

w3lib/url.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,18 @@
3131
from urllib.request import pathname2url, url2pathname
3232

3333
from ._infra import _ASCII_TAB_OR_NEWLINE, _C0_CONTROL_OR_SPACE
34-
from ._types import AnyUnicodeError
3534
from ._url import _SPECIAL_SCHEMES
3635
from .util import to_unicode
3736

3837
if TYPE_CHECKING:
3938
from collections.abc import Sequence
4039

40+
from ._types import AnyUnicodeError
41+
4142

4243
# error handling function for bytes-to-Unicode decoding errors with URLs
4344
def _quote_byte(error: UnicodeError) -> tuple[str, int]:
44-
error = cast(AnyUnicodeError, error)
45+
error = cast("AnyUnicodeError", error)
4546
return (to_unicode(quote(error.object[error.start : error.end])), error.end)
4647

4748

@@ -320,8 +321,8 @@ def url_query_cleaner(
320321
if isinstance(parameterlist, (str, bytes)):
321322
parameterlist = [parameterlist]
322323
url, fragment = urldefrag(url)
323-
url = cast(str, url)
324-
fragment = cast(str, fragment)
324+
url = cast("str", url)
325+
fragment = cast("str", fragment)
325326
base, _, query = url.partition("?")
326327
seen = set()
327328
querylist = []
@@ -400,7 +401,7 @@ def path_to_file_uri(path: str | os.PathLike[str]) -> str:
400401
"""Convert local filesystem path to legal File URIs as described in:
401402
http://en.wikipedia.org/wiki/File_URI_scheme
402403
"""
403-
x = pathname2url(str(Path(path).resolve()))
404+
x = pathname2url(str(Path(path).absolute()))
404405
return f"file:///{x.lstrip('/')}"
405406

406407

@@ -697,7 +698,7 @@ def parse_qsl_to_bytes(
697698
# (at https://hg.python.org/cpython/rev/c38ac7ab8d9a)
698699
# except for the unquote(s, encoding, errors) calls replaced
699700
# with unquote_to_bytes(s)
700-
coerce_args = cast(Callable[..., tuple[str, Callable[..., bytes]]], _coerce_args)
701+
coerce_args = cast("Callable[..., tuple[str, Callable[..., bytes]]]", _coerce_args)
701702
qs, _coerce_result = coerce_args(qs)
702703
pairs = [s2 for s1 in qs.split("&") for s2 in s1.split(";")]
703704
r = []

0 commit comments

Comments
 (0)