I am having some trouble assigning the variables in a Python 3.6 class to a particular type--a Pathlib path. Following an example from link, I tried to create a TypeVar
, but mypy
is still throwing errors. I want to make sure that the class variables initialized in the __init__.py
only receive a particular type at compile time. So this is just a check to make sure I don't inadvertently set a string or something else to these class variables.
Can anyone suggest the correct way to do this?
Here is some simple code.
import pathlib
from typing import Union, Dict, TypeVar, Type
Pathtype = TypeVar('Pathtype', bound=pathlib.Path)
class Request:
def __init__(self, argsdict):
self._dir_file1: Type[Pathtype] = argsdict['dir_file1']
self._dir_file2: Type[Pathtype] = argsdict['dir_file2']
The error that I am getting is:
Request.py:13: error: Invalid type "Request.Pathtype"
Request.py:14: error: Invalid type "Request.Pathtype"
Neither Type, TypeVar nor NewType are correct to use here. What you simply want to do is use Path
itself:
from pathlib import Path
class Request:
def __init__(self, argsdict):
self._dir_file1: Path = argsdict['dir_file1']
self._dir_file2: Path = argsdict['dir_file2']
If you annotate your argsdict
as being of type Dict[str, Path]
, you can skip having to annotate your fields entirely: mypy will infer the correct type:
from typing import Dict
from pathlib import Path
class Request:
def __init__(self, argsdict: Dict[str, Path]):
self._dir_file1 = argsdict['dir_file1']
self._dir_file2 = argsdict['dir_file2']
Here's a brief explanation of what the various type constructs you were attempting to use/was suggested to you actually do:
TypeVar
is used when you are trying to create a generic data structure or function. For example, take List[int]
, which represents a list containing ints. List[...]
is an example of a generic data structure: it can be parameterized by any arbitrary type.
You use TypeVar
as a way of adding "parameterizable holes" if you decide you want to create your own generic data structure.
It's also possible to use TypeVars
when writing generic functions. For example, suppose you want to declare that you have some function that can accept a value of any type -- but that function is guaranteed to return a value of the exact same type. You can express ideas like these using TypeVars
.
The Type[...]
annotation is used to indicate that some expression must be the type of a type. For example, to declare that some variable must hold an int, we would write my_var: int = 4
. But what if we want to write something like my_var = int
? What sort of type hint could we give that variable? In this case, we could do my_var: Type[int] = int
.
NewType
basically lets you "pretend" that you're taking some type and making a subclass of it -- but without requiring you to actually subclass anything at runtime. If you're careful, you can take advantage of this feature to help catch bugs where you mix different "kinds" of strings or ints or whatever -- e.g. passing in a string representing HTML into a function expecting a string representing SQL.
Replace TypeVar
with NewType
and remove the Type[]
modifier.
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