Source code for madam.mime

from functools import total_ordering
from typing import Optional, Union


[docs]@total_ordering class MimeType: """ Represents a MIME type according to RFC 2045. This class behaves identical to its string representation in ``dict`` and ``set``. Limitations: - Suffixes are considered a part of the subtype - Parameters like ``charset`` are not supported and will be treated as part of the subtype """ __slots__ = 'type', 'subtype'
[docs] def __init__(self, mediatype: Optional[Union[str, 'MimeType']], subtype: Optional[str] = None): """ Initializes a new MIME type with either - both, *media type* and *subtype* strings - a complete MIME type string like ``'audio/opus'`` - another ``MimeType`` object :param mediatype: Can define either the media type, or the complete MIME type by passing a MIME type string or another ``MimeType`` instance. :type mediatype: str or MimeType or None :param subtype: Defines the subtype. :type subtype: str or None """ self.type = None self.subtype = None if isinstance(mediatype, MimeType): if subtype is not None: raise ValueError('Cannot pass MimeType object and subtype string for initialization.') self.type = mediatype.type self.subtype = mediatype.subtype elif isinstance(mediatype, str): if mediatype: delimiter_count = mediatype.count('/') if delimiter_count: if subtype is not None: raise ValueError('Cannot pass MIME type string and subtype string for initialization.') if delimiter_count > 1: raise ValueError(f'Too many delimiters in {mediatype!r}') mediatype, subtype = mediatype.split('/') if mediatype != '*': self.type = str(mediatype).lower() elif mediatype is not None: raise TypeError(f'{type(mediatype).__qualname__!r} type is not allowed for initialization of MIME type') if isinstance(subtype, str): if subtype and subtype != '*': if '/' in subtype: raise ValueError('Subtype cannot contain delimiters') self.subtype = str(subtype).lower() elif subtype is not None: raise TypeError(f'{type(subtype).__qualname__!r} type is not allowed for initialization of MIME subtype')
def __str__(self) -> str: return '/'.join((self.type or '*', self.subtype or '*')) def __repr__(self) -> str: return f'{self.__class__.__qualname__}(mediatype={self.type!r}, subtype={self.subtype!r})' def __hash__(self) -> int: return hash(str(self)) def __eq__(self, other: object) -> bool: if isinstance(other, str): return self == MimeType(other) if isinstance(other, MimeType): return self.type == other.type and self.subtype == other.subtype return NotImplemented def __lt__(self, other: object) -> bool: if isinstance(other, str): return self < MimeType(other) if isinstance(other, MimeType): if self.type == other.type: if self.subtype == other.subtype: return False else: if self.subtype is None: return True return str(self.subtype) < str(other.subtype) else: if self.type is None: return True return str(self.type) < str(other.type) return NotImplemented