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

Replace flake8 and isort with ruff #6128

Merged
merged 1 commit into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions .github/workflows/style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,10 @@ jobs:
if: ${{ always() }}
run: ./script/cmake-format --check

- name: Run isort
- name: Run ruff
if: ${{ always() }}
run: |
isort --check script/ src/ tests/ test-data/

- name: Lint with flake8
if: ${{ always() }}
run: |
flake8
ruff check .

- name: Run black
if: ${{ always() }}
Expand Down
24 changes: 8 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,18 @@ markers = [
log_cli = "false"
asyncio_mode = "auto"

[tool.isort]
profile = "black"

[tool.black]
include = '(\.pyi?|\.ipynb|\.py\.j2)$'

[tool.setuptools_scm]
write_to = "src/ert/shared/version.py"

[tool.flake8]
per-file-ignores = [
# Ignore all protobuf v2 files
"*_pb2.py: E"
]
ignore = [
# whitespace before ':', solved by black:
"E203",
# line break before binary operator, solved by black:
"W503",
# The minimal set of ignores that makes flake8 pass when flake8-bugbear is installed:
"B019"
[tool.ruff]
src = ["src"]
select = [
"W", # pycodestyle
"I", # isort
"B", # flake-8-bugbear
"SIM", # flake-8-simplify
]
max-line-length = 88
line-length = 88
2 changes: 1 addition & 1 deletion src/_ert_job_runner/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
reporters.append(reporting.File())
reporters.append(
reporting.Event(
evaluator_url=dispatch_url, token=ee_token, cert_path=ee_cert_path

Check failure on line 34 in src/_ert_job_runner/cli.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (82 > 79 characters)
)
)
elif experiment_id:
Expand Down Expand Up @@ -71,7 +71,7 @@
"or specify the names of the jobs to run."
)
)
parser.add_argument("run_path", nargs="?", help="Path where jobs.json is located")

