univention.ucslint package

Submodules

univention.ucslint.base module

univention.ucslint.base.noqa(line)[source]

Check for lines to be ignored by ` ucslint: 0000-0`.

>>> noqa('')('0000-0')
False
>>> noqa('# ucslint')('0000-0')
True
>>> noqa('# ucslint: 0000-0')('0000-0')
True
>>> noqa('# ucslint: 0000-1')('0000-0')
False
>>> noqa('# ucslint: 0000-0, 0000-1')('0000-0')
True
Return type

Callable[[str], bool]

univention.ucslint.base.line_regexp(text, regexp)[source]

Find all matches and return row and colum number.

Parameters
  • text (str) – The text to seach in.

  • regexp (Pattern[str]) – Compiled regular excpression.

Return type

Iterator[Tuple[int, int, Match[str]]]

Returns

Iterator returning 3-tuples (row, col, match)

class univention.ucslint.base.UPCMessage(id_, msg, filename=None, row=None, col=None)[source]

Bases: object

Univention Policy Check message.

Parameters
  • id – Message identifier.

  • msg (str) – Message test.

  • filename (Optional[str]) – Associated file name.

  • row (Optional[int]) – Associated line number.

  • col (Optional[int]) – Associated column number.

getId()[source]

Return unique message identifier.

Return type

str

junit()[source]

Return JUnit XML test case.

Return type

TestCase

Returns

test case.

class univention.ucslint.base.UniventionPackageCheckBase[source]

Bases: object

Abstract base class for checks.

addmsg(msgid, msg, filename=None, row=None, col=None, line='')[source]

Add UPCMessage message.

Parameters
  • msgid (str) – Message identifier.

  • msg (str) – Message text.

  • filename (Optional[str]) – Associated file name.

  • row (Optional[int]) – Associated line number.

  • col (Optional[int]) – Associated column number.

  • line (str) – The line content itself (used for per-line ignores).

Return type

None

getMsgIds()[source]

Return mapping from message-identifiert to 2-tuple (severity, message-text).

Return type

Dict[str, Tuple[int, str]]

setdebug(level)[source]

Set debug level.

Parameters

level (int) – Debug level.

Return type

None

debug(msg)[source]

Print debug message.

Parameters

msg (str) – Text string.

Return type

None

postinit(path)[source]

Checks to be run before real check or to create precalculated data for several runs. Only called once!

Parameters

path (str) – Directory or file to check.

Return type

None

check(path)[source]

The real check.

Parameters

path (str) – Directory or file to check.

Return type

None

result()[source]

Return result as list of messages.

Return type

List[UPCMessage]

Returns

List of UPCMessage

class univention.ucslint.base.UniventionPackageCheckDebian[source]

Bases: univention.ucslint.base.UniventionPackageCheckBase

Check for debian/ directory.

check(path)[source]

the real check.

Return type

None

exception univention.ucslint.base.UCSLintException[source]

Bases: Exception

Top level exception.

exception univention.ucslint.base.DebianControlNotEnoughSections[source]

Bases: univention.ucslint.base.UCSLintException

Content exception.

exception univention.ucslint.base.DebianControlParsingError[source]

Bases: univention.ucslint.base.UCSLintException

Parsing exception.

exception univention.ucslint.base.FailedToReadFile(fn)[source]

Bases: univention.ucslint.base.UCSLintException

File reading exception.

class univention.ucslint.base.DebianControlEntry(content)[source]

Bases: Dict[str, str]

Handle paragraph in Deb822 control file.

Parameters

content (str) – String content of paragraph.

RE_MULTILINE = re.compile('$\\n\\s', re.MULTILINE)
class univention.ucslint.base.DebianControlSource(content)[source]

Bases: univention.ucslint.base.DebianControlEntry

Source package entry from debian/control.

property dep
property dep_indep
property dep_arch
property dep_all
property conf
property conf_indep
property conf_arch
property conf_all
class univention.ucslint.base.DebianControlBinary(content)[source]

Bases: univention.ucslint.base.DebianControlEntry

Binary package entry from debian/control.

property pre
property dep
property rec
property sug
property all
property bre
property enh
property repl
property conf
property pro
class univention.ucslint.base.ParserDebianControl(filename)[source]

Bases: object

Parse debian/control file.

Parameters

filename (str) – Full path.

RE_COMMENT = re.compile('^#.*$\\n?', re.MULTILINE)
RE_SECTION = re.compile('\\n{2,}', re.MULTILINE)
class univention.ucslint.base.RegExTest(regex, msgid, msg, cntmin=None, cntmax=None)[source]

