aio-libs / aio-libs/aiohttp

pathlib.Path-alike no longer works in 3.9.0 for web.FileResponse

Open
#7,928 4 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
16.5k
Forks
2.4k
Avg merge
17h 22m
Merged PRs (30d)
212

Description

### Describe the bug

I use `web.FileResponse` to respond with a file that is not really on the disk. This is done with a `Path` instance that implements the `pathlib.Path` interface. Much like the `zipfile.Path` in the standard library. (`zipfile.Path` has no `stat` yet, so it is a no-go anyway.)

With upgrade to 3.9.0, this no longer works, but it fails with file not found exception.

I see the change came in #7111, the backport of #6876. For no apparent reason, the condition to only replace str with `pathlib.Path` was changed to create `pathlib.Path` for any argument.

```
@@ -55,10 +55,7 @@ class FileResponse(StreamResponse):
) -> None:
super().__init__(status=status, reason=reason, headers=headers)

- if isinstance(path, str):
- path = pathlib.Path(path)
-
- self._path = path
+ self._path = pathlib.Path(path)
self._chunk_size = chunk_size
```

Python 3.12 is preparing for `pathlib.Path` to be subclassed more easily (see [whatsnew](https://docs.python.org/3/whatsnew/3.12.html#pathlib)). Whatever reasons there are to subclass, would also be broken by this kind of change.

Since this breaks something that used to work, I report this as a bug. As a new feature it would not require much. Only `Path` members `name`, `open`, `stat`, `with_name` and `is_file` for the value returned by `with_name`.

### To Reproduce

1. Subclass or implement own `pathlib.Path` like subclass.
2. Create instance.
3. Pass it to `web.FileResponse`.

### Expected behavior

Response created with the stat and file content of the `pathlib.Path`.

### Logs/tracebacks

```python-traceback
Traceback (most recent call last):
File "***/.venv310/lib/python3.10/site-packages/aiohttp/web_protocol.py", line 531, in start
resp, reset = await task
File "***/.venv310/lib/python3.10/site-packages/aiohttp/web_protocol.py", line 477, in _handle_request
reset = await self.finish_response(request, resp, start_time)
File "***/.venv310/lib/python3.10/site-packages/aiohttp/web_protocol.py", line 630, in finish_response
await prepare_meth(request)
File "***/.venv310/lib/python3.10/site-packages/aiohttp/web_fileresponse.py", line 139, in prepare
st: os.stat_result = await loop.run_in_executor(None, filepath.stat)
File "/usr/lib/python3.10/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/lib/python3.10/pathlib.py", line 1097, in stat
return self._accessor.stat(self, follow_symlinks=follow_symlinks)
FileNotFoundError: [Errno 2] No such file or directory: '***'
```

### Python Version

```console
$ python --version
Python 3.10.13
```

### aiohttp Version

```console
$ python -m pip show aiohttp
Name: aiohttp
Version: 3.9.1
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author:
Author-email:
License: Apache 2
Location: /home/kohtala/andritz/.venv310/lib/python3.10/site-packages
Requires: aiosignal, async-timeout, attrs, frozenlist, multidict, yarl
Required-by:
```

### multidict Version

```console
$ python -m pip show multidict
Name: multidict
Version: 6.0.4
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /home/kohtala/andritz/.venv310/lib/python3.10/site-packages
Requires:
Required-by: aiohttp, yarl
```

### yarl Version

```console
$ python -m pip show yarl
Name: yarl
Version: 1.9.3
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache-2.0
Location: /home/kohtala/andritz/.venv310/lib/python3.10/site-packages
Requires: idna, multidict
Required-by: aiohttp
```

### OS

```
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.6 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```

### Related component

Server

### Additional context

_No response_

### Code of Conduct

- [X] I agree to follow the aio-libs Code of Conduct

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.