What is a best way in Python to hint a filename, so that it's acceptable to pass anything into a function that you can open as a file?
Especially both strings and files found via Pathlib.
def myfunc(filename: str) -> None:
with open(filename) as f1:
# do something here
Here's how you can add type hints to our function: Add a colon and a data type after each function parameter. Add an arrow ( -> ) and a data type after the function to specify the return data type.
Introduction to Python type hints It means that you need to declare types of variables, parameters, and return values of a function upfront. The predefined types allow the compilers to check the code before compiling and running the program.
Typing defines a standard notation for Python function and variable type annotations. The notation can be used for documenting code in a concise, standard format, and it has been designed to also be used by static and runtime type checkers, static analyzers, IDEs and other tools.
Type annotations — also known as type signatures — are used to indicate the datatypes of variables and input/outputs of functions and methods. In many languages, datatypes are explicitly stated. In these languages, if you don't declare your datatype — the code will not run.
I think what you are looking for is Structural Typing, which is not yet supported. It is proposed in PEP 544.
In the mean time, you could do a half-way effort by annotating with Union[str, bytes, os.PathLike]
.
PEP 519 recommends using typing.Union[str, bytes, os.PathLike]
As Eric said,
PEP 519 recommends using
typing.Union[str, bytes, os.PathLike]
.
and this is the easiest option.
But you should consider also _typeshed.AnyPath
: it supports all kinds of paths in accordance with the different versions, and it is the default typing hint in the built-in library for filenames, such as in the function open()
itself.
Importing it results in your type helper recognising that the input should be a filename, and may help type hinting paths. It has also the variations _typeshed.StrPath
for strings only and _typeshed.BytesPath
for bytestrings only. Here for their definition.
However, you can't just import the typeshed
module, as it doesn't exist at runtime. The easiest solution to this is to import it only during type-checking (because it's the only time you need it):
from typing import TYPE_CHECKING
AnyPath = None
if TYPE_CHECKING:
from _typeshed import AnyPath
Lastly, in the current 3.10 beta build, AnyPath
has been renamed to StrOrBytesPath
, in order to separate the strings and the bytestrings from the paths of the Path module, and another AnyPath wont be seen soon. So, if you are planning to input only str filenames, you can use _typeshed.StrPath
, or just give up and use typing.Union[str, bytes, os.PathLike]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With