Check failure on line 74 in src/_ert_job_runner/cli.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (86 > 79 characters)
parser.add_argument(
"job",
nargs="*",
Expand All @@ -89,7 +89,7 @@
sys.exit(f"No such directory: {parsed_args.run_path}")
os.chdir(parsed_args.run_path)

# Make sure that logging is setup _after_ we have moved to the runpath directory

Check failure on line 92 in src/_ert_job_runner/cli.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (84 > 79 characters)
_setup_logging()

try:
Expand All @@ -101,7 +101,7 @@
ee_cert_path = jobs_data.get("ee_cert_path")
dispatch_url = jobs_data.get("dispatch_url")
except ValueError as e:
raise IOError(f"Job Runner cli failed to load JSON-file.{e}")
raise IOError("Job Runner cli failed to load JSON-file.") from e

is_interactive_run = len(parsed_args.job) > 0
reporters = _setup_reporters(
Expand All @@ -122,7 +122,7 @@
reporter.report(job_status)
except OSError as oserror:
print(
f"job_dispatch failed due to {oserror}. Stopping and cleaning up."

Check failure on line 125 in src/_ert_job_runner/cli.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (86 > 79 characters)
)
pgid = os.getpgid(os.getpid())
os.killpg(pgid, signal.SIGKILL)
Expand Down
4 changes: 2 additions & 2 deletions src/ert/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
from ert.run_models.multiple_data_assimilation import MultipleDataAssimilation
from ert.services import StorageService, WebvizErt
from ert.shared.feature_toggling import FeatureToggling
from ert.shared.plugins.plugin_manager import ErtPluginContext, ErtPluginManager

Check failure on line 33 in src/ert/__main__.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (80 > 79 characters)
from ert.shared.storage.command import add_parser_options as ert_api_add_parser_options

Check failure on line 34 in src/ert/__main__.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (87 > 79 characters)
from ert.validation import (
IntegerArgument,
NumberListStringArgument,
Expand All @@ -42,7 +42,7 @@
)


def run_ert_storage(args: Namespace, _: Optional[ErtPluginManager] = None) -> None:

Check failure on line 45 in src/ert/__main__.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (83 > 79 characters)
kwargs = {"ert_config": args.config, "verbose": True}

if args.database_url is not None:
Expand All @@ -52,7 +52,7 @@
server.wait()


def run_webviz_ert(args: Namespace, _: Optional[ErtPluginManager] = None) -> None:

Check failure on line 55 in src/ert/__main__.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (82 > 79 characters)
try:
# pylint: disable=unused-import,import-outside-toplevel
import webviz_ert # type: ignore # noqa
Expand Down Expand Up @@ -96,7 +96,7 @@
webviz_ert_server.wait()


def strip_error_message_and_raise_exception(validated: ValidationStatus) -> None:

Check failure on line 99 in src/ert/__main__.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (81 > 79 characters)
error = validated.message()
error = re.sub(r"\<[^>]*\>", " ", error)
raise ArgumentTypeError(error)
Expand All @@ -106,7 +106,7 @@
if not os.path.isfile(fname):
raise ArgumentTypeError(f"File was not found: {fname}")
if not os.access(fname, os.R_OK):
raise ArgumentTypeError(f"We do not have read permissions for file: {fname}")

Check failure on line 109 in src/ert/__main__.py

View workflow job for this annotation

GitHub Actions / annotate-python-linting

line too long (85 > 79 characters)
return fname


Expand Down Expand Up @@ -167,8 +167,8 @@
def attemp_int_conversion(val: str) -> int:
try:
return int(val)
except ValueError:
raise ArgumentTypeError(f"{val} is not a valid integer")
except ValueError as e:
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like an automated fix. Is it given that we always want to reraise exceptions and keep all the details (it probably often is). When seen by users, more details can make them blind.

If this is a new requirement imposed by ruff, it would like to have a global exception for it in ruff-configuration, and then we can think about solving it in a future PR.

Copy link
Contributor Author

@dafeda dafeda Sep 21, 2023

Choose a reason for hiding this comment

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

Not really automated, I just did not see any reason to hide the context and yes, it makes ruff happy.
Also, I'm not really sure what the difference would be between the two in the specific function.
I would guess that they do the same thing.

raise ArgumentTypeError(f"{val} is not a valid integer") from e


def convert_port(val: str) -> int:
Expand Down
6 changes: 3 additions & 3 deletions src/ert/analysis/_es_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,11 @@ def _get_obs_and_measure_data(
ds = source_fs.load_response(group, ens_active_list)
try:
filtered_ds = observation.merge(ds, join="left")
except KeyError:
except KeyError as e:
raise ErtAnalysisError(
f"Mismatched index for: "
f"Observation: {obs_key} attached to response: {group}"
)
) from e

observation_keys.append([obs_key] * len(filtered_ds.observations.data.ravel()))
observation_values.append(filtered_ds["observations"].data.ravel())
Expand Down Expand Up @@ -525,7 +525,7 @@ def analysis_IES(
update_step.observation_config(),
)
except IndexError as e:
raise ErtAnalysisError(e)
raise ErtAnalysisError(str(e)) from e
# pylint: disable=unsupported-assignment-operation
smoother_snapshot.update_step_snapshots[update_step.name] = update_snapshot
if len(observation_values) == 0:
Expand Down
4 changes: 2 additions & 2 deletions src/ert/config/analysis_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,12 @@ def set_var(self, var_name: str, value: Union[float, int, bool, str]) -> None:
else:
var["value"] = new_value

except ValueError:
except ValueError as e:
raise ConfigValidationError(
f"Variable {var_name!r} with value {value!r} has incorrect type."
f" Expected type {var['type'].__name__!r} but received"
f" value {value!r} of type {type(value).__name__!r}"
)
) from e
else:
raise ConfigValidationError(
f"Variable {var_name!r} not found in {self.name!r} analysis module"
Expand Down
9 changes: 7 additions & 2 deletions src/ert/config/ert_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,18 @@ def check_non_utf_chars(file_path: str) -> None:
hex_str = error_words[error_words.index("byte") + 1]
try:
unknown_char = chr(int(hex_str, 16))
except ValueError:
except ValueError as ve:
unknown_char = f"hex:{hex_str}"
raise ConfigValidationError(
f"Unsupported non UTF-8 character {unknown_char!r} "
f"found in file: {file_path!r}",
config_file=file_path,
) from ve
raise ConfigValidationError(
f"Unsupported non UTF-8 character {unknown_char!r} "
f"found in file: {file_path!r}",
config_file=file_path,
)
) from e

@classmethod
def _read_templates(cls, config_dict) -> List[Tuple[str, str]]:
Expand Down
7 changes: 2 additions & 5 deletions src/ert/config/ert_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,10 @@ def initializeAndRun(
) -> Any:
arguments = []
for index, arg_value in enumerate(argument_values):
if index < len(argument_types):
arg_type = argument_types[index]
else:
arg_type = str
arg_type = argument_types[index] if index < len(argument_types) else str

if arg_value is not None:
arguments.append(arg_type(arg_value))
arguments.append(arg_type(arg_value)) # type: ignore
else:
arguments.append(None)

Expand Down
2 changes: 1 addition & 1 deletion src/ert/config/ext_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ def from_config_file(cls, config_file: str, name: Optional[str] = None) -> "ExtJ
help_text=content_dict.get("HELP_TEXT", ""),
)
except IOError as err:
raise ConfigValidationError.with_context(str(err), config_file)
raise ConfigValidationError.with_context(str(err), config_file) from err
6 changes: 4 additions & 2 deletions src/ert/config/gen_kw_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,10 @@ def _parse_transfer_function(param_string: str) -> TransferFunction:
for p in param_args[2:]:
try:
param_floats.append(float(p))
except ValueError:
raise ConfigValidationError(f"Unable to convert float number: {p}")
except ValueError as e:
raise ConfigValidationError(
f"Unable to convert float number: {p}"
) from e

