Mercurial > repos > shellac > guppy_basecaller
diff env/lib/python3.7/site-packages/boltons/formatutils.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
| author | shellac |
|---|---|
| date | Mon, 01 Jun 2020 08:59:25 -0400 |
| parents | 79f47841a781 |
| children |
line wrap: on
line diff
--- a/env/lib/python3.7/site-packages/boltons/formatutils.py Thu May 14 16:47:39 2020 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,333 +0,0 @@ -# -*- coding: utf-8 -*- -"""`PEP 3101`_ introduced the :meth:`str.format` method, and what -would later be called "new-style" string formatting. For the sake of -explicit correctness, it is probably best to refer to Python's dual -string formatting capabilities as *bracket-style* and -*percent-style*. There is overlap, but one does not replace the -other. - - * Bracket-style is more pluggable, slower, and uses a method. - * Percent-style is simpler, faster, and uses an operator. - -Bracket-style formatting brought with it a much more powerful toolbox, -but it was far from a full one. :meth:`str.format` uses `more powerful -syntax`_, but `the tools and idioms`_ for working with -that syntax are not well-developed nor well-advertised. - -``formatutils`` adds several functions for working with bracket-style -format strings: - - * :class:`DeferredValue`: Defer fetching or calculating a value - until format time. - * :func:`get_format_args`: Parse the positional and keyword - arguments out of a format string. - * :func:`tokenize_format_str`: Tokenize a format string into - literals and :class:`BaseFormatField` objects. - * :func:`construct_format_field_str`: Assists in progammatic - construction of format strings. - * :func:`infer_positional_format_args`: Converts anonymous - references in 2.7+ format strings to explicit positional arguments - suitable for usage with Python 2.6. - -.. _more powerful syntax: https://docs.python.org/2/library/string.html#format-string-syntax -.. _the tools and idioms: https://docs.python.org/2/library/string.html#string-formatting -.. _PEP 3101: https://www.python.org/dev/peps/pep-3101/ -""" -# TODO: also include percent-formatting utils? -# TODO: include lithoxyl.formatters.Formatter (or some adaptation)? - -from __future__ import print_function - -import re -from string import Formatter - -try: - unicode # Python 2 -except NameError: - unicode = str # Python 3 - -__all__ = ['DeferredValue', 'get_format_args', 'tokenize_format_str', - 'construct_format_field_str', 'infer_positional_format_args', - 'BaseFormatField'] - - -_pos_farg_re = re.compile('({{)|' # escaped open-brace - '(}})|' # escaped close-brace - r'({[:!.\[}])') # anon positional format arg - - -def construct_format_field_str(fname, fspec, conv): - """ - Constructs a format field string from the field name, spec, and - conversion character (``fname``, ``fspec``, ``conv``). See Python - String Formatting for more info. - """ - if fname is None: - return '' - ret = '{' + fname - if conv: - ret += '!' + conv - if fspec: - ret += ':' + fspec - ret += '}' - return ret - - -def split_format_str(fstr): - """Does very basic splitting of a format string, returns a list of - strings. For full tokenization, see :func:`tokenize_format_str`. - - """ - ret = [] - - for lit, fname, fspec, conv in Formatter().parse(fstr): - if fname is None: - ret.append((lit, None)) - continue - field_str = construct_format_field_str(fname, fspec, conv) - ret.append((lit, field_str)) - return ret - - -def infer_positional_format_args(fstr): - """Takes format strings with anonymous positional arguments, (e.g., - "{}" and {:d}), and converts them into numbered ones for explicitness and - compatibility with 2.6. - - Returns a string with the inferred positional arguments. - """ - # TODO: memoize - ret, max_anon = '', 0 - # look for {: or {! or {. or {[ or {} - start, end, prev_end = 0, 0, 0 - for match in _pos_farg_re.finditer(fstr): - start, end, group = match.start(), match.end(), match.group() - if prev_end < start: - ret += fstr[prev_end:start] - prev_end = end - if group == '{{' or group == '}}': - ret += group - continue - ret += '{%s%s' % (max_anon, group[1:]) - max_anon += 1 - ret += fstr[prev_end:] - return ret - - -# This approach is hardly exhaustive but it works for most builtins -_INTCHARS = 'bcdoxXn' -_FLOATCHARS = 'eEfFgGn%' -_TYPE_MAP = dict([(x, int) for x in _INTCHARS] + - [(x, float) for x in _FLOATCHARS]) -_TYPE_MAP['s'] = str - - -def get_format_args(fstr): - """ - Turn a format string into two lists of arguments referenced by the - format string. One is positional arguments, and the other is named - arguments. Each element of the list includes the name and the - nominal type of the field. - - # >>> get_format_args("{noun} is {1:d} years old{punct}") - # ([(1, <type 'int'>)], [('noun', <type 'str'>), ('punct', <type 'str'>)]) - - # XXX: Py3k - >>> get_format_args("{noun} is {1:d} years old{punct}") == \ - ([(1, int)], [('noun', str), ('punct', str)]) - True - """ - # TODO: memoize - formatter = Formatter() - fargs, fkwargs, _dedup = [], [], set() - - def _add_arg(argname, type_char='s'): - if argname not in _dedup: - _dedup.add(argname) - argtype = _TYPE_MAP.get(type_char, str) # TODO: unicode - try: - fargs.append((int(argname), argtype)) - except ValueError: - fkwargs.append((argname, argtype)) - - for lit, fname, fspec, conv in formatter.parse(fstr): - if fname is not None: - type_char = fspec[-1:] - fname_list = re.split('[.[]', fname) - if len(fname_list) > 1: - raise ValueError('encountered compound format arg: %r' % fname) - try: - base_fname = fname_list[0] - assert base_fname - except (IndexError, AssertionError): - raise ValueError('encountered anonymous positional argument') - _add_arg(fname, type_char) - for sublit, subfname, _, _ in formatter.parse(fspec): - # TODO: positional and anon args not allowed here. - if subfname is not None: - _add_arg(subfname) - return fargs, fkwargs - - -def tokenize_format_str(fstr, resolve_pos=True): - """Takes a format string, turns it into a list of alternating string - literals and :class:`BaseFormatField` tokens. By default, also - infers anonymous positional references into explicit, numbered - positional references. To disable this behavior set *resolve_pos* - to ``False``. - """ - ret = [] - if resolve_pos: - fstr = infer_positional_format_args(fstr) - formatter = Formatter() - for lit, fname, fspec, conv in formatter.parse(fstr): - if lit: - ret.append(lit) - if fname is None: - continue - ret.append(BaseFormatField(fname, fspec, conv)) - return ret - - -class BaseFormatField(object): - """A class representing a reference to an argument inside of a - bracket-style format string. For instance, in ``"{greeting}, - world!"``, there is a field named "greeting". - - These fields can have many options applied to them. See the - Python docs on `Format String Syntax`_ for the full details. - - .. _Format String Syntax: https://docs.python.org/2/library/string.html#string-formatting - """ - def __init__(self, fname, fspec='', conv=None): - self.set_fname(fname) - self.set_fspec(fspec) - self.set_conv(conv) - - def set_fname(self, fname): - "Set the field name." - - path_list = re.split('[.[]', fname) # TODO - - self.base_name = path_list[0] - self.fname = fname - self.subpath = path_list[1:] - self.is_positional = not self.base_name or self.base_name.isdigit() - - def set_fspec(self, fspec): - "Set the field spec." - fspec = fspec or '' - subfields = [] - for sublit, subfname, _, _ in Formatter().parse(fspec): - if subfname is not None: - subfields.append(subfname) - self.subfields = subfields - self.fspec = fspec - self.type_char = fspec[-1:] - self.type_func = _TYPE_MAP.get(self.type_char, str) - - def set_conv(self, conv): - """There are only two built-in converters: ``s`` and ``r``. They are - somewhat rare and appearlike ``"{ref!r}"``.""" - # TODO - self.conv = conv - self.conv_func = None # TODO - - @property - def fstr(self): - "The current state of the field in string format." - return construct_format_field_str(self.fname, self.fspec, self.conv) - - def __repr__(self): - cn = self.__class__.__name__ - args = [self.fname] - if self.conv is not None: - args.extend([self.fspec, self.conv]) - elif self.fspec != '': - args.append(self.fspec) - args_repr = ', '.join([repr(a) for a in args]) - return '%s(%s)' % (cn, args_repr) - - def __str__(self): - return self.fstr - - -_UNSET = object() - - -class DeferredValue(object): - """:class:`DeferredValue` is a wrapper type, used to defer computing - values which would otherwise be expensive to stringify and - format. This is most valuable in areas like logging, where one - would not want to waste time formatting a value for a log message - which will subsequently be filtered because the message's log - level was DEBUG and the logger was set to only emit CRITICAL - messages. - - The :class:``DeferredValue`` is initialized with a callable that - takes no arguments and returns the value, which can be of any - type. By default DeferredValue only calls that callable once, and - future references will get a cached value. This behavior can be - disabled by setting *cache_value* to ``False``. - - Args: - - func (function): A callable that takes no arguments and - computes the value being represented. - cache_value (bool): Whether subsequent usages will call *func* - again. Defaults to ``True``. - - >>> import sys - >>> dv = DeferredValue(lambda: len(sys._current_frames())) - >>> output = "works great in all {0} threads!".format(dv) - - PROTIP: To keep lines shorter, use: ``from formatutils import - DeferredValue as DV`` - """ - def __init__(self, func, cache_value=True): - self.func = func - self.cache_value = True - self._value = _UNSET - - def get_value(self): - """Computes, optionally caches, and returns the value of the - *func*. If ``get_value()`` has been called before, a cached - value may be returned depending on the *cache_value* option - passed to the constructor. - """ - if self._value is not _UNSET and self.cache_value: - value = self._value - else: - value = self.func() - if self.cache_value: - self._value = value - return value - - def __int__(self): - return int(self.get_value()) - - def __float__(self): - return float(self.get_value()) - - def __str__(self): - return str(self.get_value()) - - def __unicode__(self): - return unicode(self.get_value()) - - def __repr__(self): - return repr(self.get_value()) - - def __format__(self, fmt): - value = self.get_value() - - pt = fmt[-1:] # presentation type - type_conv = _TYPE_MAP.get(pt, str) - - try: - return value.__format__(fmt) - except (ValueError, TypeError): - # TODO: this may be overkill - return type_conv(value).__format__(fmt) - -# end formatutils.py
