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

Enable all pycodestyle and isort rules in Ruff and fix violations #1463

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ markers = ["group2", "slow"]
target-version = "py311"
line-length = 120

[tool.ruff.lint]
select = ["E", "F", "I", "W"]
per-file-ignores = {"src/scripts/**" = ["E501", "W"]}

[tool.setuptools.packages.find]
where = ["src"]

Expand Down
1 change: 0 additions & 1 deletion src/scripts/hiv/projections_jan2023/analysis_full_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import datetime
import pickle
# import random
from pathlib import Path

from tlo import Date, Simulation, logging
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/profiling/run_profiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def run_profiling(
print(f"Writing {output_ipysession_file}", end="...", flush=True)
scale_run_session.save(output_ipysession_file)
print("done")

if write_flat_html:
output_html_file = output_dir / f"{output_name}.flat.html"
console_renderer = ConsoleRenderer(
Expand Down
6 changes: 3 additions & 3 deletions src/scripts/profiling/scale_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ def save_arguments_to_json(arguments_dict: dict, output_path: Path):
with open(output_path, "w") as f:
json.dump(
{
k: str(v) if isinstance(v, Path) else v
k: str(v) if isinstance(v, Path) else v
for k, v in arguments_dict.items()
},
f,
},
f,
indent=4
)

Expand Down
4 changes: 2 additions & 2 deletions src/scripts/task_runner/generate_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ def get_html_for_commit(commit_dir: Path) -> str:
<body>
<h1>$title</h1>
<p style="font-size: small;">
This page was generated on $generated_time. The
<a href="https://github.com/UCL/TLOmodel/actions/workflows/calibration.yaml">calibration workflow</a> runs every
This page was generated on $generated_time. The
<a href="https://github.com/UCL/TLOmodel/actions/workflows/calibration.yaml">calibration workflow</a> runs every
night on the latest new commit on the master branch. <a href="#" id="toggleIncomplete">toggle incomplete</a>
</p>
$body
Expand Down
2 changes: 1 addition & 1 deletion src/tlo/analysis/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def parse_log_file(log_filepath, level: int = logging.INFO):

def merge_log_files(log_path_1: Path, log_path_2: Path, output_path: Path) -> None:
"""Merge two log files, skipping any repeated header lines.

:param log_path_1: Path to first log file to merge. Records from this log file will
appear first in merged log file.
:param log_path_2: Path to second log file to merge. Records from this log file will
Expand Down
40 changes: 23 additions & 17 deletions src/tlo/bitset_handler/bitset_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@

class BitsetDtype(ExtensionDtype):
"""
A Bitset is represented by a fixed-width string, whose characters are each a uint8.
Elements of the set map 1:1 to these characters.
A Bitset is represented by a fixed-width string, whose characters are each a uint8. Elements of the set map 1:1 to
these characters.

If the elements set is indexed starting from 0, then:
- The quotient of these indices (modulo 8) is the character within the string that contains the bit representing the element,
- The remainder (modulo 8) is the index within said character that represents the element itself.
If the elements set is indexed starting from 0, then: - The quotient of these indices (modulo 8) is the character
within the string that contains the bit representing the element, - The remainder (modulo 8) is the index within
said character that represents the element itself.

The element map takes an element of the bitset as a key, and returns a tuple whose first element is the
corresponding string-character index, and the latter the uint8 representation of the element within that
string character.
corresponding string-character index, and the latter the uint8 representation of the element within that string
character.
"""
_element_map: Dict[ElementType, Tuple[int, np.uint8]]
_elements: Tuple[ElementType]
Expand All @@ -71,7 +71,7 @@ def construct_from_string(cls, string: str) -> BitsetDtype:
"""
Construct an instance of this class by passing in a string of the form
that str(<instance of this class>) produces.

That is, given a string of the form
bitset(#elements): e1, e2, e3, ...

Expand Down Expand Up @@ -101,7 +101,8 @@ def construct_from_string(cls, string: str) -> BitsetDtype:
iterable_values = tuple(s.strip() for s in string.split(","))
if n_elements is not None and len(iterable_values) != n_elements:
raise ValueError(
f"Requested bitset with {n_elements} elements, but provided {len(iterable_values)} elements: {iterable_values}"
f"Requested bitset with {n_elements} elements, "
f"but provided {len(iterable_values)} elements: {iterable_values}"
)
return BitsetDtype(s.strip() for s in string.split(","))

Expand Down Expand Up @@ -351,7 +352,7 @@ def _uint8_view(self) -> NDArray[np.bytes_]:
Each row ``i`` of this view corresponds to a bitset stored in this array.
The value at index ``i, j`` in this view is the ``uint8`` that represents
character ``j`` in ``self._data[i]``, which can have bitwise operations
performed on it.
performed on it.
"""
return self._data.view(self._uint8_view_format)

Expand Down Expand Up @@ -463,17 +464,17 @@ def __cast_to_uint8(self, other: CastableForPandasOps) -> NDArray[np.uint8]:

Scalar elements:
Cast to single-element sets, then treated as set.

Sets:
Are converted to the (array of) uint8s that represents the set.

``np.ndarray``s of ``np.uint8``
Are returned if they have the same number of columns as ``self._uint8_view``.

``np.ndarray``s of ``np.dtype("Sx")``
If ``x`` corresponds to the same fixed-width as ``self.dtype.np_array_dtype``, are cast
to the corresponding ``np.uint8`` view, like ``self._uint8_view`` is from ``self._data``.

BitsetArrays
Return their ``_uint8_view`` attribute.
"""
Expand Down Expand Up @@ -508,13 +509,17 @@ def __cast_to_uint8(self, other: CastableForPandasOps) -> NDArray[np.uint8]:
cast = self.dtype.as_uint8_array(other)
return cast

def __comparison_op(self, other: CastableForPandasOps, op: Callable[[Set[ElementType], Set[ElementType]], bool]) -> BooleanArray:
def __comparison_op(
self,
other: CastableForPandasOps,
op: Callable[[Set[ElementType], Set[ElementType]], bool],
) -> BooleanArray:
"""
Abstract method for strict and non-strict comparison operations.

Notably, __eq__ does not redirect here since it is more efficient for us to convert
the single value to a bytestring and use numpy array comparison.

For the other set comparison methods however, it's easier as a first implementation
for us to convert to sets and run the set operations. If there was a Pythonic way
of doing "bitwise less than" and "bitwise greater than", we could instead take the
Expand Down Expand Up @@ -678,7 +683,8 @@ def copy(self) -> BitsetArray:

def isna(self) -> NDArray:
"""
TODO: This isn't a great way to express missing data, but equally a bitset doesn't really ever contain missing data...
TODO: This isn't a great way to express missing data, but equally a bitset doesn't really ever contain
missing data...
"""
return np.isnan(self._data)

Expand Down
6 changes: 3 additions & 3 deletions src/tlo/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def _default_value(self) -> Any:
"""
Default value for this property, which will be used to fill the respective columns
of the population dataframe, for example.

If not explicitly set, it will fall back on the ``PANDAS_TYPE_DEFAULT_TYPE_MAP``.
If a value is provided, it must:

Expand Down Expand Up @@ -386,8 +386,8 @@ def initialise_population(self, population: Population) -> None:

Modules that wish to implement this behaviour do not need to implement this method,
it will be inherited automatically. Modules that wish to perform additional steps
during the initialise_population stage should reimplement this method and call
during the initialise_population stage should reimplement this method and call

```python
super().initialise_population(population=population)
```
Expand Down
4 changes: 2 additions & 2 deletions src/tlo/logging/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ def get_dataframe_row_as_dict_for_logging(
columns: Optional[Iterable[str]] = None,
) -> dict:
"""Get row of a pandas dataframe in a format suitable for logging.

Retrieves entries for all or a subset of columns for a particular row in a dataframe
and returns a dict keyed by column name, with values NumPy or pandas extension types
which should be the same for all rows in dataframe.

:param dataframe: Population properties dataframe to get properties from.
:param row_label: Unique index label identifying row in dataframe.
:param columns: Set of column names to extract - if ``None``, the default, all
Expand Down
3 changes: 2 additions & 1 deletion src/tlo/methods/alri.py
Original file line number Diff line number Diff line change
Expand Up @@ -3040,7 +3040,8 @@ def apply(self, person_id):

assert 'fast_breathing_pneumonia' == \
self.module.get_imci_classification_based_on_symptoms(
child_is_younger_than_2_months=False, symptoms=self.sim.modules['SymptomManager'].has_what(person_id=person_id)
child_is_younger_than_2_months=False,
symptoms=self.sim.modules['SymptomManager'].has_what(person_id=person_id)
)


Expand Down
4 changes: 3 additions & 1 deletion src/tlo/methods/contraception.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ def read_parameters(self, data_folder):
"""Import the relevant sheets from the ResourceFile (excel workbook) and declare values for other parameters
(CSV ResourceFile).
"""
workbook = pd.read_excel(Path(self.resourcefilepath) / 'contraception' / 'ResourceFile_Contraception.xlsx', sheet_name=None)
workbook = pd.read_excel(
Path(self.resourcefilepath) / 'contraception' / 'ResourceFile_Contraception.xlsx', sheet_name=None
)

# Import selected sheets from the workbook as the parameters
sheet_names = [
Expand Down
2 changes: 1 addition & 1 deletion src/tlo/methods/demography.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def __init__(self, name=None, resourcefilepath=None, equal_allocation_by_distric
),

'district_num_of_residence': Property(
Types.CATEGORICAL,
Types.CATEGORICAL,
'The district number in which the person is resident',
categories=['SET_AT_RUNTIME']
),
Expand Down
10 changes: 7 additions & 3 deletions src/tlo/methods/epilepsy.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,9 @@ def __init__(self, module, person_id):
self.EXPECTED_APPT_FOOTPRINT = self.make_appt_footprint({'Over5OPD': 1})
self.ACCEPTED_FACILITY_LEVEL = '1b'

self._MAX_NUMBER_OF_FAILED_ATTEMPTS_BEFORE_DEFAULTING = module.parameters['max_num_of_failed_attempts_before_defaulting']
self._MAX_NUMBER_OF_FAILED_ATTEMPTS_BEFORE_DEFAULTING = module.parameters[
"max_num_of_failed_attempts_before_defaulting"
]
self._counter_of_failed_attempts_due_to_unavailable_medicines = 0

def apply(self, person_id, squeeze_factor):
Expand Down Expand Up @@ -679,8 +681,10 @@ class HSI_Epilepsy_Follow_Up(HSI_Event, IndividualScopeEventMixin):
def __init__(self, module, person_id):
super().__init__(module, person_id=person_id)

self._MAX_NUMBER_OF_FAILED_ATTEMPTS_BEFORE_DEFAULTING = module.parameters['max_num_of_failed_attempts_before_defaulting']
self._DEFAULT_APPT_FOOTPRINT = self.make_appt_footprint({'Over5OPD': 1})
self._MAX_NUMBER_OF_FAILED_ATTEMPTS_BEFORE_DEFAULTING = module.parameters[
"max_num_of_failed_attempts_before_defaulting"
]
self._DEFAULT_APPT_FOOTPRINT = self.make_appt_footprint({"Over5OPD": 1})
self._REPEATED_APPT_FOOTPRINT = self.make_appt_footprint({'PharmDispensing': 1})

self.TREATMENT_ID = "Epilepsy_Treatment_Followup"
Expand Down
Loading