Skip to content

Commit b571bb9

Browse files
Use PathLike (#6876)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 30b375c commit b571bb9

File tree

6 files changed

+30
-41
lines changed

6 files changed

+30
-41
lines changed

aiohttp/web.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import asyncio
22
import logging
3+
import os
34
import socket
45
import sys
56
from argparse import ArgumentParser
67
from collections.abc import Iterable
78
from importlib import import_module
8-
from pathlib import Path
99
from typing import (
1010
Any,
1111
Awaitable,
@@ -22,6 +22,7 @@
2222
from .abc import AbstractAccessLogger
2323
from .helpers import AppKey as AppKey
2424
from .log import access_logger
25+
from .typedefs import PathLike
2526
from .web_app import Application as Application, CleanupError as CleanupError
2627
from .web_exceptions import (
2728
HTTPAccepted as HTTPAccepted,
@@ -293,7 +294,7 @@ async def _run_app(
293294
*,
294295
host: Optional[Union[str, HostSequence]] = None,
295296
port: Optional[int] = None,
296-
path: Optional[Union[str, Path]] = None,
297+
path: Union[PathLike, TypingIterable[PathLike], None] = None,
297298
sock: Optional[Union[socket.socket, TypingIterable[socket.socket]]] = None,
298299
shutdown_timeout: float = 60.0,
299300
keepalive_timeout: float = 75.0,
@@ -369,7 +370,7 @@ async def _run_app(
369370
)
370371

371372
if path is not None:
372-
if isinstance(path, (str, bytes, bytearray, memoryview, Path)):
373+
if isinstance(path, (str, os.PathLike)):
373374
sites.append(
374375
UnixSite(
375376
runner,
@@ -467,7 +468,7 @@ def run_app(
467468
debug: bool = False,
468469
host: Optional[Union[str, HostSequence]] = None,
469470
port: Optional[int] = None,
470-
path: Optional[Union[str, Path]] = None,
471+
path: Union[PathLike, TypingIterable[PathLike], None] = None,
471472
sock: Optional[Union[socket.socket, TypingIterable[socket.socket]]] = None,
472473
shutdown_timeout: float = 60.0,
473474
keepalive_timeout: float = 75.0,

aiohttp/web_fileresponse.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from . import hdrs
2222
from .abc import AbstractStreamWriter
2323
from .helpers import ETAG_ANY, ETag
24-
from .typedefs import LooseHeaders
24+
from .typedefs import LooseHeaders, PathLike
2525
from .web_exceptions import (
2626
HTTPNotModified,
2727
HTTPPartialContent,
@@ -47,18 +47,15 @@ class FileResponse(StreamResponse):
4747

4848
def __init__(
4949
self,
50-
path: Union[str, pathlib.Path],
50+
path: PathLike,
5151
chunk_size: int = 256 * 1024,
5252
status: int = 200,
5353
reason: Optional[str] = None,
5454
headers: Optional[LooseHeaders] = None,
5555
) -> None:
5656
super().__init__(status=status, reason=reason, headers=headers)
5757

58-
if isinstance(path, str):
59-
path = pathlib.Path(path)
60-
61-
self._path = path
58+
self._path = pathlib.Path(path)
6259
self._chunk_size = chunk_size
6360

6461
async def _sendfile_fallback(

aiohttp/web_runner.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
import signal
33
import socket
44
from abc import ABC, abstractmethod
5-
from pathlib import Path
6-
from typing import Any, List, Optional, Set, Type, Union
5+
from typing import Any, List, Optional, Set, Type
76

87
from yarl import URL
98

109
from .abc import AbstractAccessLogger, AbstractStreamWriter
1110
from .http_parser import RawRequestMessage
1211
from .streams import StreamReader
12+
from .typedefs import PathLike
1313
from .web_app import Application
1414
from .web_log import AccessLogger
1515
from .web_protocol import RequestHandler
@@ -142,7 +142,7 @@ class UnixSite(BaseSite):
142142
def __init__(
143143
self,
144144
runner: "BaseRunner",
145-
path: Union[str, Path],
145+
path: PathLike,
146146
*,
147147
shutdown_timeout: float = 60.0,
148148
ssl_context: Optional[SSLContext] = None,

aiohttp/web_urldispatcher.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -559,14 +559,12 @@ def __init__(
559559
def url_for( # type: ignore[override]
560560
self,
561561
*,
562-
filename: Union[str, Path],
562+
filename: PathLike,
563563
append_version: Optional[bool] = None,
564564
) -> URL:
565565
if append_version is None:
566566
append_version = self._append_version
567-
if isinstance(filename, Path):
568-
filename = str(filename)
569-
filename = filename.lstrip("/")
567+
filename = str(filename).lstrip("/")
570568

571569
url = URL.build(path=self._prefix, encoded=True)
572570
# filename is not encoded

docs/web_reference.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2846,7 +2846,8 @@ Utilities
28462846
:param path: file system path for HTTP server Unix domain socket.
28472847
A sequence of file system paths can be used to bind
28482848
multiple domain sockets. Listening on Unix domain
2849-
sockets is not supported by all operating systems, :class:`str` or :class:`pathlib.Path` .
2849+
sockets is not supported by all operating systems,
2850+
:class:`str`, :class:`pathlib.Path` or an iterable of these.
28502851

28512852
:param socket.socket sock: a preexisting socket object to accept connections on.
28522853
A sequence of socket objects can be passed.

tests/test_web_sendfile.py

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from pathlib import Path
12
from typing import Any
23
from unittest import mock
34

@@ -11,19 +12,17 @@ def test_using_gzip_if_header_present_and_file_available(loop: Any) -> None:
1112
"GET", "http://python.org/logo.png", headers={hdrs.ACCEPT_ENCODING: "gzip"}
1213
)
1314

14-
gz_filepath = mock.Mock()
15-
gz_filepath.open = mock.mock_open()
15+
gz_filepath = mock.create_autospec(Path, spec_set=True)
1616
gz_filepath.is_file.return_value = True
17-
gz_filepath.stat.return_value = mock.MagicMock()
1817
gz_filepath.stat.return_value.st_size = 1024
1918
gz_filepath.stat.return_value.st_mtime_ns = 1603733507222449291
2019

21-
filepath = mock.Mock()
20+
filepath = mock.create_autospec(Path, spec_set=True)
2221
filepath.name = "logo.png"
23-
filepath.open = mock.mock_open()
2422
filepath.with_name.return_value = gz_filepath
2523

2624
file_sender = FileResponse(filepath)
25+
file_sender._path = filepath
2726
file_sender._sendfile = make_mocked_coro(None) # type: ignore[assignment]
2827

2928
loop.run_until_complete(file_sender.prepare(request))
@@ -35,19 +34,17 @@ def test_using_gzip_if_header_present_and_file_available(loop: Any) -> None:
3534
def test_gzip_if_header_not_present_and_file_available(loop: Any) -> None:
3635
request = make_mocked_request("GET", "http://python.org/logo.png", headers={})
3736

38-
gz_filepath = mock.Mock()
39-
gz_filepath.open = mock.mock_open()
37+
gz_filepath = mock.create_autospec(Path, spec_set=True)
4038
gz_filepath.is_file.return_value = True
4139

42-
filepath = mock.Mock()
40+
filepath = mock.create_autospec(Path, spec_set=True)
4341
filepath.name = "logo.png"
44-
filepath.open = mock.mock_open()
4542
filepath.with_name.return_value = gz_filepath
46-
filepath.stat.return_value = mock.MagicMock()
4743
filepath.stat.return_value.st_size = 1024
4844
filepath.stat.return_value.st_mtime_ns = 1603733507222449291
4945

5046
file_sender = FileResponse(filepath)
47+
file_sender._path = filepath
5148
file_sender._sendfile = make_mocked_coro(None) # type: ignore[assignment]
5249

5350
loop.run_until_complete(file_sender.prepare(request))
@@ -59,19 +56,17 @@ def test_gzip_if_header_not_present_and_file_available(loop: Any) -> None:
5956
def test_gzip_if_header_not_present_and_file_not_available(loop: Any) -> None:
6057
request = make_mocked_request("GET", "http://python.org/logo.png", headers={})
6158

62-
gz_filepath = mock.Mock()
63-
gz_filepath.open = mock.mock_open()
59+
gz_filepath = mock.create_autospec(Path, spec_set=True)
6460
gz_filepath.is_file.return_value = False
6561

66-
filepath = mock.Mock()
62+
filepath = mock.create_autospec(Path, spec_set=True)
6763
filepath.name = "logo.png"
68-
filepath.open = mock.mock_open()
6964
filepath.with_name.return_value = gz_filepath
70-
filepath.stat.return_value = mock.MagicMock()
7165
filepath.stat.return_value.st_size = 1024
7266
filepath.stat.return_value.st_mtime_ns = 1603733507222449291
7367

7468
file_sender = FileResponse(filepath)
69+
file_sender._path = filepath
7570
file_sender._sendfile = make_mocked_coro(None) # type: ignore[assignment]
7671

7772
loop.run_until_complete(file_sender.prepare(request))
@@ -85,19 +80,17 @@ def test_gzip_if_header_present_and_file_not_available(loop: Any) -> None:
8580
"GET", "http://python.org/logo.png", headers={hdrs.ACCEPT_ENCODING: "gzip"}
8681
)
8782

88-
gz_filepath = mock.Mock()
89-
gz_filepath.open = mock.mock_open()
83+
gz_filepath = mock.create_autospec(Path, spec_set=True)
9084
gz_filepath.is_file.return_value = False
9185

92-
filepath = mock.Mock()
86+
filepath = mock.create_autospec(Path, spec_set=True)
9387
filepath.name = "logo.png"
94-
filepath.open = mock.mock_open()
9588
filepath.with_name.return_value = gz_filepath
96-
filepath.stat.return_value = mock.MagicMock()
9789
filepath.stat.return_value.st_size = 1024
9890
filepath.stat.return_value.st_mtime_ns = 1603733507222449291
9991

10092
file_sender = FileResponse(filepath)
93+
file_sender._path = filepath
10194
file_sender._sendfile = make_mocked_coro(None) # type: ignore[assignment]
10295

10396
loop.run_until_complete(file_sender.prepare(request))
@@ -109,14 +102,13 @@ def test_gzip_if_header_present_and_file_not_available(loop: Any) -> None:
109102
def test_status_controlled_by_user(loop: Any) -> None:
110103
request = make_mocked_request("GET", "http://python.org/logo.png", headers={})
111104

112-
filepath = mock.Mock()
105+
filepath = mock.create_autospec(Path, spec_set=True)
113106
filepath.name = "logo.png"
114-
filepath.open = mock.mock_open()
115-
filepath.stat.return_value = mock.MagicMock()
116107
filepath.stat.return_value.st_size = 1024
117108
filepath.stat.return_value.st_mtime_ns = 1603733507222449291
118109

119110
file_sender = FileResponse(filepath, status=203)
111+
file_sender._path = filepath
120112
file_sender._sendfile = make_mocked_coro(None) # type: ignore[assignment]
121113

122114
loop.run_until_complete(file_sender.prepare(request))

0 commit comments

Comments
 (0)