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

pantsbuild / pants / 19015773527

02 Nov 2025 05:33PM UTC coverage: 17.872% (-62.4%) from 80.3%
19015773527

Pull #22816

github

web-flow
Merge a12d75757 into 6c024e162
Pull Request #22816: Update Pants internal Python to 3.14

4 of 5 new or added lines in 3 files covered. (80.0%)

28452 existing lines in 683 files now uncovered.

9831 of 55007 relevant lines covered (17.87%)

0.18 hits per line

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

13.33
/src/python/pants/util/eval.py
1
# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
1✔
5

6
from typing import Any
1✔
7

8
from pants.util.strutil import softwrap
1✔
9

10

11
def parse_expression(
1✔
12
    val: str, acceptable_types: type | tuple[type, ...], name: str | None = None
13
) -> Any:
14
    """Attempts to parse the given `val` as a python expression of the specified `acceptable_types`.
15

16
    :param val: A string containing a python expression.
17
    :param acceptable_types: The acceptable types of the parsed object.
18
    :param name: An optional logical name for the value being parsed; ie if the literal val
19
                        represents a person's age, 'age'.
20
    :raises: If `val` is not a valid python literal expression or it is but evaluates to an object
21
             that is not a an instance of one of the `acceptable_types`.
22
    """
23

UNCOV
24
    def format_type(typ):
×
UNCOV
25
        return typ.__name__
×
26

UNCOV
27
    if not isinstance(val, str):
×
28
        raise ValueError(
×
29
            f"The raw `val` is not a str.  Given {val} of type {format_type(type(val))}."
30
        )
31

UNCOV
32
    def get_name():
×
UNCOV
33
        return repr(name) if name else "value"
×
34

UNCOV
35
    def format_raw_value():
×
UNCOV
36
        lines = val.splitlines()
×
UNCOV
37
        for line_number in range(0, len(lines)):
×
UNCOV
38
            lines[line_number] = "{line_number:{width}}: {line}".format(
×
39
                line_number=line_number + 1, line=lines[line_number], width=len(str(len(lines)))
40
            )
UNCOV
41
        return "\n".join(lines)
×
42

UNCOV
43
    try:
×
UNCOV
44
        parsed_value = eval(val)
×
45
    except Exception as e:
×
46
        raise ValueError(
×
47
            softwrap(
48
                f"""
49
                The {get_name()} cannot be evaluated as a literal expression: {e!r}
50
                Given raw value:
51
                  {format_raw_value()}
52
                """
53
            )
54
        )
55

UNCOV
56
    if not isinstance(parsed_value, acceptable_types):
×
57

UNCOV
58
        def iter_types(types):
×
UNCOV
59
            if isinstance(types, type):
×
UNCOV
60
                yield types
×
61
            elif isinstance(types, tuple):
×
62
                for item in types:
×
63
                    yield from iter_types(item)
×
64
            else:
65
                raise ValueError(
×
66
                    f"The given acceptable_types is not a valid type (tuple): {acceptable_types}"
67
                )
68

UNCOV
69
        expected_types = ", ".join(format_type(t) for t in iter_types(acceptable_types))
×
UNCOV
70
        raise ValueError(
×
71
            softwrap(
72
                f"""
73
                The {get_name()} is not of the expected type(s): {expected_types}:
74
                Given the following raw value that evaluated to type {format_type(type(parsed_value))}:
75
                  {format_raw_value()}
76
                """
77
            )
78
        )
UNCOV
79
    return parsed_value
×
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