• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jnothman / UpSetPlot / 493

pending completion
493

push

travis-ci-com

web-flow
Allow show_percentage to be specified with format string (#199)

46 of 46 new or added lines in 3 files covered. (100.0%)

1152 of 1181 relevant lines covered (97.54%)

2.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.97
/upsetplot/util.py
1
"""Generic utilities"""
2
import re
3✔
3

4
# The below is adapted from an answer to
5
# https://stackoverflow.com/questions/66822945
6
# by Andrius at https://stackoverflow.com/a/66869159/1017546
7
# Reproduced under the CC-BY-SA 3.0 licence.
8

9
ODD_REPEAT_PATTERN = r'((?<!{c}){c}({c}{c})*(?!{c}))'
3✔
10
EVEN_REPEAT_PATTERN = r'(?<!{c})({c}{c})+(?!{c})'
3✔
11
SPECIFIER_PATTERN = r'[^(]*[diouxXeEfFgGcs]'  # TODO: handle r
3✔
12

13

14
def __to_new_format(fmt: str, named=True):
3✔
15
    def to_named_fmt(fmt):
3✔
16
        pattern = rf'{odd_perc_pattern}\((.*?)\)({SPECIFIER_PATTERN})'
×
17
        match = re.search(pattern, fmt)
×
18
        while match:
×
19
            # Only care about placeholder group here.
20
            __, __, placeholder, specifier = match.groups()
×
21
            fmt = fmt.replace(
×
22
                f'%({placeholder}){specifier}',
23
                f'{{{placeholder}:{specifier}}}'
24
            )
25
            match = re.search(pattern, fmt)
×
26
        return fmt
×
27

28
    def to_pos_fmt(fmt):
3✔
29
        even_perc_pattern = EVEN_REPEAT_PATTERN.format(c='%')
3✔
30
        pattern = rf'{even_perc_pattern}s'
3✔
31
        # When positional placeholder has even amount of percents, it
32
        # will be treated as not having enough arguments passed.
33
        if re.search(pattern, fmt):
3✔
34
            raise TypeError(
×
35
                'not all arguments converted during string formatting'
36
            )
37
        return re.sub(
3✔
38
            rf"%({SPECIFIER_PATTERN})",
39
            lambda sub_match: f'{{:{sub_match.group(1)}}}',
40
            fmt
41
        )
42

43
    odd_perc_pattern = ODD_REPEAT_PATTERN.format(c='%')
3✔
44
    # Escape `{` and `}`, because new formatting uses it.
45
    fmt = fmt.replace('{', '{{').replace('}', '}}')
3✔
46
    fmt = to_named_fmt(fmt) if named else to_pos_fmt(fmt)
3✔
47
    # If we find odd number of occurring percentage symbols, it means
48
    # those were not escaped and we can't finish conversion.
49
    if re.search(odd_perc_pattern, fmt):
3✔
50
        raise ValueError('incomplete format')
3✔
51
    return fmt.replace('%%', '%')
3✔
52

53

54
def to_new_named_format(fmt: str) -> str:
3✔
55
    """Convert old style named formatting to new style formatting.
56
    For example: '%(x)s - %%%(y)s' -> '{x} - %{y}'
57
    Args:
58
        fmt: old style formatting to convert.
59
    Returns:
60
        new style formatting.
61
    """
62
    return __to_new_format(fmt, named=True)
×
63

64

65
def to_new_pos_format(fmt: str) -> str:
3✔
66
    """Convert old style positional formatting to new style formatting.
67
    For example: '%s - %%%s' -> '{} - %{}'
68
    Args:
69
        fmt: old style formatting to convert.
70
    Returns:
71
        new style formatting.
72
    """
73
    return __to_new_format(fmt, named=False)
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc