starting phase `check'
Using pytest
============================= test session starts ==============================
platform linux -- Python 3.9.9, pytest-6.2.5, py-1.10.0, pluggy-0.13.1 -- /gnu/store/slsh0qjv5j68xda2bb6h8gsxwyi1j25a-python-wrapper-3.9.9/bin/python
cachedir: .pytest_cache
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/guix-build-python-asgi-csrf-0.9.drv-0/source/.hypothesis/examples')
rootdir: /tmp/guix-build-python-asgi-csrf-0.9.drv-0/source
plugins: hypothesis-6.0.2, asyncio-0.17.2, anyio-3.5.0
asyncio: mode=legacy
collecting ... collected 32 items
test_asgi_csrf.py::test_hello_world_app PASSED [ 3%]
test_asgi_csrf.py::test_signing_secret_if_none_provided PASSED [ 6%]
test_asgi_csrf.py::test_asgi_csrf_sets_cookie PASSED [ 9%]
test_asgi_csrf.py::test_asgi_csrf_modifies_existing_vary_header PASSED [ 12%]
test_asgi_csrf.py::test_asgi_csrf_sets_no_cookie_or_vary_if_page_has_no_form PASSED [ 15%]
test_asgi_csrf.py::test_vary_header_only_if_page_contains_csrftoken PASSED [ 18%]
test_asgi_csrf.py::test_headers_passed_through_correctly PASSED [ 21%]
test_asgi_csrf.py::test_asgi_csrf_does_not_set_cookie_if_one_sent PASSED [ 25%]
test_asgi_csrf.py::test_prevents_post_if_cookie_not_sent_in_post PASSED [ 28%]
test_asgi_csrf.py::test_allows_post_if_cookie_duplicated_in_header PASSED [ 31%]
test_asgi_csrf.py::test_allows_post_if_cookie_duplicated_in_post_data PASSED [ 34%]
test_asgi_csrf.py::test_multipart FAILED [ 37%]
test_asgi_csrf.py::test_multipart_failure_wrong_token FAILED [ 40%]
test_asgi_csrf.py::test_multipart_failure_missing_token PASSED [ 43%]
test_asgi_csrf.py::test_multipart_failure_file_comes_before_token PASSED [ 46%]
test_asgi_csrf.py::test_post_with_authorization[Bearer xxx-200] PASSED [ 50%]
test_asgi_csrf.py::test_post_with_authorization[Basic xxx-403] PASSED [ 53%]
test_asgi_csrf.py::test_no_cookies_skips_check_unless_path_required[cookies0-/-200] PASSED [ 56%]
test_asgi_csrf.py::test_no_cookies_skips_check_unless_path_required[cookies1-/-403] PASSED [ 59%]
test_asgi_csrf.py::test_no_cookies_skips_check_unless_path_required[cookies2-/login-403] PASSED [ 62%]
test_asgi_csrf.py::test_no_cookies_skips_check_unless_path_required[cookies3-/login-403] PASSED [ 65%]
test_asgi_csrf.py::test_skip_if_scope[cookies0-/-200] PASSED [ 68%]
test_asgi_csrf.py::test_skip_if_scope[cookies1-/-403] PASSED [ 71%]
test_asgi_csrf.py::test_skip_if_scope[cookies2-/api/-200] PASSED [ 75%]
test_asgi_csrf.py::test_skip_if_scope[cookies3-/api/-200] PASSED [ 78%]
test_asgi_csrf.py::test_skip_if_scope[cookies4-/api/foo-200] PASSED [ 81%]
test_asgi_csrf.py::test_skip_if_scope[cookies5-/api/foo-200] PASSED [ 84%]
test_asgi_csrf.py::test_always_set_cookie[True] PASSED [ 87%]
test_asgi_csrf.py::test_always_set_cookie[False] PASSED [ 90%]
test_asgi_csrf.py::test_always_set_cookie_unless_cookie_is_set[True] PASSED [ 93%]
test_asgi_csrf.py::test_always_set_cookie_unless_cookie_is_set[False] PASSED [ 96%]
test_asgi_csrf.py::test_asgi_lifespan PASSED [100%]
=================================== FAILURES ===================================
________________________________ test_multipart ________________________________
csrftoken = 'InRva2VuIg.49BUIh1HVBjcyCpg_4018iFDFdY'
@pytest.mark.asyncio
async def test_multipart(csrftoken):
async with httpx.AsyncClient(
app=asgi_csrf(hello_world_app, signing_secret=SECRET)
) as client:
> response = await client.post(
"http://localhost/",
data={"csrftoken": csrftoken},
files={"csv": ("data.csv", "blah,foo\n1,2", "text/csv")},
cookies={"csrftoken": csrftoken},
)
test_asgi_csrf.py:186:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_client.py:1842: in post
return await self.request(
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_client.py:1514: in request
request = self.build_request(
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_client.py:356: in build_request
return Request(
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_models.py:336: in __init__
headers, stream = encode_request(content, data, files, json)
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_content.py:210: in encode_request
return encode_multipart_data(data or {}, files, boundary)
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_content.py:155: in encode_multipart_data
multipart = MultipartStream(data=data, files=files, boundary=boundary)
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_multipart.py:188: in __init__
self.fields = list(self._iter_fields(data, files))
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_multipart.py:202: in _iter_fields
yield FileField(name=name, value=value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <httpx._multipart.FileField object at 0x7ffff5856f40>, name = 'csv'
value = ('data.csv', 'blah,foo\n1,2', 'text/csv')
def __init__(self, name: str, value: FileTypes) -> None:
self.name = name
fileobj: FileContent
headers: typing.Dict[str, str] = {}
content_type: typing.Optional[str] = None
# This large tuple based API largely mirror's requests' API
# It would be good to think of better APIs for this that we could include in httpx 2.0
# since variable length tuples (especially of 4 elements) are quite unwieldly
if isinstance(value, tuple):
if len(value) == 2:
# neither the 3rd parameter (content_type) nor the 4th (headers) was included
filename, fileobj = value # type: ignore
elif len(value) == 3:
filename, fileobj, content_type = value # type: ignore
else:
# all 4 parameters included
filename, fileobj, content_type, headers = value # type: ignore
else:
filename = Path(str(getattr(value, "name", "upload"))).name
fileobj = value
if content_type is None:
content_type = guess_content_type(filename)
has_content_type_header = any("content-type" in key.lower() for key in headers)
if content_type is not None and not has_content_type_header:
# note that unlike requests, we ignore the content_type
# provided in the 3rd tuple element if it is also included in the headers
# requests does the opposite (it overwrites the header with the 3rd tuple element)
headers["Content-Type"] = content_type
if isinstance(fileobj, (str, io.StringIO)):
> raise TypeError(f"Expected bytes or bytes-like object got: {type(fileobj)}")
E TypeError: Expected bytes or bytes-like object got: <class 'str'>
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_multipart.py:111: TypeError
______________________ test_multipart_failure_wrong_token ______________________
csrftoken = 'InRva2VuIg.49BUIh1HVBjcyCpg_4018iFDFdY'
@pytest.mark.asyncio
async def test_multipart_failure_wrong_token(csrftoken):
async with httpx.AsyncClient(
app=asgi_csrf(hello_world_app, signing_secret=SECRET)
) as client:
> response = await client.post(
"http://localhost/",
data={"csrftoken": csrftoken},
files={"csv": ("data.csv", "blah,foo\n1,2", "text/csv")},
cookies={"csrftoken": csrftoken[:-1]},
)
test_asgi_csrf.py:201:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_client.py:1842: in post
return await self.request(
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_client.py:1514: in request
request = self.build_request(
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_client.py:356: in build_request
return Request(
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_models.py:336: in __init__
headers, stream = encode_request(content, data, files, json)
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_content.py:210: in encode_request
return encode_multipart_data(data or {}, files, boundary)
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_content.py:155: in encode_multipart_data
multipart = MultipartStream(data=data, files=files, boundary=boundary)
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_multipart.py:188: in __init__
self.fields = list(self._iter_fields(data, files))
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_multipart.py:202: in _iter_fields
yield FileField(name=name, value=value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <httpx._multipart.FileField object at 0x7ffff5587d00>, name = 'csv'
value = ('data.csv', 'blah,foo\n1,2', 'text/csv')
def __init__(self, name: str, value: FileTypes) -> None:
self.name = name
fileobj: FileContent
headers: typing.Dict[str, str] = {}
content_type: typing.Optional[str] = None
# This large tuple based API largely mirror's requests' API
# It would be good to think of better APIs for this that we could include in httpx 2.0
# since variable length tuples (especially of 4 elements) are quite unwieldly
if isinstance(value, tuple):
if len(value) == 2:
# neither the 3rd parameter (content_type) nor the 4th (headers) was included
filename, fileobj = value # type: ignore
elif len(value) == 3:
filename, fileobj, content_type = value # type: ignore
else:
# all 4 parameters included
filename, fileobj, content_type, headers = value # type: ignore
else:
filename = Path(str(getattr(value, "name", "upload"))).name
fileobj = value
if content_type is None:
content_type = guess_content_type(filename)
has_content_type_header = any("content-type" in key.lower() for key in headers)
if content_type is not None and not has_content_type_header:
# note that unlike requests, we ignore the content_type
# provided in the 3rd tuple element if it is also included in the headers
# requests does the opposite (it overwrites the header with the 3rd tuple element)
headers["Content-Type"] = content_type
if isinstance(fileobj, (str, io.StringIO)):
> raise TypeError(f"Expected bytes or bytes-like object got: {type(fileobj)}")
E TypeError: Expected bytes or bytes-like object got: <class 'str'>
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_multipart.py:111: TypeError
=============================== warnings summary ===============================
../../../gnu/store/hm97w6qgapy8x7i341mhcdn7j3jxfb42-python-pytest-asyncio-0.17.2/lib/python3.9/site-packages/pytest_asyncio/plugin.py:191
/gnu/store/hm97w6qgapy8x7i341mhcdn7j3jxfb42-python-pytest-asyncio-0.17.2/lib/python3.9/site-packages/pytest_asyncio/plugin.py:191: DeprecationWarning: The 'asyncio_mode' default value will change to 'strict' in future, please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' in pytest configuration file.
config.issue_config_time_warning(LEGACY_MODE, stacklevel=2)
test_asgi_csrf.py::test_signing_secret_if_none_provided
/gnu/store/hm97w6qgapy8x7i341mhcdn7j3jxfb42-python-pytest-asyncio-0.17.2/lib/python3.9/site-packages/pytest_asyncio/plugin.py:317: DeprecationWarning: '@pytest.fixture' is applied to <fixture monkeypatch, file=/gnu/store/7frqm5ijy66f81hr8i1j6791k84lds9w-python-pytest-6.2.5/lib/python3.9/site-packages/_pytest/monkeypatch.py, line=29> in 'legacy' mode, please replace it with '@pytest_asyncio.fixture' as a preparation for switching to 'strict' mode (or use 'auto' mode to seamlessly handle all these fixtures as asyncio-driven).
warnings.warn(
test_asgi_csrf.py::test_multipart_failure_file_comes_before_token
/gnu/store/993zn04mbdjxvng820d3zmvs0z43j3x5-python-httpx-0.23.0/lib/python3.9/site-packages/httpx/_content.py:204: DeprecationWarning: Use 'content=<...>' to upload raw bytes/text content.
warnings.warn(message, DeprecationWarning)
-- Docs: https://docs.pytest.org/en/stable/warnings.html
=========================== short test summary info ============================
FAILED test_asgi_csrf.py::test_multipart - TypeError: Expected bytes or bytes...
FAILED test_asgi_csrf.py::test_multipart_failure_wrong_token - TypeError: Exp...
=================== 2 failed, 30 passed, 3 warnings in 0.37s ===================
error: in phase 'check': uncaught exception:
%exception #<&invoke-error program: "/gnu/store/7frqm5ijy66f81hr8i1j6791k84lds9w-python-pytest-6.2.5/bin/pytest" arguments: ("-vv") exit-status: 1 term-signal: #f stop-signal: #f>
phase `check' failed after 0.7 seconds
I suspect it must have to do with the version of httpx used, which is 0.23.0 in Guix:
Thank you.