-
Notifications
You must be signed in to change notification settings - Fork 192
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
Pre-commit: move yapf
and mypy
config to pyproject.toml
#4996
Conversation
@chrisjsewell to have support for |
Codecov Report
@@ Coverage Diff @@
## develop #4996 +/- ##
===========================================
- Coverage 80.38% 80.37% -0.00%
===========================================
Files 529 529
Lines 36862 36871 +9
===========================================
+ Hits 29627 29633 +6
- Misses 7235 7238 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
Hi @sphuber, since I am here to look at mypy errors, I can try to assistant to complete this PR. Do you already start working on it, or can I directly add more commits into your branch? |
736e8d8
to
0bfd323
Compare
@unkcpz I have updated the branch with all that I have currently. It would be great if you could address the |
Hi @sphuber, I make some commits to settle the mypy errors. Except for the following types of mypy complaints are not resolved:
|
f300011
to
9a1e2a9
Compare
13d1996
to
7556343
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 @unkcpz . Reverted some changes to the Group
logic and have some other questions.
backend = self.get_backend() | ||
return Repository(backend=backend) | ||
|
||
def get_backend(self) -> 'DiskObjectStoreRepositoryBackend': |
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.
I wouldn't call this get_backend
. It would be too confusing with the database backend. If we really need this method, a better name would be get_repository_backend
. However, why can't we just call get_repository().backend
? Is it necessary to have this intermediate method?
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.
a better name would be get_repository_backend
sure!
However, why can't we just call get_repository().backend?
It is because for Profile
, get_repository().backend
return an AbstractRepositoryBackend
which has no attributes such as container
defined in it. However, for Profile
class, it sticks to the DiskObjectStoreRepositoryBackend
, access to rather than the abstract backend class make it possible to deduce the attributes from the backend.
I am not sure if there is any better way to resolve this incompatible mypy error.
aiida/manage/manager.py
Outdated
if self._backend is None: | ||
raise ValueError('Could not load the backend.') |
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.
Would be better to put this check directly after the logic that is supposed to set it, i.e. before the configure_logging
call. Second, I don't think a ValueError
is the correct exception for this. That is reserved for validation arguments of a method or function. What seems to be happening in this case, the only reason self._backend
can be None
is because the backend_type
is neither BACKEND_DJANGO
nor BACKEND_SQLA
. So really we shouldn't have this check but add the else
clause and raise an AssertionError
because our internal logic is supposed to set these when loading a profile and that is what we are checking here: internal consistency of program logic.
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.
Good point!
@@ -206,7 +209,7 @@ def get_backend(self) -> 'Backend': | |||
|
|||
""" | |||
if self._backend is None: | |||
self._load_backend() | |||
return self._load_backend() |
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.
Why is this change necessary?
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.
In order to resolve aiida/manage/manager.py:214: error: Incompatible return value type (got "Optional[Backend]", expected "Backend") [return-value]
.
I assume although the _load_backend()
method actually set the self._backend
and will never leave it to None
, get_backend
does not know it and assert the return value self._backend
still can be None
. mypy can't make an assumption about what the called function is doing.
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.
Okay, I guess this is the place where the type assertion properly takes effect. We have:
return cast('Backend', self._backend)
In that case, I propose _load_backend
method should have no return value.
@@ -38,7 +38,7 @@ | |||
|
|||
def import_data_dj( | |||
in_path: str, | |||
group: Optional[Group] = None, | |||
group: Optional[ImportGroup] = 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.
I reverted this change as it is backwards incompatible. We are currently allowing users to use a plain Group
to store nodes in upon importing. We cannot narrow this restriction down.
@@ -66,7 +66,7 @@ def collect_hashkeys(objects, hashkeys): | |||
container_export.export(set(hashkeys), container_profile, compress=True, callback=callback) | |||
|
|||
|
|||
def _make_import_group(*, group: Optional[ImportGroup], node_pks: List[int]) -> ImportGroup: | |||
def _make_import_group(*, group: Optional[ImportGroup], node_pks: List[int]) -> Optional[ImportGroup]: |
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.
To fix the mypy error related to inconsistent types, we should rather change this to Optional[Group]
. I have already done this and reverted your other change. Reason why is explained in another comment
7556343
to
0fe96c8
Compare
0fe96c8
to
d59452c
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.
@sphuber thanks for review!
I reverted this change as it is backwards incompatible. We are currently allowing users to use a plain Group to store nodes in upon importing. We cannot narrow this restriction down.
Yes, should rollback. After changing that I found it failed some migrate tests.
backend = self.get_backend() | ||
return Repository(backend=backend) | ||
|
||
def get_backend(self) -> 'DiskObjectStoreRepositoryBackend': |
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.
a better name would be get_repository_backend
sure!
However, why can't we just call get_repository().backend?
It is because for Profile
, get_repository().backend
return an AbstractRepositoryBackend
which has no attributes such as container
defined in it. However, for Profile
class, it sticks to the DiskObjectStoreRepositoryBackend
, access to rather than the abstract backend class make it possible to deduce the attributes from the backend.
I am not sure if there is any better way to resolve this incompatible mypy error.
@@ -206,7 +209,7 @@ def get_backend(self) -> 'Backend': | |||
|
|||
""" | |||
if self._backend is None: | |||
self._load_backend() | |||
return self._load_backend() |
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.
In order to resolve aiida/manage/manager.py:214: error: Incompatible return value type (got "Optional[Backend]", expected "Backend") [return-value]
.
I assume although the _load_backend()
method actually set the self._backend
and will never leave it to None
, get_backend
does not know it and assert the return value self._backend
still can be None
. mypy can't make an assumption about what the called function is doing.
aiida/manage/manager.py
Outdated
if self._backend is None: | ||
raise ValueError('Could not load the backend.') |
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.
Good point!
from aiida.repository import Repository | ||
|
||
backend = self.get_backend() |
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.
Looking at failed CI, found here is a mistake. In case of disturbing you with too many push to your branch, I will fix this later with more valid commits.
backend = self.get_backend() | |
backend = self.get_repository_backend() |
d59452c
to
53ff345
Compare
The libraries `yapf` and `mypy` support the `pyproject.toml` file for their configuration starting from v0.31 and v0.9, respectively. Co-authored-by: Jason Eu <morty.yu@yahoo.com>
53ff345
to
c342428
Compare
Well in fairness to mypy, these We have to use Additionally, it currently does not work with new default VS Code Python Language Server (Pylance) and so you get no auto-completions, etc. __all__ = ()
__all__ += calculation.__all__
__all__ += process.__all__
__all__ += workflow.__all__ this does not help with mypy though |
Ok, well if this is a known problem of |
#5061 updates mypy to v0.901 😄 |
right lets see where we are at with this |
Ok well the |
What code changes? As far as I know, any code changes applied were simply to address the new errors that were now thrown by the updated version of |
backend = self.get_repository_backend() | ||
return Repository(backend=backend) | ||
|
||
def get_repository_backend(self) -> 'DiskObjectStoreRepositoryBackend': |
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.
what code changes
well you are introducing completely new methods 😬
yeh but after #5061, I think these may be the cause of the errors, rather than fixes; this PR no longer actually updates the mypy version, so in principle moving the configuration should result in zero changes to the mypy outcome. I'm happy to give it a try when I have time |
😅 #5066 |
The libraries
yapf
andmypy
support thepyproject.toml
file fortheir configuration starting from v0.31 and v0.9, respectively.