Path: blob/master/venv/Lib/site-packages/soupsieve/util.py
811 views
"""Utility."""1from functools import wraps2import warnings3import re45DEBUG = 0x0000167RE_PATTERN_LINE_SPLIT = re.compile(r'(?:\r\n|(?!\r\n)[\n\r])|$')89LC_A = ord('a')10LC_Z = ord('z')11UC_A = ord('A')12UC_Z = ord('Z')131415def lower(string):16"""Lower."""1718new_string = []19for c in string:20o = ord(c)21new_string.append(chr(o + 32) if UC_A <= o <= UC_Z else c)22return ''.join(new_string)232425def upper(string): # pragma: no cover26"""Lower."""2728new_string = []29for c in string:30o = ord(c)31new_string.append(chr(o - 32) if LC_A <= o <= LC_Z else c)32return ''.join(new_string)333435class SelectorSyntaxError(Exception):36"""Syntax error in a CSS selector."""3738def __init__(self, msg, pattern=None, index=None):39"""Initialize."""4041self.line = None42self.col = None43self.context = None4445if pattern is not None and index is not None:46# Format pattern to show line and column position47self.context, self.line, self.col = get_pattern_context(pattern, index)48msg = '{}\n line {}:\n{}'.format(msg, self.line, self.context)4950super(SelectorSyntaxError, self).__init__(msg)515253def deprecated(message, stacklevel=2): # pragma: no cover54"""55Raise a `DeprecationWarning` when wrapped function/method is called.5657Borrowed from https://stackoverflow.com/a/48632082/86602658"""5960def _decorator(func):61@wraps(func)62def _func(*args, **kwargs):63warnings.warn(64"'{}' is deprecated. {}".format(func.__name__, message),65category=DeprecationWarning,66stacklevel=stacklevel67)68return func(*args, **kwargs)69return _func70return _decorator717273def warn_deprecated(message, stacklevel=2): # pragma: no cover74"""Warn deprecated."""7576warnings.warn(77message,78category=DeprecationWarning,79stacklevel=stacklevel80)818283def get_pattern_context(pattern, index):84"""Get the pattern context."""8586last = 087current_line = 188col = 189text = []90line = 19192# Split pattern by newline and handle the text before the newline93for m in RE_PATTERN_LINE_SPLIT.finditer(pattern):94linetext = pattern[last:m.start(0)]95if not len(m.group(0)) and not len(text):96indent = ''97offset = -198col = index - last + 199elif last <= index < m.end(0):100indent = '--> '101offset = (-1 if index > m.start(0) else 0) + 3102col = index - last + 1103else:104indent = ' '105offset = None106if len(text):107# Regardless of whether we are presented with `\r\n`, `\r`, or `\n`,108# we will render the output with just `\n`. We will still log the column109# correctly though.110text.append('\n')111text.append('{}{}'.format(indent, linetext))112if offset is not None:113text.append('\n')114text.append(' ' * (col + offset) + '^')115line = current_line116117current_line += 1118last = m.end(0)119120return ''.join(text), line, col121122123