What is the correct syntax for a Python function/method argument when it has more than one possible type hints?
Question:
import os
def scan(path) -> os.DirEntry :
return os.scandir(path)
What is the correct type hint for the path
argument of this function?
According to documentation:
path may be a path-like object. If path is of type bytes
(directly or
indirectly through the PathLike interface), the type of the name and
path attributes of each os.DirEntry
will be bytes
; in all other
circumstances, they will be of type str
.
So, it can either be a str
or bytes
object representing a path, or an object implementing the os.PathLike
protocol. How do I write these possibilities for the type hinting?
Answers:
You could write these possibilities as:
typing.Union[str, bytes, os.PathLike]
This is mentioned in PEP 519.
… the union of all acceptable path-representing types … can be represented with typing.Union[str, bytes, os.PathLike]
easily enough and the hope is users will slowly gravitate to path objects only
The union type can be denoted as str | bytes | os.PathLike
.
In Python 3.12.x you could do this:
import os
from collections.abc import Iterable
from pathlib import Path
type PT = str | bytes | os.PathLike
def doScan(dirname: PT) -> Iterable[os.DirEntry]:
return os.scandir(dirname)
doScan("mydir")
doScan(b"mydir")
doScan(Path("mydir"))
import os
def scan(path) -> os.DirEntry :
return os.scandir(path)
What is the correct type hint for the path
argument of this function?
According to documentation:
path may be a path-like object. If path is of type
bytes
(directly or
indirectly through the PathLike interface), the type of the name and
path attributes of eachos.DirEntry
will bebytes
; in all other
circumstances, they will be of typestr
.
So, it can either be a str
or bytes
object representing a path, or an object implementing the os.PathLike
protocol. How do I write these possibilities for the type hinting?
You could write these possibilities as:
typing.Union[str, bytes, os.PathLike]
This is mentioned in PEP 519.
… the union of all acceptable path-representing types … can be represented with
typing.Union[str, bytes, os.PathLike]
easily enough and the hope is users will slowly gravitate to path objects only
The union type can be denoted as str | bytes | os.PathLike
.
In Python 3.12.x you could do this:
import os
from collections.abc import Iterable
from pathlib import Path
type PT = str | bytes | os.PathLike
def doScan(dirname: PT) -> Iterable[os.DirEntry]:
return os.scandir(dirname)
doScan("mydir")
doScan(b"mydir")
doScan(Path("mydir"))