-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
fix a bunch of typing errors #4024
fix a bunch of typing errors #4024
Conversation
I do not think most of these are required. The only one that I can see as being the right change is at 943fb35#diff-89c37d9db9d559ea6d241ff3fcbee2053643e688e99a177327fd0ad15580ba26R239. |
These are all required in the sense that the original code is an error with respect to the current mypy configuration. The There's a number of cases where I've swapped variant types for invariant types. This is required for correctness. See https://mypy.readthedocs.io/en/latest/generics.html#variance-of-generic-types |
def _populate_local_repo( | ||
self, local_repo: Repository, ops: List[Operation] | ||
self, local_repo: Repository, ops: Sequence[Operation] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abn
here's an example of the use of a 'covariant' type (required for correctness)
the _populate_local_repo
method accepts ops: List[Operation]
, however Operation
is a base class. In practice we expect that this method should accept a list of some derived class (such as Uninstall
, for example).
the problem is that List[Subclass]
is not equivalent to List[Baseclass]
(see these docs - http://mypy.readthedocs.io/en/latest/generics.html#variance-of-generic-types)
however Sequence[Subclass]
is equivalent to Sequence[Baseclass]
. Similarly, Iterable[Subclass]
is equivalent to Iterable[Baseclass]
.
) -> Iterator[str]: | ||
) -> Iterable[str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abn
this too is a correctness bug. the returned value of this function is not an iterator, but it is a type than can be converted into an iterator. That's the distinction between Iterator
and Iterable
return Path(self.paths["usersite"]) | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@abn
explicitly returning None
is required to conform with PEP8 and to satisfy mypy
from PEP8-
Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable)
it's not without controversy, see this discussion - python/mypy#7511
it depends what the goal is. The goal of this pull request is not strictly correctness, it is to reduce the amount of noise that mypy makes, in the hope that this is a small step in the direction of actually being able to effectively use Mypy to lint this codebase (and also correctness!).
In a perfect world, the number of type errors would be 0, and then mypy could be added as a pre-commit hook or CI job to ensure type errors are not reintroduced. Baby steps.
943fb35
to
76f75f6
Compare
if TYPE_CHECKING: | ||
from poetry.utils.env import Env |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this pattern is used in the case that an unconditional import would cause a circular import. This isn't required here.
def _single_term_where(self, callable: callable) -> Optional[Term]: | ||
def _single_term_where(self, callable: Callable[[Term], bool]) -> Optional[Term]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the built-in callable
can't be used for type annotations
) -> "ProjectPackage": | ||
) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method doesn't return...
def __eq__(self, other: "Env") -> bool: | ||
def __eq__(self, other: object) -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is required to satisfy Liskov subsitution principle- namely that the derived class's __eq__
should have the same, or a less restrictive function signature for any overridden baseclass methods.
def _run(self, cmd: List[str], **kwargs: Any) -> int: | ||
def _run(self, cmd: List[str], **kwargs: Any) -> Optional[int]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this change, while correct, actually increases the total number of errors, since the None
case is not handled in the calling code.
@@ -61,7 +62,7 @@ def get(cls) -> "Shell": | |||
|
|||
return cls._shell | |||
|
|||
def activate(self, env: VirtualEnv) -> None: | |||
def activate(self, env: VirtualEnv) -> Optional[int]: | |||
if WINDOWS: | |||
return env.execute(self.path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method returns Optional[int]
Ping @abn |
2e1d4c1
to
d22069f
Compare
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
@abn do you mind approving the workflows? |
d22069f
to
9dd8518
Compare
rebased. @abn, it's that time again... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks very solid and I cannot see any controversial changes here. I hope this gets merged soon.
i'm not holding my breath... |
7e58c9f
to
acdfd79
Compare
@abn there's over 700 typing errors now in this repo, even after these changes. Is there any appetite for reducing/resolving these? |
acdfd79
to
390c47e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this work! I'm very interesting in getting the typing issues reduced and getting mypy into the Code Quality checks. Feel free to reach out offline (e.g. Discord) to coordinate on this.
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
this pull request takes the total number of mypy errors from 656 to 617
it's a start...