Bases: object

Regular expression test.

Parameters
  • regex (Pattern[str]) – Compiled regular expression.

  • msgid (str) – Message identifier.

  • msg (str) – Message text.

  • cntmin (Optional[int]) – Required minimum number of matches.

  • cntmax (Optional[int]) – Allowed maximum number of matches.

class univention.ucslint.base.UPCFileTester(maxsize=102400)[source]

Bases: object

Univention Package Check - File Tester simple class to test if a certain text exists/does not exist in a textfile

By default only the first 100k of the file will be read.

Example:

import re
x = UPCFileTester()
x.addTest(re.compile(r'ext[234]'), '5432-1', 'Habe ein extfs gefunden.', cntmax=0)
x.addTest(re.compile(r'squashfs'), '1234-5', 'Habe kein squashfs gefunden.', cntmin=1)
x.open('/etc/fstab')
msglist = x.runTests()
for msg in msglist:
    print('%s ==> %s ==> %s' % (msg.id, msg.filename, msg.msg))

5432-1: /etc/fstab:4:29: Habe ein extfs gefunden.
5432-1: /etc/fstab:7:19: Habe ein extfs gefunden.
1234-5: /etc/fstab: Habe kein squashfs gefunden.

creates a new UPCFileTester object

Parameters

maxsize (int) – maximum number of bytes read from specified file

open(filename)[source]

Opens the specified file and reads up to maxsize bytes into memory.

Parameters

filename (str) – File to process.

Return type

None

addTest(regex, msgid, msg, cntmin=None, cntmax=None)[source]

add a new test

Parameters
Raises

ValueError – if neither cntmin nor cntmax has been set

Return type

None

runTests()[source]

Runs all given tests on loaded file.

Return type

List[UPCMessage]

Returns

a list of UPCMessage objects

class univention.ucslint.base.FilteredDirWalkGenerator(path, ignore_dirs=None, prefixes=None, suffixes=None, ignore_suffixes=None, ignore_files=None, ignore_debian_subdirs=True, reHashBang=None, readSize=2048, dangling_symlinks=False)[source]

Bases: object

FilteredDirWalkGenerator is a generator that walks down all directories and returns all matching filenames.

There are several possibilities to limit returned results:

