def format_field(self, value, format_spec): val = value if isinstance(val, (list, tuple)): val = self.format_field(random.choice(val), format_spec) if isinstance(val, dict): val = self.format_field(list(val.values()), format_spec) return Formatter.format_field(self, val, format_spec)
def _parse_with_formatting(string, args, kwargs, *, recursion_depth=2, auto_arg_index=0, recursive=False): # This function re-implements Formatter._vformat() if recursion_depth < 0: raise ValueError("Max string recursion exceeded") formatter = Formatter() parser = AnsiParser() for literal_text, field_name, format_spec, conversion in formatter.parse( string): parser.feed(literal_text, raw=recursive) if field_name is not None: if field_name == "": if auto_arg_index is False: raise ValueError("cannot switch from manual field " "specification to automatic field " "numbering") field_name = str(auto_arg_index) auto_arg_index += 1 elif field_name.isdigit(): if auto_arg_index: raise ValueError("cannot switch from manual field " "specification to automatic field " "numbering") auto_arg_index = False obj, _ = formatter.get_field(field_name, args, kwargs) obj = formatter.convert_field(obj, conversion) format_spec, auto_arg_index = Colorizer._parse_with_formatting( format_spec, args, kwargs, recursion_depth=recursion_depth - 1, auto_arg_index=auto_arg_index, recursive=True, ) formatted = formatter.format_field(obj, format_spec) parser.feed(formatted, raw=True) tokens = parser.done() if recursive: return AnsiParser.strip(tokens), auto_arg_index return tokens
def format_field(self, value, format_spec): fss = format_spec.split(':') if 1 <= len(fss) <= 3: if len(fss) == 1: return colorize(value, color=fss[0]) elif len(fss) == 2: return colorize(value, color=fss[0], bgcolor=fss[1]) elif len(fss) == 3: return colorize(value, color=fss[0], bgcolor=fss[1], effects=fss[2]) # Return original formatter if spec is wrong return Formatter.format_field(self, value, format_spec)
def formatMentions(cls, text, *args, **kwargs): """Like `str.format`, but takes tuples with a thread id and text instead. Returns a `Message` object, with the formatted string and relevant mentions. ``` >>> Message.formatMentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")) <Message (None): "Hey 'Peter'! My name is Michael", mentions=[<Mention 1234: offset=4 length=7>, <Mention 4321: offset=24 length=7>] emoji_size=None attachments=[]> >>> Message.formatMentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter")) <Message (None): 'Hey Peter! My name is Michael', mentions=[<Mention 4321: offset=4 length=5>, <Mention 1234: offset=22 length=7>] emoji_size=None attachments=[]> ``` """ result = "" mentions = list() offset = 0 f = Formatter() field_names = [field_name[1] for field_name in f.parse(text)] automatic = "" in field_names i = 0 for (literal_text, field_name, format_spec, conversion) in f.parse(text): offset += len(literal_text) result += literal_text if field_name is None: continue if field_name == "": field_name = str(i) i += 1 elif automatic and field_name.isdigit(): raise ValueError( "cannot switch from automatic field numbering to manual field specification" ) thread_id, name = f.get_field(field_name, args, kwargs)[0] if format_spec: name = f.format_field(name, format_spec) if conversion: name = f.convert_field(name, conversion) result += name mentions.append( Mention(thread_id=thread_id, offset=offset, length=len(name))) offset += len(name) message = cls(text=result, mentions=mentions) return message
def format_mentions(text, *args, **kwargs): """Like `str.format`, but takes tuples with a thread id and text instead. Return a tuple, with the formatted string and relevant mentions. >>> Message.format_mentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")) ("Hey 'Peter'! My name is Michael", [Mention(thread_id=1234, offset=4, length=7), Mention(thread_id=4321, offset=24, length=7)]) >>> Message.format_mentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter")) ('Hey Peter! My name is Michael', [Mention(thread_id=4321, offset=4, length=5), Mention(thread_id=1234, offset=22, length=7)]) """ result = "" mentions = list() offset = 0 f = Formatter() field_names = [field_name[1] for field_name in f.parse(text)] automatic = "" in field_names i = 0 for (literal_text, field_name, format_spec, conversion) in f.parse(text): offset += len(literal_text) result += literal_text if field_name is None: continue if field_name == "": field_name = str(i) i += 1 elif automatic and field_name.isdigit(): raise ValueError( "cannot switch from automatic field numbering to manual field specification" ) thread_id, name = f.get_field(field_name, args, kwargs)[0] if format_spec: name = f.format_field(name, format_spec) if conversion: name = f.convert_field(name, conversion) result += name mentions.append( Mention(thread_id=thread_id, offset=offset, length=len(name))) offset += len(name) return result, mentions
def format_field(self, value, spec): if isinstance(value, dict) or isinstance(value, list): return json.dumps(value) return Formatter.format_field(self, value, spec)
def reverse_format(format_string, resolved_string): """ Reverse the string method format. Given format_string and resolved_string, find arguments that would give ``format_string.format(**arguments) == resolved_string`` Parameters ---------- format_string : str Format template string as used with str.format method resolved_string : str String with same pattern as format_string but with fields filled out. Returns ------- args : dict Dict of the form {field_name: value} such that ``format_string.(**args) == resolved_string`` Examples -------- >>> reverse_format('data_{year}_{month}_{day}.csv', 'data_2014_01_03.csv') {'year': '2014', 'month': '01', 'day': '03'} >>> reverse_format('data_{year:d}_{month:d}_{day:d}.csv', 'data_2014_01_03.csv') {'year': 2014, 'month': 1, 'day': 3} >>> reverse_format('data_{date:%Y_%m_%d}.csv', 'data_2016_10_01.csv') {'date': datetime.datetime(2016, 10, 1, 0, 0)} >>> reverse_format('{state:2}{zip:5}', 'PA19104') {'state': 'PA', 'zip': '19104'} See also -------- str.format : method that this reverses reverse_formats : method for reversing a list of strings using one pattern """ from string import Formatter from datetime import datetime fmt = Formatter() args = {} # ensure that format_string is in posix format format_string = make_path_posix(format_string) # split the string into bits literal_texts, field_names, format_specs, conversions = zip(*fmt.parse(format_string)) if not any(field_names): return {} for i, conversion in enumerate(conversions): if conversion: raise ValueError(('Conversion not allowed. Found on {}.' .format(field_names[i]))) # ensure that resolved string is in posix format resolved_string = make_path_posix(resolved_string) # get a list of the parts that matter bits = _get_parts_of_format_string(resolved_string, literal_texts, format_specs) for i, (field_name, format_spec) in enumerate(zip(field_names, format_specs)): if field_name: try: if format_spec.startswith('%'): args[field_name] = datetime.strptime(bits[i], format_spec) elif format_spec[-1] in list('bcdoxX'): args[field_name] = int(bits[i]) elif format_spec[-1] in list('eEfFgGn'): args[field_name] = float(bits[i]) elif format_spec[-1] == '%': args[field_name] = float(bits[i][:-1])/100 else: args[field_name] = fmt.format_field(bits[i], format_spec) except: args[field_name] = bits[i] return args
description=''): pub = Publisher(reader, parser, writer, settings=None) pub.set_components(reader_name, parser_name, writer_name) output = pub.publish(argv, usage, description, config_section=None, enable_exit_status=True) return output formatter = Formatter() #self = self.vformat(format_string, args, kwargs) to_r = formatter.convert_field(value='3', conversion='r') formatter.format_field(value=+43000, format_spec='> 4,.0F') ALLOWED_TYPES = parse.ALLOWED_TYPES def print_types(): results = dict() for TYPE in ALLOWED_TYPES: expression = '{:' + TYPE + '}' results[TYPE] = parse.compile(expression)._expression return results extract = '[[fill]align][0][width][.precision][type]' e = parse.extract_format('3>03.2e', None) n = parse.extract_format('x^03.2n', '')
def format_field(self, value, spec): t = type(value) if t == dict or t == list: return json.dumps(value) return Formatter.format_field(self, value, spec)