Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
_adapters.py137 linesDownload Raw Back to importlib_metadata
1import email.message2import email.policy3import re4import textwrap5 6from ._text import FoldedCase7 8 9class RawPolicy(email.policy.EmailPolicy):10    def fold(self, name, value):11        folded = self.linesep.join(12            textwrap13            .indent(value, prefix=' ' * 8, predicate=lambda line: True)14            .lstrip()15            .splitlines()16        )17        return f'{name}: {folded}{self.linesep}'18 19 20class Message(email.message.Message):21    r"""22    Specialized Message subclass to handle metadata naturally.23 24    Reads values that may have newlines in them and converts the25    payload to the Description.26 27    >>> msg_text = textwrap.dedent('''28    ...     Name: Foo29    ...     Version: 3.030    ...     License: blah31    ...             de-blah32    ...     <BLANKLINE>33    ...     First line of description.34    ...     Second line of description.35    ...     <BLANKLINE>36    ...     Fourth line!37    ...     ''').lstrip().replace('<BLANKLINE>', '')38    >>> msg = Message(email.message_from_string(msg_text))39    >>> msg['Description']40    'First line of description.\nSecond line of description.\n\nFourth line!\n'41 42    Message should render even if values contain newlines.43 44    >>> print(msg)45    Name: Foo46    Version: 3.047    License: blah48            de-blah49    Description: First line of description.50            Second line of description.51    <BLANKLINE>52            Fourth line!53    <BLANKLINE>54    <BLANKLINE>55    """56 57    multiple_use_keys = set(58        map(59            FoldedCase,60            [61                'Classifier',62                'Obsoletes-Dist',63                'Platform',64                'Project-URL',65                'Provides-Dist',66                'Provides-Extra',67                'Requires-Dist',68                'Requires-External',69                'Supported-Platform',70                'Dynamic',71            ],72        )73    )74    """75    Keys that may be indicated multiple times per PEP 566.76    """77 78    def __new__(cls, orig: email.message.Message):79        res = super().__new__(cls)80        vars(res).update(vars(orig))81        return res82 83    def __init__(self, *args, **kwargs):84        self._headers = self._repair_headers()85 86    # suppress spurious error from mypy87    def __iter__(self):88        return super().__iter__()89 90    def __getitem__(self, item):91        """92        Override parent behavior to typical dict behavior.93 94        ``email.message.Message`` will emit None values for missing95        keys. Typical mappings, including this ``Message``, will raise96        a key error for missing keys.97 98        Ref python/importlib_metadata#371.99        """100        res = super().__getitem__(item)101        if res is None:102            raise KeyError(item)103        return res104 105    def _repair_headers(self):106        def redent(value):107            "Correct for RFC822 indentation"108            indent = ' ' * 8109            if not value or '\n' + indent not in value:110                return value111            return textwrap.dedent(indent + value)112 113        headers = [(key, redent(value)) for key, value in vars(self)['_headers']]114        if self._payload:115            headers.append(('Description', self.get_payload()))116            self.set_payload('')117        return headers118 119    def as_string(self):120        return super().as_string(policy=RawPolicy())121 122    @property123    def json(self):124        """125        Convert PackageMetadata to a JSON-compatible format126        per PEP 0566.127        """128 129        def transform(key):130            value = self.get_all(key) if key in self.multiple_use_keys else self[key]131            if key == 'Keywords':132                value = re.split(r'\s+', value)133            tk = key.lower().replace('-', '_')134            return tk, value135 136        return dict(map(transform, map(FoldedCase, self)))137 
codekingpro/portable-devtools · Team Ai