Description
Hi!
I've been developing something kinda like dependency injection mechanism and for it I've decided to create functions that return typing.Annotated
with needed data and annotate di function arguments with this function. Something like that:
Provider-providable data code:
class _EnvironmentVariables(IProvidableData, Mapping):
"""
Class storing environment variables from dump file.
Should be used as Mapping
"""
def __init__(self, variables: dict[str, bytes]) -> None:
self.__variables = variables
def as_json_obj(self) -> JSON:
return {k: v.decode('ascii') for k, v in self.__variables.items()}
def __getitem__(self, __key: str) -> bytes:
return self.__variables.__getitem__(__key)
def __len__(self) -> int:
return self.__variables.__len__()
def __iter__(self) -> Iterator[str]:
return self.__variables.__iter__()
def __str__(self):
return str(self.__variables)
class EnvironmentVariablesProvider(ILinuxProvider[_EnvironmentVariables]):
"""
Provides environment variables from Linux dump file
"""
def __init__(self, coredump: Coredump, sort: bool) -> None:
super().__init__(coredump=coredump)
self.sort = sort
def provide(self) -> _EnvironmentVariables:
env_names = self.coredump.env.keys()
if self.sort:
env_names = sorted(env_names)
envs = {env_name: self.coredump.getenv(env_name) for env_name in env_names}
return _EnvironmentVariables(variables=envs)
def EnvironmentVariables(sort: bool): # noqa (This func is imitating a type name, so upper-camel-case is ok)
"""
Gets all environment variables from the core dump.
These environment variables were captured by the process that generated core dump.
Args:
sort: Whether to sort variables by name or not
Returns:
Mapping with env name as a key and env value as a mapping value.
Notes:
This docstring is for user, so it is not covering or describing real implementation details!
"""
return Annotated[_EnvironmentVariables, ArgsKwargs(sort=sort)]
End user code
@scenario(name='Unsorted env variables') # Decorator for DI
@linux # DI filter, doesn't matter in this example
def unsorted_env_variables(variables: EnvironmentVariables(sort=False)) -> JSON:
return variables.as_json_obj()
The issue
The issue I have is that mypy is giving me error like:
error: Invalid type comment or annotation [valid-type]
note: Suggestion: use EnvironmentVariables[...] instead of EnvironmentVariables(...)
I understand that static in "static code analysis" means that code won't run during this process and there is no (or almost no) way for mypy to see that EnvironmentVariables()
returns typing.Annotated
. But I think that mypy should be capable of differentiating function name from type name in type annotation.
This style of annotations might be kinda unintuitive, but I think that typing.Annotated
is a mechanism that might be used dynamically by some users. And in this cases it is can be very handy to annotate argumens like that.
Environment:
- Python version used: 3.10.1
- Mypy version used: 1.7.0
- Mypy configuration options from
pyproject.toml
:
### Mypy section
[tool.mypy]
python_version = "3.10"
files = "src/,test/"
# Stop errors for pytest_lazy_fixtures about untyped import
[[tool.mypy.overrides]]
module = "pytest_lazy_fixtures"
ignore_missing_imports = true