/usr/lib/python2.7/dist-packages/parse_type/parse_util.py is in python-parse-type 0.3.4-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | # -*- coding: utf-8 -*-
"""
Provides generic utility classes for the :class:`parse.Parser` class.
"""
import parse
from collections import namedtuple
import six
# -- HELPER-CLASS: For format part in a Field.
# REQUIRES: Python 2.6 or newer.
FormatSpec = namedtuple("FormatSpec",
["type", "width", "zero", "align", "fill"])
def make_format_spec(type=None, width="", zero=False, align=None, fill=None):
return FormatSpec(type, width, zero, align, fill)
class Field(object):
"""
Provides a ValueObject for a Field in a parse expression.
Examples:
* "{}"
* "{name}"
* "{:format}"
* "{name:format}"
Format specification: [[fill]align][0][width][type]
"""
ALIGN_CHARS = '<>=^'
def __init__(self, name="", format=None):
self.name = name
self.format = format
self._format_spec = None
def set_format(self, format):
self.format = format
self._format_spec = None
@property
def has_format(self):
return bool(self.format)
@property
def format_spec(self):
if not self._format_spec and self.format:
self._format_spec = self.extract_format_spec(self.format)
return self._format_spec
def __str__(self):
name = self.name or ""
if self.has_format:
return "{%s:%s}" % (name, self.format)
else:
return "{%s}" % name
def __eq__(self, other):
if isinstance(other, Field):
format1 = self.format or ""
format2 = other.format or ""
return (self.name == other.name) and (format1 == format2)
elif isinstance(other, six.string_types):
return str(self) == other
else:
raise ValueError(other)
def __ne__(self, other):
return not self.__eq__(other)
@staticmethod
def make_format(format_spec):
"""Build format string from a format specification.
:param format_spec: Format specification (as FormatSpec object).
:return: Composed format (as string).
"""
fill = ''
align = ''
zero = ''
width = format_spec.width
if format_spec.align:
align = format_spec.align[0]
if format_spec.fill:
fill = format_spec.fill[0]
if format_spec.zero:
zero = '0'
# -- FORMAT-SPEC: [[fill]align][0][width][type]
return "%s%s%s%s%s" % (fill, align, zero, width, format_spec.type)
@classmethod
def extract_format_spec(cls, format):
"""Pull apart the format [[fill]align][0][width][type]"""
# -- BASED-ON: parse.extract_format()
if not format:
raise ValueError("INVALID-FORMAT: %s (empty-string)" % format)
orig_format = format
fill = align = None
if format[0] in cls.ALIGN_CHARS:
align = format[0]
format = format[1:]
elif len(format) > 1 and format[1] in cls.ALIGN_CHARS:
fill = format[0]
align = format[1]
format = format[2:]
zero = False
if format and format[0] == '0':
zero = True
format = format[1:]
width = ''
while format:
if not format[0].isdigit():
break
width += format[0]
format = format[1:]
# the rest is the type, if present
type = format
if not type:
raise ValueError("INVALID-FORMAT: %s (without type)" % orig_format)
return FormatSpec(type, width, zero, align, fill)
class FieldParser(object):
"""
Utility class that parses/extracts fields in parse expressions.
"""
@classmethod
def parse(cls, text):
if not (text.startswith('{') and text.endswith('}')):
message = "FIELD-SCHEMA MISMATCH: text='%s' (missing braces)" % text
raise ValueError(message)
# first: lose the braces
text = text[1:-1]
if ':' in text:
# -- CASE: Typed field with format.
name, format = text.split(':')
else:
name = text
format = None
return Field(name, format)
@classmethod
def extract_fields(cls, schema):
"""
Extract fields in a parse expression schema.
:param schema: Parse expression schema/format to use (as string).
:return: Generator for fields in schema (as Field objects).
"""
# -- BASED-ON: parse.Parser._generate_expression()
for part in parse.PARSE_RE.split(schema):
if not part or part == '{{' or part == '}}':
continue
elif part[0] == '{':
# this will be a braces-delimited field to handle
yield cls.parse(part)
@classmethod
def extract_types(cls, schema):
"""
Extract types (names) for typed fields (with format/type part).
:param schema: Parser schema/format to use.
:return: Generator for type names (as string).
"""
for field in cls.extract_fields(schema):
if field.has_format:
yield field.format_spec.type
|