params = dict(zip(param_names, param_floats))

Expand Down
2 changes: 1 addition & 1 deletion src/ert/config/model_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def __init__( # pylint: disable=too-many-arguments
except (ValueError, IOError) as err:
raise ConfigValidationError.with_context(
f"Could not read timemap file {time_map_file}: {err}", time_map_file
)
) from err

@no_type_check
@classmethod
Expand Down
8 changes: 4 additions & 4 deletions src/ert/config/parsing/config_schema_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,19 @@ def token_to_value_with_context(
if val_type == SchemaItemType.INT:
try:
return ContextInt(int(token), token, keyword)
except ValueError:
except ValueError as e:
raise ConfigValidationError.with_context(
f"{self.kw!r} must have an integer value"
f" as argument {index + 1!r}",
token,
)
) from e
if val_type == SchemaItemType.FLOAT:
try:
return ContextFloat(float(token), token, keyword)
except ValueError:
except ValueError as e:
raise ConfigValidationError.with_context(
f"{self.kw!r} must have a number as argument {index + 1!r}", token
)
) from e

path: Optional[str] = str(token)
if val_type in [
Expand Down
4 changes: 2 additions & 2 deletions src/ert/config/parsing/lark_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ def _parse_file(file: str) -> Tree[Instruction]:
end_column=e.column + 1,
filename=file,
)
)
) from e
except UnicodeDecodeError as e:
error_words = str(e).split(" ")
hex_str = error_words[error_words.index("byte") + 1]
Expand Down Expand Up @@ -476,7 +476,7 @@ def _parse_file(file: str) -> Tree[Instruction]:
)
for bad_line in bad_byte_lines
]
)
) from e


def parse(
Expand Down
2 changes: 1 addition & 1 deletion src/ert/config/parsing/observations_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def _parse_content(
column=e.column,
end_column=e.column + 1,
)
)
) from e


