Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add thorough numpy type hints #109

Closed
wants to merge 2 commits into from
Closed

Conversation

TheTripleV
Copy link
Contributor

Might fix #89 .

  1. Add more thorough detection of numpy usage for inserting the import numpy statement. If any module has replace_numpy_array global classname replacement applied to it, that module will now have import numpy added to the stubs.

  2. Optionally (with cli flag) generate hints with the nptyping library. This library provides typing support for numpy included typing both the size and dtype in a way that Pylance doesn't error on. The existing numpy _Size hints generate a typing error.

@sizmailov
Copy link
Owner

With #112, it's possible to apply type transformations in a more controlled manner and not even think about imports (almost).

I'm closing the PR since it targets an obsolete library version.

The suggested feature should be implemented similarly to the following class:

FixTypingExtTypeNames

class FixNumpyArrayDimAnnotation(IParser):
__ndarray_name = QualifiedName.from_str("numpy.ndarray")
__annotated_name = QualifiedName.from_str("typing.Annotated")
numpy_primitive_types: set[QualifiedName] = set(
map(
lambda name: QualifiedName.from_str(f"numpy.{name}"),
(
"int8",
"int16",
"int32",
"int64",
"float16",
"float32",
"float64",
"complex32",
"complex64",
"longcomplex",
),
)
)
def parse_annotation_str(
self, annotation_str: str
) -> ResolvedType | InvalidExpression | Value:
# Affects types of the following pattern:
# numpy.ndarray[PRIMITIVE_TYPE[*DIMS]]
# Annotated[numpy.ndarray, PRIMITIVE_TYPE, FixedSize[*DIMS]]
result = super().parse_annotation_str(annotation_str)
if (
not isinstance(result, ResolvedType)
or result.name != self.__ndarray_name
or result.parameters is None
or len(result.parameters) != 1
or not isinstance(param := result.parameters[0], ResolvedType)
or param.name not in self.numpy_primitive_types
or param.parameters is None
or any(not isinstance(dim, Value) for dim in param.parameters)
):
return result
# isinstance check is redundant, but makes mypy happy
dims = [int(dim.repr) for dim in param.parameters if isinstance(dim, Value)]
# override result with Annotated[...]
result = ResolvedType(
name=self.__annotated_name,
parameters=[
ResolvedType(self.__ndarray_name),
ResolvedType(param.name),
],
)
if param.parameters is not None:
# TRICK: Use `self.parse_type` to make `FixedSize`
# properly added to the list of imports
self.handle_type(FixedSize)
assert result.parameters is not None
result.parameters += [self.handle_value(FixedSize(*dims))]
return result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing import datetime & numpy
2 participants