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

Bump ruff version #6614

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

danielhollas
Copy link
Collaborator

@danielhollas danielhollas commented Nov 18, 2024

Most of the changes here are minor import sorting changes (I checked all of them and they all look more correct than before).

The only other change were couple type-comparison (E721) fixes, these should be reviewed carefully.

I also turned off verbose pytest output in CI since it produces thousands of lines and is very difficult to navigate in Github UI.


type-comparison (E721)

Derived from the pycodestyle linter.

What it does

Checks for object type comparisons using == and other comparison
operators.

Why is this bad?

Unlike a direct type comparison, isinstance will also check if an object
is an instance of a class or a subclass thereof.

If you want to check for an exact type match, use is or is not.

Known problems

When using libraries that override the == (__eq__) operator (such as NumPy,
Pandas, and SQLAlchemy), this rule may produce false positives, as converting
from == to is or is not will change the behavior of the code.

For example, the following operations are not equivalent:

import numpy as np

np.array([True, False]) == False
# array([False,  True])

np.array([True, False]) is False
# False

Example

if type(obj) == type(1):
    pass

if type(obj) == int:
    pass

Use instead:

if isinstance(obj, int):
    pass

Copy link

codecov bot commented Nov 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 77.90%. Comparing base (ef60b66) to head (fcf450f).
Report is 145 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6614      +/-   ##
==========================================
+ Coverage   77.51%   77.90%   +0.40%     
==========================================
  Files         560      567       +7     
  Lines       41444    42148     +704     
==========================================
+ Hits        32120    32832     +712     
+ Misses       9324     9316       -8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@@ -1,6 +1,7 @@
from aiida.engine import ToContext, WorkChain
from child import ChildWorkChain
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rearrangement is not that great, but whatever.

.github/workflows/ci-code.yml Outdated Show resolved Hide resolved
@@ -177,7 +177,7 @@ def list_options(self, entry_point: str) -> list:
# ``typing.Union[str, None].__args__`` will return the tuple ``(str, NoneType)``. So to get the real type,
# we simply remove all ``NoneType`` and the remaining type should be the type of the option.
if hasattr(field_info.annotation, '__args__'):
args = list(filter(lambda e: e != type(None), field_info.annotation.__args__))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one of the few changes, I think this is correct, but please check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edan-bainglass I think you familiar with this part?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only way a different result can be achieved is when a custom type overwrites the equal function. That is not the case for NoneType, so it is ok.

@@ -208,7 +208,7 @@ def _resolve_nested_context(self, key: str) -> tuple[AttributeDict, str]:
# (subclasses of AttributeDict) but after resolution of an Awaitable this will be the value itself
# * assumption: a resolved value is never a plain AttributeDict, on the other hand if a resolved Awaitable
# would be an AttributeDict we can append things to it since the order of tasks is maintained.
if type(ctx) != AttributeDict:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AttributeDict is a class inheriting from dict so the __eq__ function of the type is not overwritten so it is okay here

Copy link
Contributor

@agoscinski agoscinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to wait until #6630 is merged to fix the CI. Otherwise looks good to me

- id: ruff
exclude: *exclude_ruff
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you know what this did?

Copy link
Collaborator Author

@danielhollas danielhollas Nov 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was excluding files docs/source/topics/processes/include/snippets/functions/parse_docstring_expose_ipython.py and docs/source/topics/processes/include/snippets/functions/signature_plain_python_call_illegal.py from linting and formatting.

I've moved this configuration to pyproject.toml which I think is a much better place for it. For example, you can now run ruff also manually outside of pre-commit and it will have the same configuration.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this is reusing a yaml anchor! thanks!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you said, yes 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FTR: I am refusing to google what is "yaml anchor" :-D

@@ -177,7 +177,7 @@ def list_options(self, entry_point: str) -> list:
# ``typing.Union[str, None].__args__`` will return the tuple ``(str, NoneType)``. So to get the real type,
# we simply remove all ``NoneType`` and the remaining type should be the type of the option.
if hasattr(field_info.annotation, '__args__'):
args = list(filter(lambda e: e != type(None), field_info.annotation.__args__))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only way a different result can be achieved is when a custom type overwrites the equal function. That is not the case for NoneType, so it is ok.

@@ -208,7 +208,7 @@ def _resolve_nested_context(self, key: str) -> tuple[AttributeDict, str]:
# (subclasses of AttributeDict) but after resolution of an Awaitable this will be the value itself
# * assumption: a resolved value is never a plain AttributeDict, on the other hand if a resolved Awaitable
# would be an AttributeDict we can append things to it since the order of tasks is maintained.
if type(ctx) != AttributeDict:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AttributeDict is a class inheriting from dict so the __eq__ function of the type is not overwritten so it is okay here

@unkcpz
Copy link
Member

unkcpz commented Nov 26, 2024

@danielhollas I put this into "v2.7.0" in case there are some changes that we are not sure and will break the backward compatibility. Otherwise we can just have this for a patch release. What do you think?

@danielhollas
Copy link
Collaborator Author

There shouldn't be any breaking changes, but at the same time this certainly doesn't contain any bugfixes so I don't see a reason why it would need to go in a patch release. v2.7.0 is fine

Copy link
Contributor

@agoscinski agoscinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't see any reason for keeping it outside of a patch release if it simplifies the creation of it because of merge conflicts

Copy link
Member

@unkcpz unkcpz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks all good! Thanks @danielhollas

@danielhollas
Copy link
Collaborator Author

danielhollas commented Nov 27, 2024

I also don't see any reason for keeping it outside of a patch release if it simplifies the creation of it because of merge conflicts

True, there's a fair amount of churn in this PR due to import reorderings. In case you thought it important, I could split this into two commits.

EDIT: sorry, didn't mean to close the PR.

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.

3 participants