def from_string(cls, raw_filter, rule_limit):
"""
Creates a new Filter instance from the given string.
*raw_filter* is the raw filter : a string that may contain several
regular expressions (separated by a newline char) and tags.
*rule_limit* is the Rule's limit above which the Action is executed.
Raises :class:`exceptions.ValueError` if the given string could not be
compiled in at least one suitable :class:`re.RegexObject`.
Returns a new :class:`Filter` instance.
"""
parsed_filter = cls.replace_tags(raw_filter)
regexes = cls.build_regex_list(parsed_filter, rule_limit)
return cls(regexes)
python类RegexObject()的实例源码
def _compile_template_re(delimiters):
"""
Return a regular expresssion object (re.RegexObject) instance.
"""
# The possible tag type characters following the opening tag,
# excluding "=" and "{".
tag_types = "!>&/#^"
# TODO: are we following this in the spec?
#
# The tag's content MUST be a non-whitespace character sequence
# NOT containing the current closing delimiter.
#
tag = r"""
(?P<whitespace>[\ \t]*)
%(otag)s \s*
(?:
(?P<change>=) \s* (?P<delims>.+?) \s* = |
(?P<raw>{) \s* (?P<raw_name>.+?) \s* } |
(?P<tag>[%(tag_types)s]?) \s* (?P<tag_key>[\s\S]+?)
)
\s* %(ctag)s
""" % {'tag_types': tag_types, 'otag': re.escape(delimiters[0]), 'ctag': re.escape(delimiters[1])}
return re.compile(tag, re.VERBOSE)
def regex(self):
"""
A compiled version of the expression
:rtype: re.RegexObject
:return: compiled regex object
"""
if self._regex is None:
self._regex = re.compile(self.expression)
return self._regex
def __init__(self, root_path, url_map, url_pattern):
"""Initializer for StaticContentHandler.
Args:
root_path: A string containing the full path of the directory containing
the application's app.yaml file.
url_map: An appinfo.URLMap instance containing the configuration for this
handler.
url_pattern: A re.RegexObject that matches URLs that should be handled by
this handler. It may also optionally bind groups.
"""
super(StaticContentHandler, self).__init__(url_map, url_pattern)
self._root_path = root_path
def __init__(self, regexes):
"""
Initializes a newly created Filter with the given list of
:class:`re.RegexObject`.
*regexes* is a list of :class:`re.RegexObject`s.
Raises :class:`exceptions.ValueError` if the given list evaluates to
False (empty list, None, ...)
"""
if regexes:
list.__init__(self, regexes)
else:
raise ValueError("Unable to initialize a Filter without at least "
"one valid pattern, please fix your config file")
def __init__(self, pattern=None, name=None, suffix=None,
recursive=False, match_pretty_name=True):
"""
:param Matcher.BasePattern|None pattern: If provided, reject any
type that does not match `pattern`.
:param str|re.RegexObject|None name: If it's a string, reject any
type whose name is different. If it's a regular expression
object, reject any type whose name isn't matched by it. The
regular expression must match the whole name.
:param str|None suffix: If provided, reject any type whose name
does not end with `suffix`.
:param bool recursive: If true, consider integer basis types (for
integer subrange types) or the target type of typedefs for
matching in addition to the original type.
This behavior can be surprising: for instance typedef layers
are used to distinguish unconstrained arrays from accesses to
these, so this is disabled by default.
:param bool match_pretty_name: If True, match on the pretty GDB
type name (`str(gdb_type)`, for instance: "foo.bar"),
otherwise, use the raw name (`gdb_type.name`, for instance:
"foo__bar___Xb").
"""
self.type_pattern = pattern
self.name = name
self.suffix = suffix
self.recursive = recursive
self.match_pretty_name = match_pretty_name
def __parse_line(self, regex):
"""Parse a GNATcheck message line.
Adds the message to the current database session.
Retrieves following information:
* source basename
* line in source
* rule identification
* message description
:param re.RegexObject regex: the result of the _MESSAGE regex
"""
# The following Regex results are explained using this example.
# 'input.adb:3:19: use clause for package [USE_PACKAGE_Clauses]'
# Extract each component from the message:
# ('input.adb', '3', '19', 'use clause for package',
# 'USE_PACKAGE_Clauses')
base = regex.group('file')
src = GNAThub.Project.source_file(base)
line = regex.group('line')
column = regex.group('column')
message = regex.group('message')
rule_id = regex.group('rule_id').lower()
self.__add_message(src, line, column, rule_id, message)
def __parse_line(self, regex):
"""Parse a GNATprove message line.
Adds the message to the current database session.
Retrieves following information:
* source basename
* line in source
* rule identification
* message description
:param re.RegexObject regex: the result of the _MESSAGE regex
"""
filename = regex.group('file')
src = GNAThub.Project.source_file(filename)
line = regex.group('line')
column = regex.group('column')
message = regex.group('message')
msg_id = regex.group('msg_id')
category = regex.group('category').lower()
record = self.msg_ids.get((filename, int(msg_id)))
if record is None:
self.log.warn(
'%s: failed to get record for msg_id #%s', filename, msg_id)
return
rule_id = record['rule'].lower()
self.__add_message(src, line, column, rule_id, message, category)
def build_regex_list(cls, filter_str, rule_limit):
"""
Creates a list of :class:`re.RegexObject`s from the given string.
*filter_str* is a string containing the regular expressions used to
build the Filter.
If *filter_str* contains newlines chars, it is split in different
regular expressions (one per line).
If one of these strings can not be compiled into a
:class:`re.RegexObject`, a warning is issued and the pattern is
ignored.
*rule_limit* is the Rule's limit above which the Action is executed.
If *rule_limit* is > 1 and *filter_str* doesn't have at least one named
capturing group, a warning is issued and the pattern is ignored.
Returns a list of :class:`re.RegexObject`s built upon the given string.
"""
regexes = []
for f in filter_str.splitlines():
try:
regex = re.compile(f, re.MULTILINE)
except sre_constants.error:
warnings.warn("Unable to compile this pattern: \"{0}\". "
"It will be ignored"
.format(f))
else:
# If the Rule limit is > 1, the pattern MUST have a capturing
# group.
# (this capturing group will be used later as an index to
# count the matches.)
# If the pattern doesn't respect this, it will be ignored.
if rule_limit > 1 and not regex.groupindex:
warnings.warn("The pattern \"{0}\" doesn't have a "
"capturing group but needs one."
"It will be ignored"
.format(f))
else:
regexes.append(regex)
return regexes