observations_parser = Lark(
Expand Down
5 changes: 1 addition & 4 deletions src/ert/dark_storage/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ def data_for_key(
elif key in res.get_gen_data_keys():
key_parts = key.split("@")
key = key_parts[0]
if len(key_parts) > 1:
report_step = int(key_parts[1])
else:
report_step = 0
report_step = int(key_parts[1]) if len(key_parts) > 1 else 0

try:
data = res.load_gen_data(
Expand Down
6 changes: 4 additions & 2 deletions src/ert/data/_measured_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ def _get_data(
response = ensemble.load_response(
group, tuple(range(self._facade.get_ensemble_size()))
)
except KeyError:
raise ResponseError(f"No response loaded for observation key: {key}")
except KeyError as e:
raise ResponseError(
f"No response loaded for observation key: {key}"
) from e
ds = obs.merge(
response,
join="left",
Expand Down
6 changes: 3 additions & 3 deletions src/ert/data/record/_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def __init__(self, data: blob_record_data) -> None:
try:
self._data = self._validate_data(data)
except BeartypeException as e:
raise RecordValidationError(str(e))
raise RecordValidationError(str(e)) from e

@beartype
def _validate_data(self, data: blob_record_data) -> blob_record_data:
Expand Down Expand Up @@ -167,7 +167,7 @@ def __init__(
try:
self._validate_data(data)
except BeartypeException as e:
raise RecordValidationError(str(e))
raise RecordValidationError(str(e)) from e

self._data: numerical_record_data
if isinstance(data, int):
Expand Down Expand Up @@ -296,7 +296,7 @@ def __init__(self, record_dict: Dict[str, Any]) -> None:
try:
self._validate_data(self._flat_record_dict)
except BeartypeException as e:
raise RecordValidationError(str(e))
raise RecordValidationError(str(e)) from e

@beartype
def _validate_data(self, flat_record_dict: Dict[str, RecordGen]) -> None:
Expand Down
17 changes: 8 additions & 9 deletions src/ert/ensemble_evaluator/_wait_for_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ async def attempt_connection(
) -> None:
timeout = aiohttp.ClientTimeout(connect=connection_timeout)
headers = {} if token is None else {"token": token}
async with aiohttp.ClientSession() as session:
async with session.request(
method="get",
url=url,
ssl=get_ssl_context(cert),
headers=headers,
timeout=timeout,
) as resp:
resp.raise_for_status()
async with aiohttp.ClientSession() as session, session.request(
method="get",
url=url,
ssl=get_ssl_context(cert),
headers=headers,
timeout=timeout,
) as resp:
resp.raise_for_status()


async def wait_for_evaluator( # pylint: disable=too-many-arguments
Expand Down
5 changes: 1 addition & 4 deletions src/ert/gui/ertwidgets/listeditbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,7 @@ def validateList(self):

validity_type = ValidationSupport.WARNING

if not valid:
color = ValidationSupport.ERROR_COLOR
else:
color = self._valid_color
color = ValidationSupport.ERROR_COLOR if not valid else self._valid_color

self._validation_support.setValidationMessage(message, validity_type)
self._list_edit_line.setToolTip(message)
Expand Down
5 changes: 1 addition & 4 deletions src/ert/gui/ertwidgets/pathchooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,7 @@ def validatePath(self):

validity_type = ValidationSupport.WARNING

if not valid:
color = ValidationSupport.ERROR_COLOR
else:
color = self.valid_color
color = ValidationSupport.ERROR_COLOR if not valid else self.valid_color

self._validation_support.setValidationMessage(message, validity_type)
self._path_line.setToolTip(message)
Expand Down
19 changes: 6 additions & 13 deletions src/ert/gui/model/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
from qtpy.QtCore import QAbstractItemModel, QModelIndex, QSize, Qt, QVariant
from qtpy.QtGui import QColor, QFont

from ert.ensemble_evaluator import PartialSnapshot, Snapshot
from ert.ensemble_evaluator import PartialSnapshot, Snapshot, state
from ert.ensemble_evaluator import identifiers as ids
from ert.ensemble_evaluator import state
from ert.gui.model.node import Node, NodeType
from ert.shared.status.utils import byte_with_unit

Expand Down Expand Up @@ -114,9 +113,9 @@ def prerender(
snapshot.data()[ids.REALS].keys(), key=int
)
metadata[SORTED_JOB_IDS] = {}
for real_id in snapshot.reals.keys():
for real_id in snapshot.reals:
metadata[SORTED_JOB_IDS][real_id] = {}
for step_id in snapshot.steps(real_id).keys():
for step_id in snapshot.steps(real_id):
indices = [
(job.index, job_id)
for job_id, job in snapshot.jobs(real_id, step_id).items()
Expand All @@ -136,7 +135,7 @@ def prerender(
for step in real[ids.STEPS].values():
if ids.JOBS not in step:
continue
for job_id in step[ids.JOBS].keys():
for job_id in step[ids.JOBS]:
status = step[ids.JOBS][job_id][ids.STATUS]
color = _QCOLORS[state.JOB_STATE_TO_COLOR[status]]
metadata[REAL_JOB_STATUS_AGGREGATED][real_id][job_id] = color
Expand Down Expand Up @@ -328,10 +327,7 @@ def columnCount(self, parent: QModelIndex = None):
def rowCount(self, parent: QModelIndex = None):
if parent is None:
parent = QModelIndex()
if not parent.isValid():
parentItem = self.root
else:
parentItem = parent.internalPointer()
parentItem = self.root if not parent.isValid() else parent.internalPointer()

if parent.column() > 0:
return 0
Expand Down Expand Up @@ -476,10 +472,7 @@ def index(self, row: int, column: int, parent: QModelIndex = None) -> QModelInde
if not self.hasIndex(row, column, parent):
return QModelIndex()

if not parent.isValid():
parent_item = self.root
else:
parent_item = parent.internalPointer()
parent_item = self.root if not parent.isValid() else parent.internalPointer()

child_item = None
try:
Expand Down
5 changes: 1 addition & 4 deletions src/ert/gui/plottery/plots/distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ def _plotDistribution(
index,
previous_data,
):
if data.empty:
data = pd.Series(dtype="float64")
else:
data = data[0]
data = pd.Series(dtype="float64") if data.empty else data[0]

axes.set_xlabel(plot_config.xLabel())
axes.set_ylabel(plot_config.yLabel())
Expand Down
Loading
Loading