Skip to content

Commit 8585ce6

Browse files
authored
Fix issue when inferring single-node or non-const JoinedStr (pylint-dev#2578)
1 parent 706fcdb commit 8585ce6

File tree

3 files changed

+51
-18
lines changed

3 files changed

+51
-18
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ What's New in astroid 3.3.4?
1313
============================
1414
Release date: TBA
1515

16+
* Fix regression with f-string inference.
17+
18+
Closes pylint-dev/pylint#9947
19+
1620
* Fix bug with ``manager.clear_cache()`` not fully clearing cache
1721

1822
Refs https://github.com/pylint-dev/pylint/pull/9932#issuecomment-2364985551

astroid/nodes/node_classes.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4685,32 +4685,30 @@ def get_children(self):
46854685
def _infer(
46864686
self, context: InferenceContext | None = None, **kwargs: Any
46874687
) -> Generator[InferenceResult, None, InferenceErrorInfo | None]:
4688-
if self.format_spec is None:
4689-
yield from self.value.infer(context, **kwargs)
4690-
return
4688+
format_specs = Const("") if self.format_spec is None else self.format_spec
46914689
uninferable_already_generated = False
4692-
for format_spec in self.format_spec.infer(context, **kwargs):
4690+
for format_spec in format_specs.infer(context, **kwargs):
46934691
if not isinstance(format_spec, Const):
46944692
if not uninferable_already_generated:
46954693
yield util.Uninferable
46964694
uninferable_already_generated = True
46974695
continue
46984696
for value in self.value.infer(context, **kwargs):
4697+
value_to_format = value
46994698
if isinstance(value, Const):
4700-
try:
4701-
formatted = format(value.value, format_spec.value)
4702-
yield Const(
4703-
formatted,
4704-
lineno=self.lineno,
4705-
col_offset=self.col_offset,
4706-
end_lineno=self.end_lineno,
4707-
end_col_offset=self.end_col_offset,
4708-
)
4709-
continue
4710-
except (ValueError, TypeError):
4711-
# happens when format_spec.value is invalid
4712-
pass # fall through
4713-
if not uninferable_already_generated:
4699+
value_to_format = value.value
4700+
try:
4701+
formatted = format(value_to_format, format_spec.value)
4702+
yield Const(
4703+
formatted,
4704+
lineno=self.lineno,
4705+
col_offset=self.col_offset,
4706+
end_lineno=self.end_lineno,
4707+
end_col_offset=self.end_col_offset,
4708+
)
4709+
continue
4710+
except (ValueError, TypeError):
4711+
# happens when format_spec.value is invalid
47144712
yield util.Uninferable
47154713
uninferable_already_generated = True
47164714
continue

tests/test_inference.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import pytest
2020

2121
from astroid import (
22+
Assign,
2223
Const,
2324
Slice,
2425
Uninferable,
@@ -7388,3 +7389,33 @@ def test_empty_format_spec() -> None:
73887389
assert isinstance(node, nodes.JoinedStr)
73897390

73907391
assert list(node.infer()) == [util.Uninferable]
7392+
7393+
7394+
@pytest.mark.parametrize(
7395+
"source, expected",
7396+
[
7397+
(
7398+
"""
7399+
class Cls:
7400+
# pylint: disable=too-few-public-methods
7401+
pass
7402+
7403+
c_obj = Cls()
7404+
7405+
s1 = f'{c_obj!r}' #@
7406+
""",
7407+
"<__main__.Cls",
7408+
),
7409+
("s1 = f'{5}' #@", "5"),
7410+
],
7411+
)
7412+
def test_joined_str_returns_string(source, expected) -> None:
7413+
"""Regression test for https://github.com/pylint-dev/pylint/issues/9947."""
7414+
node = extract_node(source)
7415+
assert isinstance(node, Assign)
7416+
target = node.targets[0]
7417+
assert target
7418+
inferred = list(target.inferred())
7419+
assert len(inferred) == 1
7420+
assert isinstance(inferred[0], Const)
7421+
inferred[0].value.startswith(expected)

0 commit comments

Comments
 (0)