@@ -4673,6 +4673,37 @@ def get_children(self):
46734673 if self .format_spec is not None :
46744674 yield self .format_spec
46754675
4676+ def _infer (
4677+ self , context : InferenceContext | None = None , ** kwargs : Any
4678+ ) -> Generator [InferenceResult , None , InferenceErrorInfo | None ]:
4679+ if self .format_spec is None :
4680+ yield from self .value .infer (context , ** kwargs )
4681+ return
4682+ uninferable_already_generated = False
4683+ for format_spec in self .format_spec .infer (context , ** kwargs ):
4684+ if not isinstance (format_spec , Const ):
4685+ if not uninferable_already_generated :
4686+ yield util .Uninferable
4687+ uninferable_already_generated = True
4688+ continue
4689+ for value in self .value .infer (context , ** kwargs ):
4690+ if not isinstance (value , Const ):
4691+ if not uninferable_already_generated :
4692+ yield util .Uninferable
4693+ uninferable_already_generated = True
4694+ continue
4695+ formatted = format (value .value , format_spec .value )
4696+ yield Const (
4697+ formatted ,
4698+ lineno = self .lineno ,
4699+ col_offset = self .col_offset ,
4700+ end_lineno = self .end_lineno ,
4701+ end_col_offset = self .end_col_offset ,
4702+ )
4703+
4704+
4705+ MISSING_VALUE = "{MISSING_VALUE}"
4706+
46764707
46774708class JoinedStr (NodeNG ):
46784709 """Represents a list of string expressions to be joined.
@@ -4734,6 +4765,34 @@ def postinit(self, values: list[NodeNG] | None = None) -> None:
47344765 def get_children (self ):
47354766 yield from self .values
47364767
4768+ def _infer (
4769+ self , context : InferenceContext | None = None , ** kwargs : Any
4770+ ) -> Generator [InferenceResult , None , InferenceErrorInfo | None ]:
4771+ yield from self ._infer_from_values (self .values , context )
4772+
4773+ @classmethod
4774+ def _infer_from_values (
4775+ cls , nodes : list [NodeNG ], context : InferenceContext | None = None , ** kwargs : Any
4776+ ) -> Generator [InferenceResult , None , InferenceErrorInfo | None ]:
4777+ if len (nodes ) == 1 :
4778+ yield from nodes [0 ]._infer (context , ** kwargs )
4779+ return
4780+ uninferable_already_generated = False
4781+ for prefix in nodes [0 ]._infer (context , ** kwargs ):
4782+ for suffix in cls ._infer_from_values (nodes [1 :], context , ** kwargs ):
4783+ result = ""
4784+ for node in (prefix , suffix ):
4785+ if isinstance (node , Const ):
4786+ result += str (node .value )
4787+ continue
4788+ result += MISSING_VALUE
4789+ if MISSING_VALUE in result :
4790+ if not uninferable_already_generated :
4791+ uninferable_already_generated = True
4792+ yield util .Uninferable
4793+ else :
4794+ yield Const (result )
4795+
47374796
47384797class NamedExpr (_base_nodes .AssignTypeNode ):
47394798 """Represents the assignment from the assignment expression
0 commit comments