Parameters
  • ignore_dirs (Optional[Iterable[str]]) – a list of additional directory names that will be excluded when traversing subdirectories (e.g. [‘.git’, ‘.svn’])

  • prefixes (Optional[Iterable[str]]) – a list of prefixes files have to start with (e.g. [‘univention-‘, ‘preinst’])

  • suffixes (Optional[Iterable[str]]) – a list of suffixes files have to end with (e.g. [‘.py’, ‘.sh’, ‘.patch’])

  • ignore_suffixes (Optional[Iterable[str]]) – a list of additional files, that end with one of defined suffixes, will be ignored (e.g. [‘~’, ‘.bak’])

  • ignore_files (Optional[Iterable[str]]) – list of additional files that will be ignored (e.g. [‘.gitignore’, ‘config.sub’]).

  • ignore_debian_subdirs (bool) – boolean that defines if .../debian/* directories are ignored or not.

  • reHashBang (Optional[Pattern[str]]) – if defined, additionally text files are returned whose first characters match specified regular expression.

  • readSize (int) – number of bytes that will be read for e.g. reHashBang

example:

for fn in FilteredDirWalkGenerator(path, suffixes=['.py']):
  print(fn)
IGNORE_DIRS = {'.git', '.mypy_cache', '.pybuild', '.svn', 'CVS', '__pycache__'}
IGNORE_SUFFIXES = {'.bak', '.pyc', '.pyo', '.swp', '~'}
IGNORE_FILES = {'config.guess', 'config.status', 'config.sub', 'configure', 'depcomp', 'install-sh', 'libtool', 'missing'}
BINARY_SUFFIXES = {'.ai', '.bz2', '.cer', '.class', '.cvd', '.deb', '.der', '.dll', '.efi.signed', '.gd2', '.gif', '.gpg', '.gz', '.ico', '.jar', '.jpeg', '.jpg', '.mo', '.pdf', '.png', '.so', '.svg', '.svgz', '.swf', '.ttf', '.udeb', '.woff', '.xcf', '.xz', '.zip'}
DOCUMENTATION_SUFFIXES = {'.1', '.2', '.3', '.4', '.5', '.6', '.7', '.8', '.doc', '.html', '.md', '.po', '.rst', '.txt', '.xml', 'ChangeLog', 'README', 'changelog'}

univention.ucslint.common module

>>> RE_DEBIAN_PACKAGE_NAME.match("0").groups()
('0',)
>>> RE_DEBIAN_PACKAGE_VERSION.match("0").groups()
(None, '0', None)
>>> RE_DEBIAN_PACKAGE_VERSION.match("0-0").groups()
(None, '0', '0')
>>> RE_DEBIAN_PACKAGE_VERSION.match("0-0-0").groups()
(None, '0-0', '0')
>>> RE_DEBIAN_CHANGELOG.match("0 (0) unstable; urgency=low").groups()
('0', '0', ' unstable', ' urgency=low')
>>> RE_HASHBANG_SHELL.match('#!/bin/sh') is not None
True
>>> RE_HASHBANG_SHELL.match('#! /bin/bash') is not None
True

univention.ucslint.python module

class univention.ucslint.python.Base[source]

Bases: object

VER = (0, 0)
MATCHED_RAW = '\\b(?:[Rr]|[BbFfUu][Rr]|[Rr][BbFf])(?:\'\'\'(?:[^\'\\\\]|\\\\(?:$|.)|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|\\\\(?:$|.)|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|\\\\(?:$|.))*?\'|"(?:[^"\\\\\\n]|\\\\(?:$|.))*?")'
MATCHED_BYTES = '\\b[Bb](?:\'\'\'(?:[^\'\\\\]|\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2}))*?\'|"(?:[^"\\\\\\n]|\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2}))*?")'
MATCHED_UNICODE = '(?:\\b[FfUu])?(?:\'\'\'(?:[^\'\\\\]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})))*?\'|"(?:[^"\\\\\\n]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})))*?")'
classmethod matcher()[source]
Return type

Pattern[str]

class univention.ucslint.python.Python27[source]

Bases: univention.ucslint.python.Base

VER = (2, 7)
MATCHED_RAW = '\\b(?:[Rr]|[BbUu][Rr]|[Rr][Uu])(?:\'\'\'(?:[^\'\\\\]|\\\\(?:$|.)|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|\\\\(?:$|.)|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|\\\\(?:$|.))*?\'|"(?:[^"\\\\\\n]|\\\\(?:$|.))*?")'
class univention.ucslint.python.Python30[source]

Bases: univention.ucslint.python.Base

VER = (3, 0)
MATCHED_RAW = '\\b(?:[Rr]|[Bb][Rr])(?:\'\'\'(?:[^\'\\\\]|\\\\(?:$|.)|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|\\\\(?:$|.)|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|\\\\(?:$|.))*?\'|"(?:[^"\\\\\\n]|\\\\(?:$|.))*?")'
MATCHED_UNICODE = '(?:\'\'\'(?:[^\'\\\\]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})))*?\'|"(?:[^"\\\\\\n]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})))*?")'
class univention.ucslint.python.Python33[source]

Bases: univention.ucslint.python.Base

VER = (3, 3)
MATCHED_RAW = '\\b(?:[Rr]|[Bb][Rr]|[Rr][Bb])(?:\'\'\'(?:[^\'\\\\]|\\\\(?:$|.)|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|\\\\(?:$|.)|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|\\\\(?:$|.))*?\'|"(?:[^"\\\\\\n]|\\\\(?:$|.))*?")'
MATCHED_UNICODE = '(?:\\b[Uu])?(?:\'\'\'(?:[^\'\\\\]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})))*?\'|"(?:[^"\\\\\\n]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})))*?")'
class univention.ucslint.python.Python36[source]

Bases: univention.ucslint.python.Base

VER = (3, 6)
MATCHED_RAW = '\\b(?:[Rr]|[BbFf][Rr]|[Rr][BbFf])(?:\'\'\'(?:[^\'\\\\]|\\\\(?:$|.)|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|\\\\(?:$|.)|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|\\\\(?:$|.))*?\'|"(?:[^"\\\\\\n]|\\\\(?:$|.))*?")'
MATCHED_UNICODE = '(?:\\b[FfUu])?(?:\'\'\'(?:[^\'\\\\]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))|\'[^\']|\'\'[^\'])*?\'\'\'|"""(?:[^"\\\\]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}))|"[^"]|""[^"])*?"""|\'(?:[^\'\\\\\\n]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})))*?\'|"(?:[^"\\\\\\n]|(?:\\\\(?:$|[\\\\\'"abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]{2})|\\\\(?:N\\{[^}]+\\}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})))*?")'
univention.ucslint.python.python_files(path)[source]
Return type

Iterator[str]