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

zopefoundation / RestrictedPython / 18617392201

18 Oct 2025 03:17PM UTC coverage: 97.829% (-0.9%) from 98.772%
18617392201

Pull #303

github

loechel
readd Python 3.9 support
Pull Request #303: Type Annotations for RestrictedPython

215 of 235 branches covered (91.49%)

150 of 176 new or added lines in 5 files covered. (85.23%)

7 existing lines in 2 files now uncovered.

2524 of 2580 relevant lines covered (97.83%)

0.98 hits per line

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

41.18
/tests/transformer/test_tstring.py
1
import pytest
1✔
2

3
from RestrictedPython import compile_restricted_exec
1✔
4
from RestrictedPython._compat import IS_PY314_OR_GREATER
1✔
5
from RestrictedPython.Eval import default_guarded_getattr
1✔
6
from RestrictedPython.Eval import default_guarded_getiter
1✔
7
from RestrictedPython.PrintCollector import PrintCollector
1✔
8

9

10
if IS_PY314_OR_GREATER:
1!
NEW
11
    from string.templatelib import Template
×
12

13

14
@pytest.mark.skipif(
1✔
15
    not IS_PY314_OR_GREATER,
16
    reason="t-strings were added in Python 3.14.",
17
)
18
def test_transform():
1✔
19
    """It compiles a function call successfully and returns the used name."""
20

NEW
21
    result = compile_restricted_exec('a = t"{max([1, 2, 3])}"')
×
NEW
22
    assert result.errors == ()
×
NEW
23
    assert result.warnings == [
×
24
        'Line 1: TemplateStr statements are not yet allowed, please use f-strings or a real template engine instead.']  # NOQA: E501
NEW
25
    assert result.code is not None
×
NEW
26
    loc = {}
×
NEW
27
    exec(result.code, {}, loc)
×
NEW
28
    template = loc['a']
×
NEW
29
    assert isinstance(template, Template)
×
NEW
30
    assert template.values == (3, )
×
NEW
31
    assert result.used_names == {'max': True}
×
32

33

34
@pytest.mark.skipif(
1✔
35
    not IS_PY314_OR_GREATER,
36
    reason="t-strings were added in Python 3.14.",
37
)
38
def test_visit_invalid_variable_name():
1✔
39
    """Accessing private attributes is forbidden.
40

41
    This is just a smoke test to validate that restricted exec is used
42
    in the run-time evaluation of t-strings.
43
    """
NEW
44
    result = compile_restricted_exec('t"{__init__}"')
×
NEW
45
    assert result.errors == (
×
46
        'Line 1: "__init__" is an invalid variable name because it starts with "_"',  # NOQA: E501
47
    )
48

49

50
t_string_self_documenting_expressions_example = """
1✔
51
from datetime import date
52
from string.templatelib import Template, Interpolation
53

54
user = 'eric_idle'
55
member_since = date(1975, 7, 31)
56

57
def render_template(template: Template) -> str:
58
    result = ''
59
    for part in template:
60
        if isinstance(part, Interpolation):
61
            if isinstance(part.value, str):
62
                result += part.value.upper()
63
            else:
64
                result += str(part.value)
65
        else:
66
            result += part.lower()
67
    return result
68

69
print(render_template(t'The User {user} is a member since {member_since}'))
70
"""
71

72

73
@pytest.mark.skipif(
1✔
74
    not IS_PY314_OR_GREATER,
75
    reason="t-strings were added in Python 3.14.",
76
)
77
def test_t_string_self_documenting_expressions():
1✔
78
    """Checks if t-string self-documenting expressions is checked."""
NEW
79
    result = compile_restricted_exec(
×
80
        t_string_self_documenting_expressions_example,
81
    )
82
    # assert result.errors == (
83
    #   'Line 13: TemplateStr statements are not allowed.',
84
    # )
85
    # assert result.warnings == [
86
    #     'Line 13: TemplateStr statements are not yet allowed, please use '
87
    #     'f-strings or a real template engine instead.',
88
    #     "Line None: Prints, but never reads 'printed' variable."
89
    # ]
90
    # assert result.code is None
NEW
91
    assert result.errors == ()
×
NEW
92
    assert result.warnings == [
×
93
        'Line 20: TemplateStr statements are not yet allowed, '
94
        'please use f-strings or a real template engine instead.',
95
        "Line None: Prints, but never reads 'printed' variable."]
NEW
96
    assert result.code is not None
×
97

NEW
98
    glb = {
×
99
        '_print_': PrintCollector,
100
        '_getattr_': default_guarded_getattr,
101
        '_getiter_': default_guarded_getiter,
102
        '_inplacevar_': lambda x, y, z: y + z,
103
    }
NEW
104
    exec(result.code, glb)
×
NEW
105
    assert glb['_print']() == "the user ERIC_IDLE is a member since 1975-07-31\n"  # NOQA: E501
×
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