Make ``JoinedStr`` nodes ``Uninferable`` when the ``FormattedValue`` is ``Uninferable``. (#2944)
Ensure ``ast.JoinedStr`` nodes are ``Uninferable`` when the ``ast.FormattedValue`` is
``Uninferable``. This prevents ``unexpected-keyword-arg`` messages in Pylint
where the ``Uninferable`` string appeared in function arguments that were
constructed dynamically.
Closes pylint-dev/pylint#10822
diff --git a/ChangeLog b/ChangeLog
index 35f673d..37e4b91 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,13 @@
============================
Release date: TBA
+* Ensure ``ast.JoinedStr`` nodes are ``Uninferable`` when the ``ast.FormattedValue`` is
+ ``Uninferable``. This prevents ``unexpected-keyword-arg`` messages in Pylint
+ where the ``Uninferable`` string appeared in function arguments that were
+ constructed dynamically.
+
+ Closes pylint-dev/pylint#10822
+
* Add support for type constraints (`isinstance(x, y)`) in inference.
Closes pylint-dev/pylint#1162
diff --git a/astroid/nodes/node_classes.py b/astroid/nodes/node_classes.py
index 7f0887b..88e62fc 100644
--- a/astroid/nodes/node_classes.py
+++ b/astroid/nodes/node_classes.py
@@ -4740,6 +4740,9 @@
uninferable_already_generated = True
continue
for value in self.value.infer(context, **kwargs):
+ if value is util.Uninferable:
+ yield util.Uninferable
+ return
value_to_format = value
if isinstance(value, Const):
value_to_format = value.value
diff --git a/tests/test_inference.py b/tests/test_inference.py
index 31a4f7d..5f6478a 100644
--- a/tests/test_inference.py
+++ b/tests/test_inference.py
@@ -7154,3 +7154,21 @@
inferred[0].value.startswith(expected)
else:
assert inferred[0] is Uninferable
+
+
+def test_joined_str_uninferable() -> None:
+ """`thing` is not known, therefore the joinedstring should be
+ Uninferable
+ """
+ code = """
+ def hey(thing):
+ return thing
+
+ f"Hello {hey()}"
+ """
+ joined_str = extract_node(code)
+ constant_value, formatted_value = joined_str.values
+ assert constant_value.value == "Hello "
+ assert formatted_value.value.as_string() == "hey()"
+ inferred = next(joined_str.infer())
+ assert inferred is util.Uninferable