python-multipart 0.0.20__tar.gz → 0.0.22__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_multipart-0.0.20 → python_multipart-0.0.22}/CHANGELOG.md +8 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/PKG-INFO +4 -4
- {python_multipart-0.0.20 → python_multipart-0.0.22}/pyproject.toml +6 -6
- {python_multipart-0.0.20 → python_multipart-0.0.22}/python_multipart/__init__.py +1 -1
- {python_multipart-0.0.20 → python_multipart-0.0.22}/python_multipart/decoders.py +1 -1
- {python_multipart-0.0.20 → python_multipart-0.0.22}/python_multipart/multipart.py +11 -10
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/compat.py +2 -1
- python_multipart-0.0.22/tests/test_file.py +26 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_multipart.py +5 -2
- {python_multipart-0.0.20 → python_multipart-0.0.22}/.gitignore +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/LICENSE.txt +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/README.md +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/multipart/__init__.py +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/multipart/decoders.py +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/multipart/exceptions.py +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/multipart/multipart.py +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/python_multipart/exceptions.py +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/python_multipart/py.typed +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/__init__.py +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CRLF_in_header.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CRLF_in_header.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CR_in_header.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CR_in_header.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CR_in_header_value.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CR_in_header_value.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary_without_CR.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary_without_CR.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary_without_LF.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary_without_LF.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary_without_final_hyphen.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary_without_final_hyphen.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_end_of_headers.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_end_of_headers.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_header_char.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_header_char.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_initial_boundary.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_initial_boundary.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/base64_encoding.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/base64_encoding.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/empty_header.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/empty_header.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/empty_message.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/empty_message.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/empty_message_with_bad_end.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/empty_message_with_bad_end.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/header_with_number.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/header_with_number.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/mixed_plain_and_base64_encoding.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/mixed_plain_and_base64_encoding.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/multiple_fields.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/multiple_fields.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/multiple_files.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/multiple_files.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/quoted_printable_encoding.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/quoted_printable_encoding.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_blocks.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_blocks.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_longer.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_longer.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_single_file.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_single_file.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_with_leading_newlines.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_with_leading_newlines.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_file.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_file.yaml +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/utf8_filename.http +0 -0
- {python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/utf8_filename.yaml +0 -0
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.22 (2026-01-25)
|
|
4
|
+
|
|
5
|
+
* Drop directory path from filename in `File` [9433f4b](https://github.com/Kludex/python-multipart/commit/9433f4bbc9652bdde82bbe380984e32f8cfc89c4).
|
|
6
|
+
|
|
7
|
+
## 0.0.21 (2025-12-17)
|
|
8
|
+
|
|
9
|
+
* Add support for Python 3.14 and drop EOL 3.8 and 3.9 [#216](https://github.com/Kludex/python-multipart/pull/216).
|
|
10
|
+
|
|
3
11
|
## 0.0.20 (2024-12-16)
|
|
4
12
|
|
|
5
13
|
* Handle messages containing only end boundary [#142](https://github.com/Kludex/python-multipart/pull/142).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-multipart
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.22
|
|
4
4
|
Summary: A streaming multipart parser for Python
|
|
5
5
|
Project-URL: Homepage, https://github.com/Kludex/python-multipart
|
|
6
6
|
Project-URL: Documentation, https://kludex.github.io/python-multipart/
|
|
@@ -16,13 +16,13 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
18
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
24
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
|
|
28
28
|
# [Python-Multipart](https://kludex.github.io/python-multipart/)
|
|
@@ -8,7 +8,7 @@ dynamic = ["version"]
|
|
|
8
8
|
description = "A streaming multipart parser for Python"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
12
|
authors = [
|
|
13
13
|
{ name = "Andrew Dunham", email = "andrew@du.nham.ca" },
|
|
14
14
|
{ name = "Marcelo Trylesinski", email = "marcelotryle@gmail.com" },
|
|
@@ -21,17 +21,17 @@ classifiers = [
|
|
|
21
21
|
'Operating System :: OS Independent',
|
|
22
22
|
'Programming Language :: Python :: 3 :: Only',
|
|
23
23
|
'Programming Language :: Python :: 3',
|
|
24
|
-
'Programming Language :: Python :: 3.8',
|
|
25
|
-
'Programming Language :: Python :: 3.9',
|
|
26
24
|
'Programming Language :: Python :: 3.10',
|
|
27
25
|
'Programming Language :: Python :: 3.11',
|
|
28
26
|
'Programming Language :: Python :: 3.12',
|
|
27
|
+
'Programming Language :: Python :: 3.13',
|
|
28
|
+
'Programming Language :: Python :: 3.14',
|
|
29
29
|
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
30
30
|
]
|
|
31
31
|
dependencies = []
|
|
32
32
|
|
|
33
|
-
[
|
|
34
|
-
dev
|
|
33
|
+
[dependency-groups]
|
|
34
|
+
dev = [
|
|
35
35
|
"atomicwrites==1.4.1",
|
|
36
36
|
"attrs==23.2.0",
|
|
37
37
|
"coverage==7.4.4",
|
|
@@ -44,7 +44,7 @@ dev-dependencies = [
|
|
|
44
44
|
"PyYAML==6.0.1",
|
|
45
45
|
"invoke==2.2.0",
|
|
46
46
|
"pytest-timeout==2.3.1",
|
|
47
|
-
"ruff==0.
|
|
47
|
+
"ruff==0.11.7",
|
|
48
48
|
"mypy",
|
|
49
49
|
"types-PyYAML",
|
|
50
50
|
"atheris==2.3.0; python_version <= '3.11'",
|
|
@@ -15,9 +15,8 @@ from .decoders import Base64Decoder, QuotedPrintableDecoder
|
|
|
15
15
|
from .exceptions import FileError, FormParserError, MultipartParseError, QuerystringParseError
|
|
16
16
|
|
|
17
17
|
if TYPE_CHECKING: # pragma: no cover
|
|
18
|
-
from
|
|
19
|
-
|
|
20
|
-
from typing_extensions import TypeAlias
|
|
18
|
+
from collections.abc import Callable
|
|
19
|
+
from typing import Any, Literal, Protocol, TypeAlias, TypedDict
|
|
21
20
|
|
|
22
21
|
class SupportsRead(Protocol):
|
|
23
22
|
def read(self, __n: int) -> bytes: ...
|
|
@@ -332,7 +331,7 @@ class Field:
|
|
|
332
331
|
else:
|
|
333
332
|
v = repr(self.value)
|
|
334
333
|
|
|
335
|
-
return "{}(field_name={!r}, value={})"
|
|
334
|
+
return f"{self.__class__.__name__}(field_name={self.field_name!r}, value={v})"
|
|
336
335
|
|
|
337
336
|
|
|
338
337
|
class File:
|
|
@@ -376,7 +375,9 @@ class File:
|
|
|
376
375
|
|
|
377
376
|
# Split the extension from the filename.
|
|
378
377
|
if file_name is not None:
|
|
379
|
-
|
|
378
|
+
# Extract just the basename to avoid directory traversal
|
|
379
|
+
basename = os.path.basename(file_name)
|
|
380
|
+
base, ext = os.path.splitext(basename)
|
|
380
381
|
self._file_base = base
|
|
381
382
|
self._ext = ext
|
|
382
383
|
|
|
@@ -570,7 +571,7 @@ class File:
|
|
|
570
571
|
self._fileobj.close()
|
|
571
572
|
|
|
572
573
|
def __repr__(self) -> str:
|
|
573
|
-
return "{}(file_name={!r}, field_name={!r})"
|
|
574
|
+
return f"{self.__class__.__name__}(file_name={self.file_name!r}, field_name={self.field_name!r})"
|
|
574
575
|
|
|
575
576
|
|
|
576
577
|
class BaseParser:
|
|
@@ -1241,7 +1242,7 @@ class MultipartParser(BaseParser):
|
|
|
1241
1242
|
elif state == MultipartState.HEADER_VALUE_ALMOST_DONE:
|
|
1242
1243
|
# The last character should be a LF. If not, it's an error.
|
|
1243
1244
|
if c != LF:
|
|
1244
|
-
msg = "Did not find LF character at end of header
|
|
1245
|
+
msg = f"Did not find LF character at end of header (found {c!r})"
|
|
1245
1246
|
self.logger.warning(msg)
|
|
1246
1247
|
e = MultipartParseError(msg)
|
|
1247
1248
|
e.offset = i
|
|
@@ -1715,7 +1716,7 @@ class FormParser:
|
|
|
1715
1716
|
else:
|
|
1716
1717
|
self.logger.warning("Unknown Content-Transfer-Encoding: %r", transfer_encoding)
|
|
1717
1718
|
if self.config["UPLOAD_ERROR_ON_BAD_CTE"]:
|
|
1718
|
-
raise FormParserError('Unknown Content-Transfer-Encoding "{!r}"'
|
|
1719
|
+
raise FormParserError(f'Unknown Content-Transfer-Encoding "{transfer_encoding!r}"')
|
|
1719
1720
|
else:
|
|
1720
1721
|
# If we aren't erroring, then we just treat this as an
|
|
1721
1722
|
# unencoded Content-Transfer-Encoding.
|
|
@@ -1746,7 +1747,7 @@ class FormParser:
|
|
|
1746
1747
|
|
|
1747
1748
|
else:
|
|
1748
1749
|
self.logger.warning("Unknown Content-Type: %r", content_type)
|
|
1749
|
-
raise FormParserError("Unknown Content-Type: {}"
|
|
1750
|
+
raise FormParserError(f"Unknown Content-Type: {content_type}")
|
|
1750
1751
|
|
|
1751
1752
|
self.parser = parser
|
|
1752
1753
|
|
|
@@ -1776,7 +1777,7 @@ class FormParser:
|
|
|
1776
1777
|
self.parser.close()
|
|
1777
1778
|
|
|
1778
1779
|
def __repr__(self) -> str:
|
|
1779
|
-
return "{}(content_type={!r}, parser={!r})"
|
|
1780
|
+
return f"{self.__class__.__name__}(content_type={self.content_type!r}, parser={self.parser!r})"
|
|
1780
1781
|
|
|
1781
1782
|
|
|
1782
1783
|
def create_form_parser(
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from python_multipart.multipart import File
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_upload_dir_with_leading_slash_in_filename(tmp_path: Path) -> None:
|
|
7
|
+
upload_dir = tmp_path / "upload"
|
|
8
|
+
upload_dir.mkdir()
|
|
9
|
+
|
|
10
|
+
# When the file_name provided has a leading slash, we should only use the basename.
|
|
11
|
+
# This is to avoid directory traversal.
|
|
12
|
+
to_upload = tmp_path / "foo.txt"
|
|
13
|
+
|
|
14
|
+
file = File(
|
|
15
|
+
bytes(to_upload),
|
|
16
|
+
config={
|
|
17
|
+
"UPLOAD_DIR": bytes(upload_dir),
|
|
18
|
+
"UPLOAD_KEEP_FILENAME": True,
|
|
19
|
+
"UPLOAD_KEEP_EXTENSIONS": True,
|
|
20
|
+
"MAX_MEMORY_FILE_SIZE": 10,
|
|
21
|
+
},
|
|
22
|
+
)
|
|
23
|
+
file.write(b"123456789012")
|
|
24
|
+
assert not file.in_memory
|
|
25
|
+
assert Path(upload_dir / "foo.txt").exists()
|
|
26
|
+
assert Path(upload_dir / "foo.txt").read_bytes() == b"123456789012"
|
|
@@ -37,7 +37,8 @@ from python_multipart.multipart import (
|
|
|
37
37
|
from .compat import parametrize, parametrize_class
|
|
38
38
|
|
|
39
39
|
if TYPE_CHECKING:
|
|
40
|
-
from
|
|
40
|
+
from collections.abc import Iterator
|
|
41
|
+
from typing import Any, TypedDict
|
|
41
42
|
|
|
42
43
|
from python_multipart.multipart import FieldProtocol, FileConfig, FileProtocol
|
|
43
44
|
|
|
@@ -1069,7 +1070,9 @@ class TestFormParser(unittest.TestCase):
|
|
|
1069
1070
|
|
|
1070
1071
|
self.make("boundary")
|
|
1071
1072
|
data = b"--Boundary\r\nfoobar"
|
|
1072
|
-
with self.assertRaisesRegex(
|
|
1073
|
+
with self.assertRaisesRegex(
|
|
1074
|
+
MultipartParseError, "Expected boundary character {!r}, got {!r}".format(b"b"[0], b"B"[0])
|
|
1075
|
+
):
|
|
1073
1076
|
self.f.write(data)
|
|
1074
1077
|
|
|
1075
1078
|
def test_octet_stream(self) -> None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CRLF_in_header.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CRLF_in_header.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CR_in_header_value.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/CR_in_header_value.yaml
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/almost_match_boundary.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_end_of_headers.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_end_of_headers.yaml
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_header_char.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_header_char.yaml
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_initial_boundary.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/bad_initial_boundary.yaml
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/base64_encoding.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/base64_encoding.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/header_with_number.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/header_with_number.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/multiple_fields.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/multiple_fields.yaml
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/multiple_files.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/multiple_files.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_blocks.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_blocks.yaml
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_longer.http
RENAMED
|
File without changes
|
{python_multipart-0.0.20 → python_multipart-0.0.22}/tests/test_data/http/single_field_longer.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|