Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I type hint a filename in a function?

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
like image 510
576i Avatar asked Nov 21 '18 17:11

576i


People also ask

How do you type hints in Python?

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.

What are type hints?

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.

What is typing in Python?

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.

What is type annotation in Python?

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.


3 Answers

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].

like image 160
lxop Avatar answered Oct 01 '22 03:10

lxop


PEP 519 recommends using typing.Union[str, bytes, os.PathLike]

like image 36
Eric Langlois Avatar answered Oct 01 '22 03:10

Eric Langlois


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].

like image 30
Remmar00 Avatar answered Oct 01 '22 05:10

Remmar00