Skip to content

Commit

Permalink
Merge pull request #2635 from cdce8p/refactor-dist
Browse files Browse the repository at this point in the history
Refactor ``read_pkg_file``
  • Loading branch information
jaraco committed Apr 14, 2021
2 parents 1d330f9 + c18ed87 commit 07eda18
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 28 deletions.
83 changes: 55 additions & 28 deletions setuptools/dist.py
Expand Up @@ -16,6 +16,8 @@
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
from email import message_from_file
Expand All @@ -36,6 +38,9 @@
from setuptools.config import parse_configuration
import pkg_resources

if TYPE_CHECKING:
from email.message import Message

__import__('setuptools.extern.packaging.specifiers')
__import__('setuptools.extern.packaging.version')

Expand Down Expand Up @@ -67,53 +72,75 @@ def get_metadata_version(self):
return mv


def read_pkg_file(self, file):
"""Reads the metadata values from a file object."""
msg = message_from_file(file)
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]
if value == 'UNKNOWN':
return None
return value


def _read_field(name):
value = msg[name]
if value == 'UNKNOWN':
return None
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(name):
values = msg.get_all(name, None)
if values == []:
return None
return values

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)
if values == []:
return None
return values


def read_pkg_file(self, file):
"""Reads the metadata values from a file object."""
msg = message_from_file(file)

self.metadata_version = StrictVersion(msg['metadata-version'])
self.name = _read_field('name')
self.version = _read_field('version')
self.description = _read_field('summary')
self.name = _read_field_from_msg(msg, 'name')
self.version = _read_field_from_msg(msg, 'version')
self.description = _read_field_from_msg(msg, 'summary')
# we are filling author only.
self.author = _read_field('author')
self.author = _read_field_from_msg(msg, 'author')
self.maintainer = None
self.author_email = _read_field('author-email')
self.author_email = _read_field_from_msg(msg, 'author-email')
self.maintainer_email = None
self.url = _read_field('home-page')
self.license = _read_field('license')
self.url = _read_field_from_msg(msg, 'home-page')
self.license = _read_field_from_msg(msg, 'license')

if 'download-url' in msg:
self.download_url = _read_field('download-url')
self.download_url = _read_field_from_msg(msg, 'download-url')
else:
self.download_url = None

self.long_description = _read_field('description')
self.description = _read_field('summary')
self.long_description = _read_field_unescaped_from_msg(msg, 'description')
self.description = _read_field_from_msg(msg, 'summary')

if 'keywords' in msg:
self.keywords = _read_field('keywords').split(',')
self.keywords = _read_field_from_msg(msg, 'keywords').split(',')

self.platforms = _read_list('platform')
self.classifiers = _read_list('classifier')
self.platforms = _read_list_from_msg(msg, 'platform')
self.classifiers = _read_list_from_msg(msg, 'classifier')

# PEP 314 - these fields only exist in 1.1
if self.metadata_version == StrictVersion('1.1'):
self.requires = _read_list('requires')
self.provides = _read_list('provides')
self.obsoletes = _read_list('obsoletes')
self.requires = _read_list_from_msg(msg, 'requires')
self.provides = _read_list_from_msg(msg, 'provides')
self.obsoletes = _read_list_from_msg(msg, 'obsoletes')
else:
self.requires = None
self.provides = None
Expand Down
40 changes: 40 additions & 0 deletions setuptools/tests/test_dist.py
Expand Up @@ -10,6 +10,8 @@
check_package_data,
DistDeprecationWarning,
check_specifier,
rfc822_escape,
rfc822_unescape,
)
from setuptools import sic
from setuptools import Distribution
Expand Down Expand Up @@ -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'],
)),
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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))

0 comments on commit 07eda18

Please sign in to comment.