Skip to content

Fix implicit concatenation of t-string literals with str or bytes - #11635

Open
Henry Su (hsusul) wants to merge 1 commit into
microsoft:mainfrom
hsusul:fix/tstring-str-implicit-concatenation
Open

Fix implicit concatenation of t-string literals with str or bytes#11635
Henry Su (hsusul) wants to merge 1 commit into
microsoft:mainfrom
hsusul:fix/tstring-str-implicit-concatenation

Conversation

@hsusul

Copy link
Copy Markdown
Contributor

Summary

  • CPython 3.14 and PEP 750 reject implicit concatenation of a t-string literal with a str, bytes, or f-string literal (SyntaxError: cannot mix t-string literals with string or bytes literals).
  • Pyright previously accepted mixes such as t"x" "y" and "" t"x", and inferred Template. Adjacent t-string literals (t"a" t"b") remain valid.
  • The check is implemented next to the existing bytes/str implicit-concatenation diagnostic, so mixed t-string concatenations are reported and typed as Unknown.

Reproduction (Python 3.14)

t1 = t"Hello " t"World"  # valid Template
t2 = t"Hello " "World"   # SyntaxError at runtime; Pyright now reports an error
t3 = t"x" + t"y"         # valid
t4 = t"x" + "y"          # TypeError at runtime; already reported via Template.__add__

CPython:

>>> t"a" "b"
SyntaxError: cannot mix t-string literals with string or bytes literals

Root cause

getTypeOfStringList treated any string list containing a t-string as Template, including mixed implicit concatenations. That matched an earlier draft of PEP 750; the final spec and CPython 3.14 disallow Template/str (and Template/bytes) implicit concatenation.

Test plan

  • tstring2.py: valid t-string implicit concat; mix with str, f-string, and bytes; explicit Template + Template vs Template + str
  • npx jest typeEvaluator4.test.ts -t TString --forceExit (pass)
  • npx jest typeEvaluator4.test.ts --forceExit (155 passed)
  • npx jest localizer.test.ts --forceExit (pass)
  • npx jest typeEvaluator8.test.ts -t Strings2 --forceExit from packages/pyright-internal (pass)
  • ESLINT_USE_FLAT_CONFIG=false npx eslint on changed TS files (pass)
  • npx prettier -c on changed TS/JSON files (pass)
  • npx lerna exec --stream --no-bail --ignore=pyright -- "tsc --noEmit" (pass)
  • git diff --check (pass)

Full packages/pyright-internal npm test was not run (includes webpack test server + entire Jest suite). Analyzer coverage for this change is the TString / string-concatenation sample tests.

PEP 750 and CPython 3.14 reject mixing t-string literals with string or bytes literals. Report that mix instead of inferring Template.
@rchiodo

Rich Chiodo (rchiodo) commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

🔒 Automated review in progress — Rich Chiodo (@rchiodo) is auto-reviewing this PR.

t5 = "" t"x"

# This should generate an error.
t6 = t"x" "y"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning · Non-blocking recommendation

The tests only contribute to an aggregate diagnostic count and do not verify the new Unknown recovery type. Add reveal_type coverage for at least one mixed expression so a regression to Template inference cannot pass.

[verified]

@rchiodo

Copy link
Copy Markdown
Collaborator

Non-blocking follow-up: mirror this validation in Pylance's getTypeOfStringList_ForStubLoading counterpart when the Pyright change is vendored.

@rchiodo Rich Chiodo (rchiodo) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved via Review Center.

@rchiodo Rich Chiodo (rchiodo) added the review-auto:approved Automated review: no blocking findings (approval posted). label Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-auto:approved Automated review: no blocking findings (approval posted).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants