summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--setuptools/dist.py21
-rw-r--r--setuptools/tests/test_dist.py40
2 files changed, 60 insertions, 1 deletions
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 8b687af7..c7af35dc 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -16,6 +16,7 @@ from distutils.util import strtobool
from distutils.debug import DEBUG
from distutils.fancy_getopt import translate_longopt
import itertools
+import textwrap
from typing import List, Optional, TYPE_CHECKING
from collections import defaultdict
@@ -71,6 +72,16 @@ def get_metadata_version(self):
return mv
+def rfc822_unescape(content: str) -> str:
+ """Reverse RFC-822 escaping by removing leading whitespaces from content."""
+ lines = content.splitlines()
+ if len(lines) == 1:
+ return lines[0].lstrip()
+ return '\n'.join(
+ (lines[0].lstrip(),
+ textwrap.dedent('\n'.join(lines[1:]))))
+
+
def _read_field_from_msg(msg: "Message", field: str) -> Optional[str]:
"""Read Message header field."""
value = msg[field]
@@ -79,6 +90,14 @@ def _read_field_from_msg(msg: "Message", field: str) -> Optional[str]:
return value
+def _read_field_unescaped_from_msg(msg: "Message", field: str) -> Optional[str]:
+ """Read Message header field and apply rfc822_unescape."""
+ value = _read_field_from_msg(msg, field)
+ if value is None:
+ return value
+ return rfc822_unescape(value)
+
+
def _read_list_from_msg(msg: "Message", field: str) -> Optional[List[str]]:
"""Read Message header field and return all results as list."""
values = msg.get_all(field, None)
@@ -108,7 +127,7 @@ def read_pkg_file(self, file):
else:
self.download_url = None
- self.long_description = _read_field_from_msg(msg, 'description')
+ self.long_description = _read_field_unescaped_from_msg(msg, 'description')
self.description = _read_field_from_msg(msg, 'summary')
if 'keywords' in msg:
diff --git a/setuptools/tests/test_dist.py b/setuptools/tests/test_dist.py
index e4bba47b..dcec1734 100644
--- a/setuptools/tests/test_dist.py
+++ b/setuptools/tests/test_dist.py
@@ -10,6 +10,8 @@ from setuptools.dist import (
check_package_data,
DistDeprecationWarning,
check_specifier,
+ rfc822_escape,
+ rfc822_unescape,
)
from setuptools import sic
from setuptools import Distribution
@@ -85,6 +87,9 @@ def __read_test_cases():
('Metadata version 1.1: Provides', params(
provides=['package'],
)),
+ ('Metadata Version 1.0: Short long description', params(
+ long_description='Short long description',
+ )),
('Metadata version 1.1: Obsoletes', params(
obsoletes=['foo'],
)),
@@ -162,6 +167,7 @@ def test_read_metadata(name, attrs):
('metadata_version', dist_class.get_metadata_version),
('provides', dist_class.get_provides),
('description', dist_class.get_description),
+ ('long_description', dist_class.get_long_description),
('download_url', dist_class.get_download_url),
('keywords', dist_class.get_keywords),
('platforms', dist_class.get_platforms),
@@ -336,3 +342,37 @@ def test_check_specifier():
attrs = {'name': 'foo', 'python_requires': ['>=3.0', '!=3.1']}
with pytest.raises(DistutilsSetupError):
dist = Distribution(attrs)
+
+
+@pytest.mark.parametrize(
+ 'content, result',
+ (
+ pytest.param(
+ "Just a single line",
+ None,
+ id="single_line",
+ ),
+ pytest.param(
+ "Multiline\nText\nwithout\nextra indents\n",
+ None,
+ id="multiline",
+ ),
+ pytest.param(
+ "Multiline\n With\n\nadditional\n indentation",
+ None,
+ id="multiline_with_indentation",
+ ),
+ pytest.param(
+ " Leading whitespace",
+ "Leading whitespace",
+ id="remove_leading_whitespace",
+ ),
+ pytest.param(
+ " Leading whitespace\nIn\n Multiline comment",
+ "Leading whitespace\nIn\n Multiline comment",
+ id="remove_leading_whitespace_multiline",
+ ),
+ )
+)
+def test_rfc822_unescape(content, result):
+ assert (result or content) == rfc822_unescape(rfc822_escape(content))