Show More
@@ -597,33 +597,52 b' def wrap_paragraphs(text, ncols=80):' | |||
|
597 | 597 | return out_ps |
|
598 | 598 | |
|
599 | 599 | |
|
600 | ||
|
601 | 600 | class EvalFormatter(Formatter): |
|
602 | 601 | """A String Formatter that allows evaluation of simple expressions. |
|
603 | ||
|
604 | Any time a format key is not found in the kwargs, | |
|
605 | it will be tried as an expression in the kwargs namespace. | |
|
606 | ||
|
602 | ||
|
603 | Note that this version interprets a : as specifying a format string (as per | |
|
604 | standard string formatting), so if slicing is required, you must explicitly | |
|
605 | create a slice. | |
|
606 | ||
|
607 | 607 | This is to be used in templating cases, such as the parallel batch |
|
608 | 608 | script templates, where simple arithmetic on arguments is useful. |
|
609 | 609 | |
|
610 | 610 | Examples |
|
611 | 611 | -------- |
|
612 | ||
|
613 | In [1]: f = EvalFormatter() | |
|
614 | In [2]: f.format('{n//4}', n=8) | |
|
615 | Out [2]: '2' | |
|
616 | ||
|
617 | In [3]: f.format("{greeting[slice(2,4)]}", greeting="Hello") | |
|
618 | Out [3]: 'll' | |
|
619 | """ | |
|
620 | def get_field(self, name, args, kwargs): | |
|
621 | v = eval(name, kwargs) | |
|
622 | return v, name | |
|
612 | 623 | |
|
613 | In [1]: f = EvalFormatter() | |
|
624 | class FullEvalFormatter(Formatter): | |
|
625 | """A String Formatter that allows evaluation of simple expressions. | |
|
626 | ||
|
627 | Any time a format key is not found in the kwargs, | |
|
628 | it will be tried as an expression in the kwargs namespace. | |
|
629 | ||
|
630 | Note that this version allows slicing using [1:2], so you cannot specify | |
|
631 | a format string. Use :class:`EvalFormatter` to permit format strings. | |
|
632 | ||
|
633 | Examples | |
|
634 | -------- | |
|
635 | ||
|
636 | In [1]: f = FullEvalFormatter() | |
|
614 | 637 | In [2]: f.format('{n//4}', n=8) |
|
615 | 638 | Out[2]: '2' |
|
616 | ||
|
617 |
In [3]: f.format('{list(range( |
|
|
618 |
Out[3]: '[ |
|
|
639 | ||
|
640 | In [3]: f.format('{list(range(5))[2:4]}') | |
|
641 | Out[3]: '[2, 3]' | |
|
619 | 642 | |
|
620 | 643 | In [4]: f.format('{3*2}') |
|
621 | 644 | Out[4]: '6' |
|
622 | 645 | """ |
|
623 | ||
|
624 | # should we allow slicing by disabling the format_spec feature? | |
|
625 | allow_slicing = True | |
|
626 | ||
|
627 | 646 | # copied from Formatter._vformat with minor changes to allow eval |
|
628 | 647 | # and replace the format_spec code with slicing |
|
629 | 648 | def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): |
@@ -640,12 +659,11 b' class EvalFormatter(Formatter):' | |||
|
640 | 659 | # if there's a field, output it |
|
641 | 660 | if field_name is not None: |
|
642 | 661 | # this is some markup, find the object and do |
|
643 |
# |
|
|
662 | # the formatting | |
|
644 | 663 | |
|
645 |
if |
|
|
664 | if format_spec: | |
|
646 | 665 | # override format spec, to allow slicing: |
|
647 | 666 | field_name = ':'.join([field_name, format_spec]) |
|
648 | format_spec = '' | |
|
649 | 667 | |
|
650 | 668 | # eval the contents of the field for the object |
|
651 | 669 | # to be formatted |
@@ -654,12 +672,8 b' class EvalFormatter(Formatter):' | |||
|
654 | 672 | # do any conversion on the resulting object |
|
655 | 673 | obj = self.convert_field(obj, conversion) |
|
656 | 674 | |
|
657 | # expand the format spec, if needed | |
|
658 | format_spec = self._vformat(format_spec, args, kwargs, | |
|
659 | used_args, recursion_depth-1) | |
|
660 | ||
|
661 | 675 | # format the object and append to the result |
|
662 |
result.append(self.format_field(obj, |
|
|
676 | result.append(self.format_field(obj, '')) | |
|
663 | 677 | |
|
664 | 678 | return ''.join(result) |
|
665 | 679 |
General Comments 0
You need to be logged in to leave comments.
Login now