How to Fix PyCharm's "Unexpected type(s): (str | None)" Type-Hint Error
Understanding the PyCharm Type-Hinting Error
PyCharm's static type checker is incredibly powerful, but it can occasionally produce head-scratching warnings. If you are seeing the error Unexpected type(s): (str | None) Possible type(s): (LiteralString) (str), you are encountering a type-narrowing limitation in PyCharm's code analysis engine.
Why is This Error Happening?
In your code, filename is defined as an optional type: str | None. Even though you added an if filename: check, PyCharm fails to narrow the type down from str | None to just str inside the block. This usually happens for two reasons:
- Truthiness vs. Identity: The check
if filename:checks for truthiness (excluding empty strings""andNone). PyCharm's type checker sometimes struggles to propagate this truthiness narrowing through string operations like concatenation ("files/" + filename). - Redundant Self-Assignment: The line
filename = filenamecan confuse PyCharm's control-flow analysis, resetting its understanding of the variable's narrowed type.
How to Fix It (3 Solutions)
1. Use an Explicit is not None Check
The most robust way to narrow an optional type in Python is using an explicit identity check. This tells the type checker unambiguously that the variable is not None.
filename: str | None = None
# ...
if filename is not None:
# PyCharm now knows 'filename' is strictly 'str'
with open("files/" + filename, "wb") as f:
pass2. Use pathlib (Modern & Recommended)
Instead of manually concatenating paths with strings (which is prone to platform-specific bugs, like using backslashes on Windows vs. forward slashes on Linux), use Python's built-in pathlib library. It integrates flawlessly with modern type checkers.
from pathlib import Path
filename: str | None = None
# ...
if filename is not None:
file_path = Path("files") / filename
with open(file_path, "wb") as f:
pass3. Use an Explicit Type Assertion
If you are absolutely sure the variable cannot be None at this point in the execution, you can use an assert statement. This acts as both a runtime safety check and a type-hinting guarantee for PyCharm.
filename: str | None = None
# ...
assert filename is not None, "Filename must be provided"
with open("files/" + filename, "wb") as f:
passSummary
To resolve this warning, avoid relying on implicit truthiness checks (if filename:) for type narrowing when performing string concatenation, remove redundant self-assignments, and adopt pathlib for modern, type-safe path manipulation.