Skip to content

Commit 858b7e7

Browse files
authored
Merge pull request #21 from d-chris/develop
Fix UrlPath.exists and improve test coverage
2 parents 819de53 + 46bea60 commit 858b7e7

9 files changed

Lines changed: 112 additions & 36 deletions

File tree

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ repos:
77
- id: trailing-whitespace
88
- id: check-toml
99
- repo: https://github.com/tox-dev/pyproject-fmt
10-
rev: v2.4.3
10+
rev: v2.5.0
1111
hooks:
1212
- id: pyproject-fmt
1313
- repo: https://github.com/tox-dev/tox-ini-fmt
@@ -38,7 +38,7 @@ repos:
3838
- id: poetry-lock
3939
args: ["--no-update"]
4040
- repo: https://github.com/google/yamlfmt
41-
rev: v0.13.0
41+
rev: v0.14.0
4242
hooks:
4343
- id: yamlfmt
4444
- repo: https://github.com/PyCQA/flake8

pathlibutil/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,11 @@
55
from pathlibutil.path import Path, Register7zFormat
66
from pathlibutil.types import ByteInt, StatResult, TimeInt, byteint
77

8-
__all__ = ["Path", "Register7zFormat", "ByteInt", "byteint", "TimeInt", "StatResult"]
8+
__all__ = [
9+
"Path",
10+
"Register7zFormat",
11+
"ByteInt",
12+
"byteint",
13+
"TimeInt",
14+
"StatResult",
15+
]

pathlibutil/urlpath.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from dataclasses import asdict, dataclass, field
77
from functools import cached_property, wraps
88
from typing import Any, Dict, Optional, Tuple, TypeVar, Union
9+
from urllib.error import HTTPError
910

1011

1112
@dataclass
@@ -612,7 +613,14 @@ def exists(self, errors: bool = False, **kwargs) -> bool:
612613

613614
try:
614615
with urllib.request.urlopen(url, **kwargs) as response:
615-
return response.status == 200
616+
if response.status == 200:
617+
return True
618+
619+
raise HTTPError(
620+
url=url,
621+
code=response.status,
622+
message=response.reason,
623+
)
616624
except Exception as e:
617625
if errors is not False:
618626
raise FileNotFoundError(url) from e

poetry.lock

Lines changed: 17 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ documentation = "https://d-chris.github.io/pathlibutil"
2828

2929
[tool.poetry.dependencies]
3030
python = "^3.8.1"
31-
py7zr = { version = "^0.20.2", optional = true }
31+
py7zr = { version = ">=0.20.2", optional = true }
3232

3333
[tool.poetry.extras]
3434
7z = [ "py7zr" ]
@@ -76,3 +76,10 @@ addopts = [
7676
exclude_lines = [
7777
"^def normalize_url",
7878
]
79+
80+
[tool.coverage.run]
81+
omit = [
82+
"*/tests/*",
83+
"*/docs/*",
84+
"*/examples/*",
85+
]

tests/conftest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ def cls() -> Generator[Path, Any, Any]:
1616
yield Path
1717
Path.default_hash = hash
1818

19+
try:
20+
del Path._netuse
21+
except AttributeError:
22+
pass
23+
1924

2025
@pytest.fixture
2126
def file(cls) -> Path:

tests/test_json.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ def obj(file):
88
return [file, {1: file}, "string"]
99

1010

11+
def test_dump_raises():
12+
class Base:
13+
pass
14+
15+
with pytest.raises(TypeError):
16+
_ = dumps(Base())
17+
18+
1119
def test_dumps(obj):
1220

1321
result = dumps(obj)

tests/test_resolve.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ def mock_run(mocker):
3131

3232

3333
@pytest.fixture
34-
def path():
35-
return Path("file.txt")
34+
def path(cls):
35+
36+
yield cls("file.txt")
3637

3738

3839
def test_resolve_default(path, mock_resolve, mock_run):
@@ -43,6 +44,13 @@ def test_resolve_unctrue(path, mock_resolve, mock_run):
4344
assert path.resolve(unc=True) == Path("//server/temp/file.txt")
4445

4546

47+
def test_resolve_uncfalse_none(path, mock_run, mocker):
48+
49+
mocker.patch("re.finditer", side_effect=Exception)
50+
mocker.patch("pathlib.Path.resolve", return_value=path)
51+
assert path.resolve(unc=False).as_posix() == path.as_posix()
52+
53+
4654
@pytest.mark.skipif(os.name != "nt", reason="Windows only")
4755
def test_resolve_uncfalse(path, mock_resolve, mock_run):
4856
assert path.resolve(unc=False) == Path("T:/file.txt")

tests/test_urlpath.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,16 @@ def test_urlnetloc_normalize(netlocs):
142142
assert str(netloc) == result
143143

144144

145+
def test_urlnetloc_normalize_patch(mocker):
146+
147+
url = "www.ExamplE.com:443"
148+
149+
mocker.patch("re.search", return_value=None)
150+
netloc = UrlNetloc.from_netloc(url, normalize=False)
151+
152+
assert url != str(netloc)
153+
154+
145155
def test_urlnetloc_str():
146156
hostname = "www.example.com"
147157

@@ -267,22 +277,45 @@ def test_url_from():
267277
assert str(url) == "https://www.server.com/path/readme.pdf"
268278

269279

270-
def test_anchor():
271-
url = UrlPath("//server/root/path/readme.pdf")
280+
def test_url_from_exist(mocker, mock_openurl):
272281

273-
assert url.anchor == "//server/root"
282+
file = "//server/root/path/readme.pdf"
274283

284+
mocker.patch(
285+
"pathlib.Path.resolve",
286+
return_value=pathlib.Path(file),
287+
)
288+
if mock_openurl == 404:
289+
with pytest.raises(FileNotFoundError):
290+
_ = url_from(file, "https://www.server.com", strict=True)
291+
else:
292+
url = url_from(file, "https://www.server.com", strict=True)
293+
assert str(url) == "https://www.server.com/path/readme.pdf"
275294

276-
def test_with_anchor():
277-
url = UrlPath("//server/root/path/readme.pdf")
278295

279-
assert (
280-
url.with_anchor("//fubar", root=True).__str__()
281-
== "//fubar/root/path/readme.pdf"
282-
)
296+
@pytest.mark.parametrize(
297+
"url,result",
298+
[
299+
("//server/root/path/readme.pdf", "//server/root"),
300+
("//server/root/", "//server/root"),
301+
("//server/", "//server/"),
302+
],
303+
)
304+
def test_anchor(url, result):
305+
306+
assert UrlPath(url).anchor == result
283307

284308

285-
def test_fubar_anchor():
286-
url = UrlPath("//server/root/path/readme.pdf")
309+
@pytest.mark.parametrize(
310+
"anchor,root,result",
311+
[
312+
("//fubar", False, "//fubar/path/readme.pdf"),
313+
("//fubar", True, "//fubar/root/path/readme.pdf"),
314+
("//fubar/share", False, "//fubar/share/path/readme.pdf"),
315+
("//fubar/share", True, "//fubar/share/root/path/readme.pdf"),
316+
],
317+
)
318+
def test_with_anchor(anchor, root, result):
319+
url = UrlPath("//server/root/path/readme.pdf").with_anchor(anchor, root)
287320

288-
assert url.with_anchor("//fubar").__str__() == "//fubar/path/readme.pdf"
321+
assert str(url) == result

0 commit comments

Comments
 (0)