class Header(deb822.RestrictedWrapper): """Represents the header paragraph of a debian/copyright file. Property values are all immutable, such that in order to modify them you must explicitly set them (rather than modifying a returned reference). """ def __init__(self, data=None): """Initializer. :param parsed: A deb822.Deb822 object for underlying data. If None, a new one will be created. """ if data is None: data = deb822.Deb822() data['Format'] = _CURRENT_FORMAT if 'Format-Specification' in data: warnings.warn('use of deprecated "Format-Specification" field;' ' rewriting as "Format"') data['Format'] = data['Format-Specification'] del data['Format-Specification'] super(Header, self).__init__(data) fmt = self.format if fmt is None: raise NotMachineReadableError( 'input is not a machine-readable debian/copyright') if fmt not in _KNOWN_FORMATS: warnings.warn('format not known: %r' % fmt) def known_format(self): """Returns True iff the format is known.""" return self.format in _KNOWN_FORMATS def current_format(self): """Returns True iff the format is the current format.""" return self.format == _CURRENT_FORMAT format = deb822.RestrictedField( 'Format', to_str=_single_line, allow_none=False) upstream_name = deb822.RestrictedField( 'Upstream-Name', to_str=_single_line) upstream_contact = deb822.RestrictedField( 'Upstream-Contact', from_str=_LineBased.from_str, to_str=_LineBased.to_str) source = deb822.RestrictedField('Source') disclaimer = deb822.RestrictedField('Disclaimer') comment = deb822.RestrictedField('Comment') license = deb822.RestrictedField( 'License', from_str=License.from_str, to_str=License.to_str) copyright = deb822.RestrictedField('Copyright')
class LicenseParagraph(deb822.RestrictedWrapper): """Represents a standalone license paragraph of a debian/copyright file. Minimally, this kind of paragraph requires a 'License' field and has no 'Files' field. It is used to give a short name to a license text, which can be referred to from the header or files paragraphs. """ def __init__(self, data, _internal_validate=True): # type: (deb822.Deb822, bool) -> None super(LicenseParagraph, self).__init__(data) if _internal_validate: if 'License' not in data: raise MachineReadableFormatError('"License" field required') if 'Files' in data: raise MachineReadableFormatError( 'input appears to be a Files paragraph') @classmethod def create(cls, license): # type: (License) -> LicenseParagraph """Returns a LicenseParagraph with the given license.""" # pylint: disable=redefined-builtin if not isinstance(license, License): raise TypeError('license must be a License instance') paragraph = cls(deb822.Deb822(), _internal_validate=False) paragraph.license = license # type: ignore ## properties return paragraph # TODO(jsw): Validate that the synopsis of the license is a short name or # short name with exceptions (not an alternatives expression). This # requires help from the License class. license = deb822.RestrictedField( 'License', from_str=License.from_str, to_str=License.to_str, allow_none=False) # type: ignore comment = deb822.RestrictedField('Comment') # type: ignore # Hide 'Files'. __files = deb822.RestrictedField('Files') # type: ignore
class Header(deb822.RestrictedWrapper): """Represents the header paragraph of a debian/copyright file. Property values are all immutable, such that in order to modify them you must explicitly set them (rather than modifying a returned reference). """ def __init__(self, data=None): # type: (Optional[deb822.Deb822]) -> None """Initializer. :param data: A deb822.Deb822 object for underlying data. If None, a new one will be created. """ if data is None: data = deb822.Deb822() data['Format'] = _CURRENT_FORMAT if 'Format-Specification' in data: warnings.warn('use of deprecated "Format-Specification" field;' ' rewriting as "Format"') data['Format'] = data['Format-Specification'] del data['Format-Specification'] super(Header, self).__init__(data) fmt = str() # Set this to be a string type to appease later checking fmt = self.format # type: ignore if fmt != _CURRENT_FORMAT and fmt is not None: # Add a terminal slash onto the end if missing if not fmt.endswith('/'): fmt += "/" # Upgrade http to https if that is valid if fmt.startswith('http:'): fmt = "https:%s" % fmt[5:] if fmt in _KNOWN_FORMATS: warnings.warn('Fixing Format URL') self.format = fmt # type: ignore if fmt is None: raise NotMachineReadableError( 'input is not a machine-readable debian/copyright') if fmt not in _KNOWN_FORMATS: warnings.warn('format not known: %r' % fmt) def known_format(self): # type: () -> bool """Returns True iff the format is known.""" return self.format in _KNOWN_FORMATS def current_format(self): # type: () -> bool """Returns True iff the format is the current format.""" return self.format == _CURRENT_FORMAT # lots of type ignores due to https://github.com/python/mypy/issues/1279 format = deb822.RestrictedField( # type: ignore 'Format', to_str=_single_line, allow_none=False) upstream_name = deb822.RestrictedField( # type: ignore 'Upstream-Name', to_str=_single_line) upstream_contact = deb822.RestrictedField( # type: ignore 'Upstream-Contact', from_str=_LineBased.from_str, to_str=_LineBased.to_str) source = deb822.RestrictedField('Source') # type: ignore disclaimer = deb822.RestrictedField('Disclaimer') # type: ignore comment = deb822.RestrictedField('Comment') # type: ignore license = deb822.RestrictedField( # type: ignore 'License', from_str=License.from_str, to_str=License.to_str) copyright = deb822.RestrictedField('Copyright') # type: ignore
class FilesParagraph(deb822.RestrictedWrapper): """Represents a Files paragraph of a debian/copyright file. This kind of paragraph is used to specify the copyright and license for a particular set of files in the package. """ def __init__(self, data, _internal_validate=True, strict=True): # type: (deb822.Deb822, bool, bool) -> None super(FilesParagraph, self).__init__(data) if _internal_validate: if 'Files' not in data: raise MachineReadableFormatError('"Files" field required') if 'Copyright' not in data: _complain('Files paragraph missing Copyright field', strict) if 'License' not in data: _complain('Files paragraph missing License field', strict) if not self.files: _complain('Files paragraph has empty Files field', strict) self.__cached_files_pat = ('', re.compile('')) # type: Tuple[str, Pattern] @classmethod def create(cls, files, # type: Optional[List[str]] copyright, # type: Optional[str] license, # type: Optional[License] ): # type: (...) -> FilesParagraph """Create a new FilesParagraph from its required parts. :param files: The list of file globs. :param copyright: The copyright for the files (free-form text). :param license: The Licence for the files. """ # pylint: disable=redefined-builtin p = cls(deb822.Deb822(), _internal_validate=False) # mypy doesn't handle the metaprogrammed properties at all p.files = files # type: ignore p.copyright = copyright # type: ignore p.license = license # type: ignore return p def files_pattern(self): # type: () -> Optional[Pattern] """Returns a regular expression equivalent to the Files globs. Caches the result until files is set to a different value. Raises ValueError if any of the globs are invalid. """ files_str = self['files'] if self.__cached_files_pat[0] != files_str: self.__cached_files_pat = (files_str, globs_to_re(self.files)) return self.__cached_files_pat[1] def matches(self, filename): # type: (str) -> bool """Returns True iff filename is matched by a glob in Files.""" pat = self.files_pattern() if pat is None: return False return pat.match(filename) is not None files = deb822.RestrictedField( 'Files', from_str=_SpaceSeparated.from_str, to_str=_SpaceSeparated.to_str, allow_none=False) # type: ignore copyright = deb822.RestrictedField('Copyright', allow_none=False) # type: ignore license = deb822.RestrictedField( 'License', from_str=License.from_str, to_str=License.to_str, allow_none=False) comment = deb822.RestrictedField('Comment') # type: ignore
class FilesParagraph(deb822.RestrictedWrapper): """Represents a Files paragraph of a debian/copyright file. This kind of paragraph is used to specify the copyright and license for a particular set of files in the package. """ def __init__(self, data, _internal_validate=True): super(FilesParagraph, self).__init__(data) if _internal_validate: if 'Files' not in data: raise ValueError('"Files" field required') # For the other "required" fields, we just warn for now. Perhaps # these should be upgraded to exceptions (potentially protected by # a "strict" param). if 'Copyright' not in data: warnings.warn('Files paragraph missing Copyright field') if 'License' not in data: warnings.warn('Files paragraph missing License field') if not self.files: warnings.warn('Files paragraph has empty Files field') self.__cached_files_pat = (None, None) @classmethod def create(cls, files, copyright, license): """Create a new FilesParagraph from its required parts. :param files: The list of file globs. :param copyright: The copyright for the files (free-form text). :param license: The Licence for the files. """ p = cls(deb822.Deb822(), _internal_validate=False) p.files = files p.copyright = copyright p.license = license return p def files_pattern(self): """Returns a regular expression equivalent to the Files globs. Caches the result until files is set to a different value. Raises ValueError if any of the globs are invalid. """ files_str = self['files'] if self.__cached_files_pat[0] != files_str: self.__cached_files_pat = (files_str, globs_to_re(self.files)) return self.__cached_files_pat[1] def matches(self, filename): """Returns True iff filename is matched by a glob in Files.""" pat = self.files_pattern() return pat.match(filename) is not None files = deb822.RestrictedField( 'Files', from_str=_SpaceSeparated.from_str, to_str=_SpaceSeparated.to_str, allow_none=False) copyright = deb822.RestrictedField('Copyright', allow_none=False) license = deb822.RestrictedField( 'License', from_str=License.from_str, to_str=License.to_str, allow_none=False) comment = deb822.RestrictedField('Comment')