Remove stringformat.py, it's unused
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -10,7 +10,7 @@ runtests: | |||||||
| 	coverage run --branch --source=compressor `which django-admin.py` test --settings=compressor.test_settings compressor | 	coverage run --branch --source=compressor `which django-admin.py` test --settings=compressor.test_settings compressor | ||||||
|  |  | ||||||
| coveragereport: | coveragereport: | ||||||
| 	coverage report --omit=compressor/test*,compressor/filters/jsmin/rjsmin*,compressor/filters/cssmin/cssmin*,compressor/utils/stringformat* | 	coverage report --omit=compressor/test*,compressor/filters/jsmin/rjsmin*,compressor/filters/cssmin/cssmin* | ||||||
|  |  | ||||||
| test: flake8 runtests coveragereport | test: flake8 runtests coveragereport | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,260 +0,0 @@ | |||||||
| # -*- coding: utf-8 -*- |  | ||||||
| """Advanced string formatting for Python >= 2.4. |  | ||||||
|  |  | ||||||
| An implementation of the advanced string formatting (PEP 3101). |  | ||||||
|  |  | ||||||
| Author: Florent Xicluna |  | ||||||
| """ |  | ||||||
|  |  | ||||||
| from __future__ import unicode_literals |  | ||||||
|  |  | ||||||
| import re |  | ||||||
|  |  | ||||||
| from django.utils import six |  | ||||||
|  |  | ||||||
| _format_str_re = re.compile( |  | ||||||
|     r'((?<!{)(?:{{)+'                       # '{{' |  | ||||||
|     r'|(?:}})+(?!})'                        # '}} |  | ||||||
|     r'|{(?:[^{](?:[^{}]+|{[^{}]*})*)?})'    # replacement field |  | ||||||
| ) |  | ||||||
| _format_sub_re = re.compile(r'({[^{}]*})')  # nested replacement field |  | ||||||
| _format_spec_re = re.compile( |  | ||||||
|     r'((?:[^{}]?[<>=^])?)'      # alignment |  | ||||||
|     r'([-+ ]?)'                 # sign |  | ||||||
|     r'(#?)' r'(\d*)' r'(,?)'    # base prefix, minimal width, thousands sep |  | ||||||
|     r'((?:\.\d+)?)'             # precision |  | ||||||
|     r'(.?)$'                    # type |  | ||||||
| ) |  | ||||||
| _field_part_re = re.compile( |  | ||||||
|     r'(?:(\[)|\.|^)'            # start or '.' or '[' |  | ||||||
|     r'((?(1)[^]]*|[^.[]*))'     # part |  | ||||||
|     r'(?(1)(?:\]|$)([^.[]+)?)'  # ']' and invalid tail |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| _format_str_sub = _format_str_re.sub |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _is_integer(value): |  | ||||||
|     return hasattr(value, '__index__') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _strformat(value, format_spec=""): |  | ||||||
|     """Internal string formatter. |  | ||||||
|  |  | ||||||
|     It implements the Format Specification Mini-Language. |  | ||||||
|     """ |  | ||||||
|     m = _format_spec_re.match(str(format_spec)) |  | ||||||
|     if not m: |  | ||||||
|         raise ValueError('Invalid conversion specification') |  | ||||||
|     align, sign, prefix, width, comma, precision, conversion = m.groups() |  | ||||||
|     is_numeric = hasattr(value, '__float__') |  | ||||||
|     is_integer = is_numeric and _is_integer(value) |  | ||||||
|     if prefix and not is_integer: |  | ||||||
|         raise ValueError('Alternate form (#) not allowed in %s format ' |  | ||||||
|                          'specifier' % (is_numeric and 'float' or 'string')) |  | ||||||
|     if is_numeric and conversion == 'n': |  | ||||||
|         # Default to 'd' for ints and 'g' for floats |  | ||||||
|         conversion = is_integer and 'd' or 'g' |  | ||||||
|     elif sign: |  | ||||||
|         if not is_numeric: |  | ||||||
|             raise ValueError("Sign not allowed in string format specifier") |  | ||||||
|         if conversion == 'c': |  | ||||||
|             raise ValueError("Sign not allowed with integer " |  | ||||||
|                              "format specifier 'c'") |  | ||||||
|     if comma: |  | ||||||
|         # TODO: thousand separator |  | ||||||
|         pass |  | ||||||
|     try: |  | ||||||
|         if ((is_numeric and conversion == 's') or (not is_integer and conversion in set('cdoxX'))): |  | ||||||
|             raise ValueError |  | ||||||
|         if conversion == 'c': |  | ||||||
|             conversion = 's' |  | ||||||
|             value = chr(value % 256) |  | ||||||
|         rv = ('%' + prefix + precision + (conversion or 's')) % (value,) |  | ||||||
|     except ValueError: |  | ||||||
|         raise ValueError("Unknown format code %r for object of type %r" % |  | ||||||
|                          (conversion, value.__class__.__name__)) |  | ||||||
|     if sign not in '-' and value >= 0: |  | ||||||
|         # sign in (' ', '+') |  | ||||||
|         rv = sign + rv |  | ||||||
|     if width: |  | ||||||
|         zero = (width[0] == '0') |  | ||||||
|         width = int(width) |  | ||||||
|     else: |  | ||||||
|         zero = False |  | ||||||
|         width = 0 |  | ||||||
|     # Fastpath when alignment is not required |  | ||||||
|     if width <= len(rv): |  | ||||||
|         if not is_numeric and (align == '=' or (zero and not align)): |  | ||||||
|             raise ValueError("'=' alignment not allowed in string format " |  | ||||||
|                              "specifier") |  | ||||||
|         return rv |  | ||||||
|     fill, align = align[:-1], align[-1:] |  | ||||||
|     if not fill: |  | ||||||
|         fill = zero and '0' or ' ' |  | ||||||
|     if align == '^': |  | ||||||
|         padding = width - len(rv) |  | ||||||
|         # tweak the formatting if the padding is odd |  | ||||||
|         if padding % 2: |  | ||||||
|             rv += fill |  | ||||||
|         rv = rv.center(width, fill) |  | ||||||
|     elif align == '=' or (zero and not align): |  | ||||||
|         if not is_numeric: |  | ||||||
|             raise ValueError("'=' alignment not allowed in string format " |  | ||||||
|                              "specifier") |  | ||||||
|         if value < 0 or sign not in '-': |  | ||||||
|             rv = rv[0] + rv[1:].rjust(width - 1, fill) |  | ||||||
|         else: |  | ||||||
|             rv = rv.rjust(width, fill) |  | ||||||
|     elif align in ('>', '=') or (is_numeric and not align): |  | ||||||
|         # numeric value right aligned by default |  | ||||||
|         rv = rv.rjust(width, fill) |  | ||||||
|     else: |  | ||||||
|         rv = rv.ljust(width, fill) |  | ||||||
|     return rv |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _format_field(value, parts, conv, spec, want_bytes=False): |  | ||||||
|     """Format a replacement field.""" |  | ||||||
|     for k, part, _ in parts: |  | ||||||
|         if k: |  | ||||||
|             if part.isdigit(): |  | ||||||
|                 value = value[int(part)] |  | ||||||
|             else: |  | ||||||
|                 value = value[part] |  | ||||||
|         else: |  | ||||||
|             value = getattr(value, part) |  | ||||||
|     if conv: |  | ||||||
|         value = ((conv == 'r') and '%r' or '%s') % (value,) |  | ||||||
|     if hasattr(value, '__format__'): |  | ||||||
|         value = value.__format__(spec) |  | ||||||
|     elif hasattr(value, 'strftime') and spec: |  | ||||||
|         value = value.strftime(str(spec)) |  | ||||||
|     else: |  | ||||||
|         value = _strformat(value, spec) |  | ||||||
|     if want_bytes and isinstance(value, six.text_type): |  | ||||||
|         return str(value) |  | ||||||
|     return value |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class FormattableString(object): |  | ||||||
|     """Class which implements method format(). |  | ||||||
|  |  | ||||||
|     The method format() behaves like str.format() in python 2.6+. |  | ||||||
|  |  | ||||||
|     >>> FormattableString('{a:5}').format(a=42) |  | ||||||
|     ... # Same as '{a:5}'.format(a=42) |  | ||||||
|     '   42' |  | ||||||
|  |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     __slots__ = '_index', '_kwords', '_nested', '_string', 'format_string' |  | ||||||
|  |  | ||||||
|     def __init__(self, format_string): |  | ||||||
|         self._index = 0 |  | ||||||
|         self._kwords = {} |  | ||||||
|         self._nested = {} |  | ||||||
|  |  | ||||||
|         self.format_string = format_string |  | ||||||
|         self._string = _format_str_sub(self._prepare, format_string) |  | ||||||
|  |  | ||||||
|     def __eq__(self, other): |  | ||||||
|         if isinstance(other, FormattableString): |  | ||||||
|             return self.format_string == other.format_string |  | ||||||
|         # Compare equal with the original string. |  | ||||||
|         return self.format_string == other |  | ||||||
|  |  | ||||||
|     def _prepare(self, match): |  | ||||||
|         # Called for each replacement field. |  | ||||||
|         part = match.group(0) |  | ||||||
|         if part[0] == part[-1]: |  | ||||||
|             # '{{' or '}}' |  | ||||||
|             assert part == part[0] * len(part) |  | ||||||
|             return part[:len(part) // 2] |  | ||||||
|         repl = part[1:-1] |  | ||||||
|         field, _, format_spec = repl.partition(':') |  | ||||||
|         literal, sep, conversion = field.partition('!') |  | ||||||
|         if sep and not conversion: |  | ||||||
|             raise ValueError("end of format while looking for " |  | ||||||
|                              "conversion specifier") |  | ||||||
|         if len(conversion) > 1: |  | ||||||
|             raise ValueError("expected ':' after format specifier") |  | ||||||
|         if conversion not in 'rsa': |  | ||||||
|             raise ValueError("Unknown conversion specifier %s" % |  | ||||||
|                              str(conversion)) |  | ||||||
|         name_parts = _field_part_re.findall(literal) |  | ||||||
|         if literal[:1] in '.[': |  | ||||||
|             # Auto-numbering |  | ||||||
|             if self._index is None: |  | ||||||
|                 raise ValueError("cannot switch from manual field " |  | ||||||
|                                  "specification to automatic field numbering") |  | ||||||
|             name = str(self._index) |  | ||||||
|             self._index += 1 |  | ||||||
|             if not literal: |  | ||||||
|                 del name_parts[0] |  | ||||||
|         else: |  | ||||||
|             name = name_parts.pop(0)[1] |  | ||||||
|             if name.isdigit() and self._index is not None: |  | ||||||
|                 # Manual specification |  | ||||||
|                 if self._index: |  | ||||||
|                     raise ValueError("cannot switch from automatic field " |  | ||||||
|                                      "numbering to manual field specification") |  | ||||||
|                 self._index = None |  | ||||||
|         empty_attribute = False |  | ||||||
|         for k, v, tail in name_parts: |  | ||||||
|             if not v: |  | ||||||
|                 empty_attribute = True |  | ||||||
|             if tail: |  | ||||||
|                 raise ValueError("Only '.' or '[' may follow ']' " |  | ||||||
|                                  "in format field specifier") |  | ||||||
|         if name_parts and k == '[' and not literal[-1] == ']': |  | ||||||
|             raise ValueError("Missing ']' in format string") |  | ||||||
|         if empty_attribute: |  | ||||||
|             raise ValueError("Empty attribute in format string") |  | ||||||
|         if '{' in format_spec: |  | ||||||
|             format_spec = _format_sub_re.sub(self._prepare, format_spec) |  | ||||||
|             rv = (name_parts, conversion, format_spec) |  | ||||||
|             self._nested.setdefault(name, []).append(rv) |  | ||||||
|         else: |  | ||||||
|             rv = (name_parts, conversion, format_spec) |  | ||||||
|             self._kwords.setdefault(name, []).append(rv) |  | ||||||
|         return r'%%(%s)s' % id(rv) |  | ||||||
|  |  | ||||||
|     def format(self, *args, **kwargs): |  | ||||||
|         """Same as str.format() and unicode.format() in Python 2.6+.""" |  | ||||||
|         if args: |  | ||||||
|             kwargs.update(dict((str(i), value) |  | ||||||
|                                for (i, value) in enumerate(args))) |  | ||||||
|         # Encode arguments to ASCII, if format string is bytes |  | ||||||
|         want_bytes = isinstance(self._string, str) |  | ||||||
|         params = {} |  | ||||||
|         for name, items in self._kwords.items(): |  | ||||||
|             value = kwargs[name] |  | ||||||
|             for item in items: |  | ||||||
|                 parts, conv, spec = item |  | ||||||
|                 params[str(id(item))] = _format_field(value, parts, conv, spec, |  | ||||||
|                                                       want_bytes) |  | ||||||
|         for name, items in self._nested.items(): |  | ||||||
|             value = kwargs[name] |  | ||||||
|             for item in items: |  | ||||||
|                 parts, conv, spec = item |  | ||||||
|                 spec = spec % params |  | ||||||
|                 params[str(id(item))] = _format_field(value, parts, conv, spec, |  | ||||||
|                                                       want_bytes) |  | ||||||
|         return self._string % params |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def selftest(): |  | ||||||
|     import datetime |  | ||||||
|     F = FormattableString |  | ||||||
|  |  | ||||||
|     assert F("{0:{width}.{precision}s}").format('hello world', |  | ||||||
|              width=8, precision=5) == 'hello   ' |  | ||||||
|  |  | ||||||
|     d = datetime.date(2010, 9, 7) |  | ||||||
|     assert F("The year is {0.year}").format(d) == "The year is 2010" |  | ||||||
|     assert F("Tested on {0:%Y-%m-%d}").format(d) == "Tested on 2010-09-07" |  | ||||||
|     print('Test successful') |  | ||||||
|  |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     selftest() |  | ||||||
		Reference in New Issue
	
	Block a user
	 Johannes Linke
					Johannes Linke