Show More
Commit Description:
Merge pull request #17 from nattee/master...
Commit Description:
Merge pull request #17 from nattee/master
upgrade to current working snapshot
References:
File last commit:
Show/Diff file:
Action:
lib/assets/Lib/string.py
| 164 lines
| 6.0 KiB
| text/x-python
| PythonLexer
|
r584 | """A collection of string constants. | |||
Public module variables: | ||||
whitespace -- a string containing all ASCII whitespace | ||||
ascii_lowercase -- a string containing all ASCII lowercase letters | ||||
ascii_uppercase -- a string containing all ASCII uppercase letters | ||||
ascii_letters -- a string containing all ASCII letters | ||||
digits -- a string containing all ASCII decimal digits | ||||
hexdigits -- a string containing all ASCII hexadecimal digits | ||||
octdigits -- a string containing all ASCII octal digits | ||||
punctuation -- a string containing all ASCII punctuation characters | ||||
printable -- a string containing all ASCII characters considered printable | ||||
""" | ||||
import _string | ||||
# Some strings for ctype-style character classification | ||||
whitespace = ' \t\n\r\v\f' | ||||
ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz' | ||||
ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | ||||
ascii_letters = ascii_lowercase + ascii_uppercase | ||||
digits = '0123456789' | ||||
hexdigits = digits + 'abcdef' + 'ABCDEF' | ||||
octdigits = '01234567' | ||||
punctuation = """!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" | ||||
printable = digits + ascii_letters + punctuation + whitespace | ||||
# Functions which aren't available as string methods. | ||||
# Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def". | ||||
def capwords(s, sep=None): | ||||
"""capwords(s [,sep]) -> string | ||||
Split the argument into words using split, capitalize each | ||||
word using capitalize, and join the capitalized words using | ||||
join. If the optional second argument sep is absent or None, | ||||
runs of whitespace characters are replaced by a single space | ||||
and leading and trailing whitespace are removed, otherwise | ||||
sep is used to split and join the words. | ||||
""" | ||||
return (sep or ' ').join(x.capitalize() for x in s.split(sep)) | ||||
#################################################################### | ||||
import re as _re | ||||
from collections import ChainMap | ||||
class _TemplateMetaclass(type): | ||||
pattern = r""" | ||||
%(delim)s(?: | ||||
(?P<escaped>%(delim)s) | # Escape sequence of two delimiters | ||||
(?P<named>%(id)s) | # delimiter and a Python identifier | ||||
{(?P<braced>%(id)s)} | # delimiter and a braced identifier | ||||
(?P<invalid>) # Other ill-formed delimiter exprs | ||||
) | ||||
""" | ||||
def __init__(cls, name, bases, dct): | ||||
super(_TemplateMetaclass, cls).__init__(name, bases, dct) | ||||
if 'pattern' in dct: | ||||
pattern = cls.pattern | ||||
else: | ||||
pattern = _TemplateMetaclass.pattern % { | ||||
'delim' : _re.escape(cls.delimiter), | ||||
'id' : cls.idpattern, | ||||
} | ||||
cls.pattern = _re.compile(pattern, cls.flags | _re.VERBOSE) | ||||
class Template(metaclass=_TemplateMetaclass): | ||||
"""A string class for supporting $-substitutions.""" | ||||
delimiter = '$' | ||||
idpattern = r'[_a-z][_a-z0-9]*' | ||||
flags = _re.IGNORECASE | ||||
def __init__(self, template): | ||||
self.template = template | ||||
# Search for $$, $identifier, ${identifier}, and any bare $'s | ||||
def _invalid(self, mo): | ||||
i = mo.start('invalid') | ||||
lines = self.template[:i].splitlines(keepends=True) | ||||
if not lines: | ||||
colno = 1 | ||||
lineno = 1 | ||||
else: | ||||
colno = i - len(''.join(lines[:-1])) | ||||
lineno = len(lines) | ||||
raise ValueError('Invalid placeholder in string: line %d, col %d' % | ||||
(lineno, colno)) | ||||
def substitute(self, *args, **kws): | ||||
if len(args) > 1: | ||||
raise TypeError('Too many positional arguments') | ||||
if not args: | ||||
mapping = kws | ||||
elif kws: | ||||
mapping = ChainMap(kws, args[0]) | ||||
else: | ||||
mapping = args[0] | ||||
# Helper function for .sub() | ||||
def convert(mo): | ||||
# Check the most common path first. | ||||
named = mo.group('named') or mo.group('braced') | ||||
if named is not None: | ||||
val = mapping[named] | ||||
# We use this idiom instead of str() because the latter will | ||||
# fail if val is a Unicode containing non-ASCII characters. | ||||
return '%s' % (val,) | ||||
if mo.group('escaped') is not None: | ||||
return self.delimiter | ||||
if mo.group('invalid') is not None: | ||||
self._invalid(mo) | ||||
raise ValueError('Unrecognized named group in pattern', | ||||
self.pattern) | ||||
return self.pattern.sub(convert, self.template) | ||||
def safe_substitute(self, *args, **kws): | ||||
if len(args) > 1: | ||||
raise TypeError('Too many positional arguments') | ||||
if not args: | ||||
mapping = kws | ||||
elif kws: | ||||
mapping = ChainMap(kws, args[0]) | ||||
else: | ||||
mapping = args[0] | ||||
# Helper function for .sub() | ||||
def convert(mo): | ||||
named = mo.group('named') or mo.group('braced') | ||||
if named is not None: | ||||
try: | ||||
# We use this idiom instead of str() because the latter | ||||
# will fail if val is a Unicode containing non-ASCII | ||||
return '%s' % (mapping[named],) | ||||
except KeyError: | ||||
return mo.group() | ||||
if mo.group('escaped') is not None: | ||||
return self.delimiter | ||||
if mo.group('invalid') is not None: | ||||
return mo.group() | ||||
raise ValueError('Unrecognized named group in pattern', | ||||
self.pattern) | ||||
return self.pattern.sub(convert, self.template) | ||||
######################################################################## | ||||
# the Formatter class | ||||
# see PEP 3101 for details and purpose of this class | ||||
# The hard parts are reused from the C implementation. They're exposed as "_" | ||||
# prefixed methods of str. | ||||
# The overall parser is implemented in _string.formatter_parser. | ||||
# The field name parser is implemented in _string.formatter_field_name_split | ||||
class Formatter: | ||||
def format(self, format_string, *args, **kwargs): | ||||
return format_string.format(*args, **kwargs) | ||||