diff --git a/Makefile b/Makefile index fd99cbbbf..d3be82a72 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ documentation: python docs/add_plotly_to_book.py docs/_build format: + ruff check . --fix ruff format . install: diff --git a/changelog.d/add-ruff-linting.added.md b/changelog.d/add-ruff-linting.added.md new file mode 100644 index 000000000..597070fb5 --- /dev/null +++ b/changelog.d/add-ruff-linting.added.md @@ -0,0 +1 @@ +Added ruff linting (ruff check) to Makefile format target with E, F, and I rule sets. diff --git a/docs/usage/country.ipynb b/docs/usage/country.ipynb index 5d49b73a6..691dbe2cb 100644 --- a/docs/usage/country.ipynb +++ b/docs/usage/country.ipynb @@ -16,11 +16,11 @@ "outputs": [], "source": [ "from policyengine_core.country_template import (\n", - " CountryTaxBenefitSystem, # Holds all policy-related data.\n", - " Simulation, # General purpose: enables users to simulate policy on new data.\n", - " Microsimulation, # Specific purpose: enables users to simulate policy on large datasets.\n", " COUNTRY_DIR, # Path to the country directory.\n", " DATASETS, # List of datasets available for this country (to use with `Microsimulation`).\n", + " CountryTaxBenefitSystem, # Holds all policy-related data.\n", + " Microsimulation, # Specific purpose: enables users to simulate policy on large datasets.\n", + " Simulation, # General purpose: enables users to simulate policy on new data.\n", ")" ] }, @@ -52,23 +52,16 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n", - "from typing import Dict, Type\n", - "from policyengine_core.data.dataset import Dataset\n", - "from policyengine_core.populations.population import Population\n", - "from policyengine_core.taxbenefitsystems import TaxBenefitSystem\n", "from policyengine_core.country_template import entities\n", - "from policyengine_core.country_template.situation_examples import couple\n", - "from policyengine_core.simulations import Simulation as CoreSimulation\n", - "from policyengine_core.simulations import (\n", - " Microsimulation as CoreMicrosimulation,\n", - ")\n", + "from policyengine_core.country_template.constants import COUNTRY_DIR\n", "from policyengine_core.country_template.data.datasets.country_template_dataset import (\n", " CountryTemplateDataset,\n", ")\n", - "from pathlib import Path\n", - "import logging\n", - "from policyengine_core.country_template.constants import COUNTRY_DIR\n", + "from policyengine_core.simulations import (\n", + " Microsimulation as CoreMicrosimulation,\n", + ")\n", + "from policyengine_core.simulations import Simulation as CoreSimulation\n", + "from policyengine_core.taxbenefitsystems import TaxBenefitSystem\n", "\n", "DATASETS = [CountryTemplateDataset] # Important: must be instantiated\n", "\n", diff --git a/docs/usage/datasets.ipynb b/docs/usage/datasets.ipynb index a7cfbce22..24d6cfa2d 100644 --- a/docs/usage/datasets.ipynb +++ b/docs/usage/datasets.ipynb @@ -32,7 +32,7 @@ "source": [ "from policyengine_core.country_template.constants import COUNTRY_DIR\n", "from policyengine_core.data import Dataset\n", - "from policyengine_core.periods import ETERNITY, MONTH, period\n", + "from policyengine_core.periods import ETERNITY, period\n", "\n", "\n", "class CountryTemplateDataset(Dataset):\n", diff --git a/docs/usage/simulation.ipynb b/docs/usage/simulation.ipynb index 66979a965..8add3e8b5 100644 --- a/docs/usage/simulation.ipynb +++ b/docs/usage/simulation.ipynb @@ -1044,7 +1044,8 @@ ], "source": [ "import plotly.express as px\n", - "from policyengine_core.charts import format_fig, display_fig, BLUE\n", + "\n", + "from policyengine_core.charts import BLUE, format_fig\n", "\n", "fig = (\n", " px.line(\n", diff --git a/policyengine_core/charts/__init__.py b/policyengine_core/charts/__init__.py index f12564970..69c00d563 100644 --- a/policyengine_core/charts/__init__.py +++ b/policyengine_core/charts/__init__.py @@ -1,15 +1,14 @@ +from .api import * +from .bar import * from .formatting import ( BLUE, BLUE_COLOUR_SCALE, - DARK_GREEN, - LIGHT_GREEN, DARK_GRAY, + DARK_GREEN, GRAY, LIGHT_GRAY, + LIGHT_GREEN, WHITE, - format_fig, display_fig, + format_fig, ) - -from .bar import * -from .api import * diff --git a/policyengine_core/charts/api.py b/policyengine_core/charts/api.py index cddc2bf32..6fb9da460 100644 --- a/policyengine_core/charts/api.py +++ b/policyengine_core/charts/api.py @@ -1,12 +1,14 @@ -import requests import time + import plotly.graph_objects as go +import requests + from .formatting import ( + BLUE_LIGHT, + BLUE_PRIMARY, DARK_GRAY, MEDIUM_DARK_GRAY, WHITE, - BLUE_LIGHT, - BLUE_PRIMARY, format_fig, ) diff --git a/policyengine_core/charts/bar.py b/policyengine_core/charts/bar.py index 03798cb0c..063c0f86a 100644 --- a/policyengine_core/charts/bar.py +++ b/policyengine_core/charts/bar.py @@ -1,9 +1,11 @@ +from typing import Callable + +import numpy as np import pandas as pd -from .formatting import * import plotly.express as px from microdf import MicroSeries -from typing import Callable -import numpy as np + +from .formatting import * def bar_chart( diff --git a/policyengine_core/commons/formulas.py b/policyengine_core/commons/formulas.py index 425628d55..adca3f2fb 100644 --- a/policyengine_core/commons/formulas.py +++ b/policyengine_core/commons/formulas.py @@ -1,16 +1,13 @@ import logging from typing import Any, Callable, Dict, List, Sequence, Type, TypeVar, Union +from warnings import warn import numpy import numpy as np import pandas as pd -from numpy import logical_not as not_ from numpy import maximum as max_ from numpy import minimum as min_ -from numpy import round as round_ -from numpy import select, where - -from warnings import warn +from numpy import select from policyengine_core.parameters.parameter_node import ParameterNode from policyengine_core.periods.period_ import Period @@ -18,8 +15,6 @@ from policyengine_core.types import ArrayLike, ArrayType from policyengine_core.variables.variable import Variable -import json - T = TypeVar("T") @@ -426,7 +421,7 @@ def sum_of_variables(variables: Union[List[str], str]) -> Callable: """ warn( - f"Sum-of-variables formulas are deprecated- please use `adds` or `subtracts` instead." + "Sum-of-variables formulas are deprecated- please use `adds` or `subtracts` instead." ) def sum_of_variables(entity, period, parameters): diff --git a/policyengine_core/country_template/data/datasets/country_template_dataset.py b/policyengine_core/country_template/data/datasets/country_template_dataset.py index d0ae21795..0abd45ef3 100644 --- a/policyengine_core/country_template/data/datasets/country_template_dataset.py +++ b/policyengine_core/country_template/data/datasets/country_template_dataset.py @@ -1,6 +1,6 @@ from policyengine_core.country_template.constants import COUNTRY_DIR from policyengine_core.data import Dataset -from policyengine_core.periods import ETERNITY, MONTH, period +from policyengine_core.periods import ETERNITY, period class CountryTemplateDataset(Dataset): diff --git a/policyengine_core/data/dataset.py b/policyengine_core/data/dataset.py index 7caebb0c0..70478e5ab 100644 --- a/policyengine_core/data/dataset.py +++ b/policyengine_core/data/dataset.py @@ -1,19 +1,21 @@ +import os +import shutil +import sys +import tempfile from pathlib import Path -from typing import Dict, Union, List +from typing import Dict, List, Union + import h5py import numpy as np import pandas as pd -import shutil import requests -import os -import tempfile -from policyengine_core.tools.hugging_face import * + from policyengine_core.tools.google_cloud import ( - parse_gs_url, download_gcs_file, + parse_gs_url, upload_gcs_file, ) -import sys +from policyengine_core.tools.hugging_face import * from policyengine_core.tools.win_file_manager import WindowsAtomicFileManager diff --git a/policyengine_core/data_storage/in_memory_storage.py b/policyengine_core/data_storage/in_memory_storage.py index a5e510b42..a87c6ff59 100644 --- a/policyengine_core/data_storage/in_memory_storage.py +++ b/policyengine_core/data_storage/in_memory_storage.py @@ -1,4 +1,4 @@ -from typing import Dict, Union +from typing import Dict import numpy from numpy.typing import ArrayLike diff --git a/policyengine_core/entities/helpers.py b/policyengine_core/entities/helpers.py index bb0162ac0..c537f7de5 100644 --- a/policyengine_core/entities/helpers.py +++ b/policyengine_core/entities/helpers.py @@ -1,4 +1,4 @@ -from typing import List, Union +from typing import List from policyengine_core import entities from policyengine_core.entities.entity import Entity diff --git a/policyengine_core/enums/enum.py b/policyengine_core/enums/enum.py index 0522cdaf5..8cfdfea4b 100644 --- a/policyengine_core/enums/enum.py +++ b/policyengine_core/enums/enum.py @@ -1,9 +1,12 @@ from __future__ import annotations + import enum import logging from functools import lru_cache from typing import Tuple, Union + import numpy as np + from .config import ENUM_ARRAY_DTYPE from .enum_array import EnumArray diff --git a/policyengine_core/model_api.py b/policyengine_core/model_api.py index 68f1f2dd4..87244c653 100644 --- a/policyengine_core/model_api.py +++ b/policyengine_core/model_api.py @@ -1,33 +1,5 @@ -from datetime import date - -from numpy import logical_not as not_ -from numpy import maximum as max_ -from numpy import minimum as min_ -from numpy import round as round_ -from numpy import select, where - -from policyengine_core.enums import Enum -from policyengine_core.holders import ( - set_input_dispatch_by_period, - set_input_divide_by_period, -) -from policyengine_core.parameters import ( - Parameter, - ParameterNode, - ParameterScale, - ParameterScaleBracket, - load_parameter_file, -) -from policyengine_core.periods import DAY, ETERNITY, MONTH, YEAR, period -from policyengine_core.populations import ADD, DIVIDE -from policyengine_core.reforms import Reform -from policyengine_core.simulations import ( - calculate_output_add, - calculate_output_divide, -) from policyengine_core.variables import ( QuantityType, - Variable, VariableCategory, ) diff --git a/policyengine_core/parameters/__init__.py b/policyengine_core/parameters/__init__.py index 29a5faa43..04ff45fb3 100644 --- a/policyengine_core/parameters/__init__.py +++ b/policyengine_core/parameters/__init__.py @@ -13,11 +13,11 @@ ) from .helpers import contains_nan, load_parameter_file from .operations import ( + get_parameter, homogenize_parameter_structures, interpolate_parameters, propagate_parameter_metadata, uprate_parameters, - get_parameter, ) from .parameter import Parameter from .parameter_at_instant import ParameterAtInstant diff --git a/policyengine_core/parameters/operations/homogenize_parameters.py b/policyengine_core/parameters/operations/homogenize_parameters.py index 6d2e830a7..6ce0f5540 100644 --- a/policyengine_core/parameters/operations/homogenize_parameters.py +++ b/policyengine_core/parameters/operations/homogenize_parameters.py @@ -1,5 +1,5 @@ import logging -from typing import Any, Dict, List, Type +from typing import Any, Dict, List from policyengine_core.enums import Enum from policyengine_core.parameters.parameter import Parameter diff --git a/policyengine_core/parameters/operations/propagate_parameter_metadata.py b/policyengine_core/parameters/operations/propagate_parameter_metadata.py index de2925ad3..e23a94547 100644 --- a/policyengine_core/parameters/operations/propagate_parameter_metadata.py +++ b/policyengine_core/parameters/operations/propagate_parameter_metadata.py @@ -1,4 +1,3 @@ -from policyengine_core.parameters.parameter import Parameter from policyengine_core.parameters.parameter_node import ParameterNode diff --git a/policyengine_core/parameters/operations/uprate_parameters.py b/policyengine_core/parameters/operations/uprate_parameters.py index 415b9fbf9..2e639330a 100644 --- a/policyengine_core/parameters/operations/uprate_parameters.py +++ b/policyengine_core/parameters/operations/uprate_parameters.py @@ -1,11 +1,11 @@ -from numpy import ceil, floor +from datetime import datetime # rrule is purposely imported this way to allow for programmatic # calling of rrule.YEARLY, rrule.MONTHLY, and rrule.DAILY from dateutil import rrule -from dateutil.relativedelta import relativedelta from dateutil.parser import parse -from datetime import datetime +from dateutil.relativedelta import relativedelta +from numpy import ceil, floor from policyengine_core.parameters.operations.get_parameter import get_parameter from policyengine_core.parameters.parameter import Parameter @@ -14,7 +14,7 @@ ) from policyengine_core.parameters.parameter_node import ParameterNode from policyengine_core.parameters.parameter_scale import ParameterScale -from policyengine_core.periods import instant, Instant +from policyengine_core.periods import instant def uprate_parameters(root: ParameterNode) -> ParameterNode: diff --git a/policyengine_core/parameters/parameter.py b/policyengine_core/parameters/parameter.py index 50c3205f7..8b4dfa89c 100644 --- a/policyengine_core/parameters/parameter.py +++ b/policyengine_core/parameters/parameter.py @@ -2,14 +2,15 @@ import os from typing import Dict, List, Optional +from policyengine_core.commons.misc import empty_clone from policyengine_core.errors import ParameterParsingError -from .at_instant_like import AtInstantLike -from .parameter_at_instant import ParameterAtInstant +from policyengine_core.periods import INSTANT_PATTERN +from policyengine_core.periods import period as get_period -from .helpers import _validate_parameter, _compose_name +from .at_instant_like import AtInstantLike from .config import COMMON_KEYS -from policyengine_core.commons.misc import empty_clone -from policyengine_core.periods import INSTANT_PATTERN, period as get_period +from .helpers import _compose_name, _validate_parameter +from .parameter_at_instant import ParameterAtInstant class Parameter(AtInstantLike): diff --git a/policyengine_core/parameters/parameter_node.py b/policyengine_core/parameters/parameter_node.py index 94dbd88ff..e88ac65fe 100644 --- a/policyengine_core/parameters/parameter_node.py +++ b/policyengine_core/parameters/parameter_node.py @@ -1,24 +1,23 @@ import copy import os import typing -from typing import Iterable, List, Type, Union +from typing import Iterable, Union from policyengine_core import commons, parameters, tools -from policyengine_core.data_structures import Reference from policyengine_core.periods.instant_ import Instant from policyengine_core.tracers import TracingParameterNodeAtInstant from .at_instant_like import AtInstantLike -from .parameter import Parameter -from .parameter_node_at_instant import ParameterNodeAtInstant from .config import COMMON_KEYS, FILE_EXTENSIONS from .helpers import ( - load_parameter_file, _compose_name, - _validate_parameter, - _parse_child, _load_yaml_file, + _parse_child, + _validate_parameter, + load_parameter_file, ) +from .parameter import Parameter +from .parameter_node_at_instant import ParameterNodeAtInstant EXCLUDED_PARAMETER_CHILD_NAMES = ["reference", "__pycache__"] diff --git a/policyengine_core/parameters/parameter_node_at_instant.py b/policyengine_core/parameters/parameter_node_at_instant.py index 343e152dc..64152c7e7 100644 --- a/policyengine_core/parameters/parameter_node_at_instant.py +++ b/policyengine_core/parameters/parameter_node_at_instant.py @@ -1,5 +1,4 @@ import os -import sys from typing import TYPE_CHECKING, Iterable, Union import numpy diff --git a/policyengine_core/parameters/parameter_scale_bracket.py b/policyengine_core/parameters/parameter_scale_bracket.py index 703b25a77..2cbc12eb0 100644 --- a/policyengine_core/parameters/parameter_scale_bracket.py +++ b/policyengine_core/parameters/parameter_scale_bracket.py @@ -1,4 +1,5 @@ from typing import Iterable + from policyengine_core.parameters import Parameter, ParameterNode diff --git a/policyengine_core/periods/period_.py b/policyengine_core/periods/period_.py index fd58f69c0..3a235fe4d 100644 --- a/policyengine_core/periods/period_.py +++ b/policyengine_core/periods/period_.py @@ -1,7 +1,7 @@ from __future__ import annotations import calendar -from datetime import datetime, date, timedelta +from datetime import date, datetime, timedelta from typing import List from policyengine_core import periods diff --git a/policyengine_core/populations/group_population.py b/policyengine_core/populations/group_population.py index c770ee751..8e7b6f890 100644 --- a/policyengine_core/populations/group_population.py +++ b/policyengine_core/populations/group_population.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Callable +from typing import TYPE_CHECKING, Any, Callable, Container, Optional import numpy from numpy.typing import ArrayLike @@ -6,9 +6,8 @@ from policyengine_core import projectors from policyengine_core.entities import Entity, Role from policyengine_core.enums import EnumArray -from policyengine_core.populations.population import Population from policyengine_core.periods.period_ import Period -from typing import Optional, Container +from policyengine_core.populations.population import Population if TYPE_CHECKING: from policyengine_core.simulations import Simulation diff --git a/policyengine_core/populations/population.py b/policyengine_core/populations/population.py index fbce9dcbf..c03774643 100644 --- a/policyengine_core/populations/population.py +++ b/policyengine_core/populations/population.py @@ -1,5 +1,5 @@ import traceback -from typing import TYPE_CHECKING, Any, List, Optional, Container +from typing import TYPE_CHECKING, Any, Container, List, Optional import numpy from numpy.typing import ArrayLike diff --git a/policyengine_core/reforms/reform.py b/policyengine_core/reforms/reform.py index 068cac240..672c1a6e9 100644 --- a/policyengine_core/reforms/reform.py +++ b/policyengine_core/reforms/reform.py @@ -1,20 +1,21 @@ from __future__ import annotations import copy -from typing import Callable, Union, TYPE_CHECKING +from typing import TYPE_CHECKING, Callable, Union -from policyengine_core.parameters import ParameterNode, Parameter +from policyengine_core.parameters import Parameter, ParameterNode from policyengine_core.taxbenefitsystems import TaxBenefitSystem if TYPE_CHECKING: from policyengine_core.simulations import Simulation +import requests + from policyengine_core.periods import ( - period as period_, instant as instant_, - Period, ) - -import requests +from policyengine_core.periods import ( + period as period_, +) class classproperty(object): diff --git a/policyengine_core/scripts/policyengine_command.py b/policyengine_core/scripts/policyengine_command.py index 7aa85c888..d240346f9 100644 --- a/policyengine_core/scripts/policyengine_command.py +++ b/policyengine_core/scripts/policyengine_command.py @@ -1,6 +1,5 @@ import argparse import sys -import warnings from policyengine_core.scripts import add_tax_benefit_system_arguments diff --git a/policyengine_core/simulations/__init__.py b/policyengine_core/simulations/__init__.py index c992f3a2b..03c5ba788 100644 --- a/policyengine_core/simulations/__init__.py +++ b/policyengine_core/simulations/__init__.py @@ -6,7 +6,7 @@ check_type, transform_to_strict_syntax, ) +from .individual_sim import IndividualSim from .microsimulation import Microsimulation from .simulation import Simulation from .simulation_builder import SimulationBuilder -from .individual_sim import IndividualSim diff --git a/policyengine_core/simulations/individual_sim.py b/policyengine_core/simulations/individual_sim.py index c00933c87..1438a79cb 100644 --- a/policyengine_core/simulations/individual_sim.py +++ b/policyengine_core/simulations/individual_sim.py @@ -3,14 +3,13 @@ """ from functools import partial -from typing import Dict, List import numpy as np from policyengine_core.entities.entity import Entity from policyengine_core.periods import period from policyengine_core.reforms import Reform, set_parameter -from policyengine_core.simulations import SimulationBuilder, Simulation +from policyengine_core.simulations import Simulation, SimulationBuilder from policyengine_core.taxbenefitsystems.tax_benefit_system import ( TaxBenefitSystem, ) diff --git a/policyengine_core/simulations/microsimulation.py b/policyengine_core/simulations/microsimulation.py index 28410d044..8264d963b 100644 --- a/policyengine_core/simulations/microsimulation.py +++ b/policyengine_core/simulations/microsimulation.py @@ -1,8 +1,6 @@ -from typing import Dict, Type - -from microdf import MicroDataFrame, MicroSeries import numpy as np -from policyengine_core.data.dataset import Dataset +from microdf import MicroDataFrame, MicroSeries + from policyengine_core.periods import Period from policyengine_core.periods import period as get_period from policyengine_core.periods.config import MONTH, YEAR diff --git a/policyengine_core/simulations/simulation.py b/policyengine_core/simulations/simulation.py index 8f79c3b70..f49781e89 100644 --- a/policyengine_core/simulations/simulation.py +++ b/policyengine_core/simulations/simulation.py @@ -1,11 +1,12 @@ +import json +import random import tempfile +from pathlib import Path from typing import TYPE_CHECKING, Any, Dict, List, Type, Union import numpy as np import pandas as pd from numpy.typing import ArrayLike -import logging -from pathlib import Path from policyengine_core import commons, periods from policyengine_core.data.dataset import Dataset @@ -14,34 +15,29 @@ from policyengine_core.errors import CycleError, SpiralError from policyengine_core.holders.holder import Holder from policyengine_core.periods import Period -from policyengine_core.periods.config import ETERNITY, MONTH, YEAR -from policyengine_core.periods.helpers import period +from policyengine_core.periods.config import MONTH, YEAR +from policyengine_core.tools.google_cloud import ( + download_gcs_file, + parse_gs_url, +) +from policyengine_core.tools.hugging_face import * from policyengine_core.tracers import ( FullTracer, SimpleTracer, TracingParameterNodeAtInstant, ) -import random -from policyengine_core.tools.hugging_face import * -from policyengine_core.tools.google_cloud import ( - parse_gs_url, - download_gcs_file, -) - -import json if TYPE_CHECKING: from policyengine_core.taxbenefitsystems import TaxBenefitSystem from policyengine_core.experimental import MemoryConfig -from policyengine_core.populations import Population, GroupPopulation -from policyengine_core.tracers import SimpleTracer -from policyengine_core.variables import Variable, QuantityType -from policyengine_core.reforms.reform import Reform from policyengine_core.parameters import get_parameter +from policyengine_core.populations import GroupPopulation, Population +from policyengine_core.reforms.reform import Reform from policyengine_core.simulations.simulation_macro_cache import ( SimulationMacroCache, ) +from policyengine_core.variables import QuantityType, Variable class Simulation: @@ -592,7 +588,7 @@ def _calculate(self, variable_name: str, period: Period = None) -> ArrayLike: ] ): return holder.default_array() - except Exception as e: + except Exception: pass # First look for a value already cached @@ -735,7 +731,7 @@ def _calculate(self, variable_name: str, period: Period = None) -> ArrayLike: except SpiralError: array = holder.default_array() - except RecursionError as e: + except RecursionError: if isinstance(self.tracer, FullTracer): self.tracer.print_computation_log() stack = self.tracer.stack diff --git a/policyengine_core/simulations/simulation_builder.py b/policyengine_core/simulations/simulation_builder.py index 628a478c4..09aba30fd 100644 --- a/policyengine_core/simulations/simulation_builder.py +++ b/policyengine_core/simulations/simulation_builder.py @@ -15,21 +15,22 @@ ) from policyengine_core.periods import Period from policyengine_core.populations import GroupPopulation, Population -from policyengine_core.simulations.simulation import Simulation from policyengine_core.simulations.helpers import ( - check_type, _get_person_count, + check_type, transform_to_strict_syntax, ) +from policyengine_core.simulations.simulation import Simulation if TYPE_CHECKING: from policyengine_core.taxbenefitsystems.tax_benefit_system import ( TaxBenefitSystem, ) -from policyengine_core.variables import Variable from datetime import datetime +from policyengine_core.variables import Variable + class SimulationBuilder: def __init__(self): diff --git a/policyengine_core/simulations/simulation_macro_cache.py b/policyengine_core/simulations/simulation_macro_cache.py index 80520c6b3..5c720e956 100644 --- a/policyengine_core/simulations/simulation_macro_cache.py +++ b/policyengine_core/simulations/simulation_macro_cache.py @@ -1,8 +1,9 @@ +import importlib.metadata import shutil from pathlib import Path + import h5py from numpy.typing import ArrayLike -import importlib.metadata from policyengine_core.taxbenefitsystems import TaxBenefitSystem diff --git a/policyengine_core/taxbenefitsystems/tax_benefit_system.py b/policyengine_core/taxbenefitsystems/tax_benefit_system.py index 077f6f27e..fc6539a81 100644 --- a/policyengine_core/taxbenefitsystems/tax_benefit_system.py +++ b/policyengine_core/taxbenefitsystems/tax_benefit_system.py @@ -6,13 +6,11 @@ import inspect import logging import os -import yaml -from pathlib import Path import sys import traceback import typing +from pathlib import Path from typing import ( - TYPE_CHECKING, Any, Callable, Dict, @@ -20,21 +18,20 @@ Optional, Sequence, Type, - Union, ) -import importlib + +import yaml from policyengine_core import commons, periods, variables -from policyengine_core.data_structures.reference import Reference from policyengine_core.entities import Entity from policyengine_core.errors import ( VariableNameConflictError, VariableNotFoundError, ) from policyengine_core.parameters import ( + Parameter, ParameterNode, ParameterNodeAtInstant, - Parameter, ) from policyengine_core.parameters.operations.homogenize_parameters import ( homogenize_parameter_structures, @@ -174,7 +171,7 @@ def add_abolition_parameters(self): "unit": "bool", }, } - if not "abolitions" in self.parameters.gov.children: + if "abolitions" not in self.parameters.gov.children: self.parameters.gov.add_child( "abolitions", ParameterNode(name="gov.abolitions", data=abolition_folder_data), diff --git a/policyengine_core/tools/google_cloud.py b/policyengine_core/tools/google_cloud.py index 791b1121b..dc56864e4 100644 --- a/policyengine_core/tools/google_cloud.py +++ b/policyengine_core/tools/google_cloud.py @@ -60,8 +60,8 @@ def download_gcs_file( The local path where the file was saved. """ try: - from google.cloud import storage import google.auth + from google.cloud import storage except ImportError: raise ImportError( "google-cloud-storage is required for gs:// URLs. " @@ -103,8 +103,8 @@ def upload_gcs_file( version_metadata: Optional version string to store in blob metadata. """ try: - from google.cloud import storage import google.auth + from google.cloud import storage except ImportError: raise ImportError( "google-cloud-storage is required for gs:// URLs. " diff --git a/policyengine_core/tools/hugging_face.py b/policyengine_core/tools/hugging_face.py index 7964658f3..ee008fb09 100644 --- a/policyengine_core/tools/hugging_face.py +++ b/policyengine_core/tools/hugging_face.py @@ -1,13 +1,14 @@ +import os +import traceback +import warnings +from getpass import getpass + from huggingface_hub import ( + ModelInfo, hf_hub_download, model_info, - ModelInfo, ) from huggingface_hub.errors import RepositoryNotFoundError -from getpass import getpass -import os -import warnings -import traceback with warnings.catch_warnings(): warnings.simplefilter("ignore") @@ -66,11 +67,11 @@ def download_huggingface_dataset( try: fetched_model_info: ModelInfo = model_info(repo) is_repo_private: bool = fetched_model_info.private - except RepositoryNotFoundError as e: + except RepositoryNotFoundError: # If this error type arises, it's likely the repo is private; see docs above is_repo_private = True pass - except Exception as e: + except Exception: # Otherwise, there probably is just a download error raise Exception( f"Unable to download dataset {repo_filename} from Hugging Face. This may be because the repo " diff --git a/policyengine_core/tools/test_from_situation.py b/policyengine_core/tools/test_from_situation.py index 4ec3bb862..4e6e43ca7 100644 --- a/policyengine_core/tools/test_from_situation.py +++ b/policyengine_core/tools/test_from_situation.py @@ -1,7 +1,6 @@ -import yaml from pathlib import Path -import numpy as np -import json + +import yaml def generate_test_from_situation(situation: dict, file_path: str): diff --git a/policyengine_core/tools/test_runner.py b/policyengine_core/tools/test_runner.py index 1874ceed7..1468b8b8a 100644 --- a/policyengine_core/tools/test_runner.py +++ b/policyengine_core/tools/test_runner.py @@ -1,28 +1,26 @@ # -*- coding: utf-8 -*- import logging -import sys import os -import traceback +import sys import textwrap +import traceback from typing import Dict, List import pytest from policyengine_core.enums import EnumArray -from policyengine_core.tools import ( - assert_enum_equals, - assert_datetime_equals, - eval_expression, -) -from policyengine_core.simulations import SimulationBuilder from policyengine_core.errors import ( SituationParsingError, VariableNotFoundError, ) -from policyengine_core.scripts import build_tax_benefit_system from policyengine_core.reforms import Reform, set_parameter -from policyengine_core.populations import ADD, DIVIDE +from policyengine_core.simulations import SimulationBuilder +from policyengine_core.tools import ( + assert_datetime_equals, + assert_enum_equals, + eval_expression, +) log = logging.getLogger(__name__) @@ -196,7 +194,7 @@ def runtest(self): key, value, return_modifier=True, - period=f"year:2000:40", + period="year:2000:40", ) ] parametric_reform_items.append((key, value)) diff --git a/policyengine_core/tracers/__init__.py b/policyengine_core/tracers/__init__.py index e6b07cbd5..d4bcf3da5 100644 --- a/policyengine_core/tracers/__init__.py +++ b/policyengine_core/tracers/__init__.py @@ -2,7 +2,7 @@ from .flat_trace import FlatTrace from .full_tracer import FullTracer from .performance_log import PerformanceLog -from .variable_graph import VariableGraph from .simple_tracer import SimpleTracer from .trace_node import TraceNode from .tracing_parameter_node_at_instant import TracingParameterNodeAtInstant +from .variable_graph import VariableGraph diff --git a/policyengine_core/tracers/trace_node.py b/policyengine_core/tracers/trace_node.py index 501648774..4844caeb4 100644 --- a/policyengine_core/tracers/trace_node.py +++ b/policyengine_core/tracers/trace_node.py @@ -7,7 +7,6 @@ import numpy from policyengine_core.enums import EnumArray - from policyengine_core.periods import Period Array = typing.Union[EnumArray, numpy.typing.ArrayLike] Time = typing.Union[float, int] diff --git a/policyengine_core/tracers/tracing_parameter_node_at_instant.py b/policyengine_core/tracers/tracing_parameter_node_at_instant.py index d4bf17466..eae2efde9 100644 --- a/policyengine_core/tracers/tracing_parameter_node_at_instant.py +++ b/policyengine_core/tracers/tracing_parameter_node_at_instant.py @@ -11,6 +11,7 @@ if typing.TYPE_CHECKING: from numpy.typing import ArrayLike + from policyengine_core.parameters import ( ParameterNodeAtInstant, VectorialParameterNodeAtInstant, diff --git a/policyengine_core/tracers/variable_graph.py b/policyengine_core/tracers/variable_graph.py index 723e20e99..b29e2ed51 100644 --- a/policyengine_core/tracers/variable_graph.py +++ b/policyengine_core/tracers/variable_graph.py @@ -6,14 +6,12 @@ from typing import Optional, Union import numpy -from pyvis.node import Node +from pyvis.network import Network from policyengine_core.enums import EnumArray from .. import tracers -from pyvis.network import Network - if typing.TYPE_CHECKING: from numpy.typing import ArrayLike diff --git a/policyengine_core/types/data_types/arrays.py b/policyengine_core/types/data_types/arrays.py index 4068906fb..120050ca6 100644 --- a/policyengine_core/types/data_types/arrays.py +++ b/policyengine_core/types/data_types/arrays.py @@ -1,5 +1,4 @@ -from typing import Sequence, TypeVar, Any -from numpy.typing import NDArray as ArrayType +from typing import Sequence, TypeVar T = TypeVar("T", bool, bytes, float, int, object, str) diff --git a/policyengine_core/variables/defined_for.py b/policyengine_core/variables/defined_for.py index 597bc874b..5f9dd35fb 100644 --- a/policyengine_core/variables/defined_for.py +++ b/policyengine_core/variables/defined_for.py @@ -2,10 +2,9 @@ import numpy as np from numpy.typing import ArrayLike -from policyengine_core.entities import Entity -from policyengine_core.populations import GroupPopulation, Population -from policyengine_core.projectors import EntityToPersonProjector, Projector -from policyengine_core.variables import Variable + +from policyengine_core.populations import Population +from policyengine_core.projectors import EntityToPersonProjector class CallableSubset: diff --git a/policyengine_core/variables/variable.py b/policyengine_core/variables/variable.py index dda76e0bb..5880d96cb 100644 --- a/policyengine_core/variables/variable.py +++ b/policyengine_core/variables/variable.py @@ -10,12 +10,11 @@ from policyengine_core import periods, tools from policyengine_core.entities import Entity from policyengine_core.enums import Enum, EnumArray -from policyengine_core.periods import Period from policyengine_core.holders import ( set_input_dispatch_by_period, set_input_divide_by_period, ) -from policyengine_core.periods import DAY, ETERNITY +from policyengine_core.periods import DAY, ETERNITY, Period from . import config, helpers diff --git a/pyproject.toml b/pyproject.toml index 85f789b15..6f30248f9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,3 +103,19 @@ showcontent = true directory = "removed" name = "Removed" showcontent = true + +[tool.ruff.lint] +select = ["E", "F", "I"] +ignore = [ + "E402", # module-import-not-at-top-of-file + "E501", # line too long (handled by ruff format) + "E712", # true-false-comparison (common in numpy/pandas code) + "E721", # type-comparison + "E722", # bare-except + "E741", # ambiguous-variable-name + "F401", # unused-import (many are intentional re-exports) + "F403", # undefined-local-with-import-star + "F405", # undefined-local-with-import-star-usage + "F811", # redefined-while-unused + "F841", # unused-variable +] diff --git a/test.ipynb b/test.ipynb index 310c0da93..6a29ad645 100644 --- a/test.ipynb +++ b/test.ipynb @@ -7,6 +7,7 @@ "outputs": [], "source": [ "from policyengine_uk import Microsimulation\n", + "\n", "from policyengine_core.reforms import Reform\n", "\n", "reform = Reform.from_dict(\n", diff --git a/tests/core/commons/test_between_function.py b/tests/core/commons/test_between_function.py index 7ad050567..aff5b033d 100644 --- a/tests/core/commons/test_between_function.py +++ b/tests/core/commons/test_between_function.py @@ -1,7 +1,7 @@ """Test the between function from commons.formulas.""" import numpy as np -import pytest + from policyengine_core.commons.formulas import between diff --git a/tests/core/commons/test_is_in_function.py b/tests/core/commons/test_is_in_function.py index ee724ffda..edd976b9e 100644 --- a/tests/core/commons/test_is_in_function.py +++ b/tests/core/commons/test_is_in_function.py @@ -1,7 +1,7 @@ """Test the is_in function from commons.formulas.""" import numpy as np -import pytest + from policyengine_core.commons.formulas import is_in diff --git a/tests/core/commons/test_random_seed.py b/tests/core/commons/test_random_seed.py index e63abe3f7..68cd73d36 100644 --- a/tests/core/commons/test_random_seed.py +++ b/tests/core/commons/test_random_seed.py @@ -1,8 +1,9 @@ """Test the random function with large entity IDs to ensure no overflow.""" -import numpy as np -import pytest from unittest.mock import Mock + +import numpy as np + from policyengine_core.commons.formulas import random diff --git a/tests/core/data/test_dataset.py b/tests/core/data/test_dataset.py index d53703659..b74bdadec 100644 --- a/tests/core/data/test_dataset.py +++ b/tests/core/data/test_dataset.py @@ -1,11 +1,11 @@ -from pathlib import Path -from tempfile import NamedTemporaryFile import sys -import threading -from policyengine_core.tools.win_file_manager import WindowsAtomicFileManager import tempfile -from pathlib import Path +import threading import uuid +from pathlib import Path +from tempfile import NamedTemporaryFile + +from policyengine_core.tools.win_file_manager import WindowsAtomicFileManager def test_dataset_class(): diff --git a/tests/core/enums/test_enum.py b/tests/core/enums/test_enum.py index 19983f835..52811251b 100644 --- a/tests/core/enums/test_enum.py +++ b/tests/core/enums/test_enum.py @@ -1,5 +1,6 @@ -import pytest import numpy as np +import pytest + from policyengine_core.enums.enum import Enum from policyengine_core.enums.enum_array import EnumArray diff --git a/tests/core/parameters/test_numpy2_structured_arrays.py b/tests/core/parameters/test_numpy2_structured_arrays.py index b0a4be1be..97c4e2af2 100644 --- a/tests/core/parameters/test_numpy2_structured_arrays.py +++ b/tests/core/parameters/test_numpy2_structured_arrays.py @@ -10,7 +10,7 @@ import numpy as np import pytest -from policyengine_core.parameters import ParameterNode + from policyengine_core.parameters.vectorial_parameter_node_at_instant import ( VectorialParameterNodeAtInstant, ) diff --git a/tests/core/parameters_fancy_indexing/test_fancy_indexing.py b/tests/core/parameters_fancy_indexing/test_fancy_indexing.py index a3eaed648..1b9b53f4f 100644 --- a/tests/core/parameters_fancy_indexing/test_fancy_indexing.py +++ b/tests/core/parameters_fancy_indexing/test_fancy_indexing.py @@ -1,14 +1,12 @@ # -*- coding: utf-8 -*- import os -import re import numpy as np import pytest from policyengine_core.model_api import * from policyengine_core.parameters import ( - Parameter, ParameterNode, ParameterNotFoundError, ) diff --git a/tests/core/test_countries.py b/tests/core/test_countries.py index 6fa70b457..d1d2ce449 100644 --- a/tests/core/test_countries.py +++ b/tests/core/test_countries.py @@ -3,9 +3,7 @@ from policyengine_core import periods, populations, tools from policyengine_core.errors import ( VariableNameConflictError, - VariableNotFoundError, ) -from policyengine_core.simulations import SimulationBuilder from policyengine_core.variables import Variable PERIOD = periods.period("2016-01") diff --git a/tests/core/test_cycles.py b/tests/core/test_cycles.py index a488765b1..318a081be 100644 --- a/tests/core/test_cycles.py +++ b/tests/core/test_cycles.py @@ -3,7 +3,7 @@ from policyengine_core import periods, tools from policyengine_core.country_template import entities from policyengine_core.errors import CycleError -from policyengine_core.simulations import SimulationBuilder, Simulation +from policyengine_core.simulations import Simulation, SimulationBuilder from policyengine_core.variables import Variable diff --git a/tests/core/test_entities.py b/tests/core/test_entities.py index f9660e112..e11feccf6 100644 --- a/tests/core/test_entities.py +++ b/tests/core/test_entities.py @@ -1,5 +1,5 @@ from copy import deepcopy -from typing import Dict, Any +from typing import Any, Dict from policyengine_core import tools from policyengine_core.country_template import entities, situation_examples diff --git a/tests/core/test_holders.py b/tests/core/test_holders.py index 94aebe09d..70c3b2858 100644 --- a/tests/core/test_holders.py +++ b/tests/core/test_holders.py @@ -4,7 +4,6 @@ from policyengine_core import holders, periods, tools from policyengine_core.country_template import situation_examples from policyengine_core.country_template.variables import housing -from policyengine_core.errors import PeriodMismatchError from policyengine_core.experimental import MemoryConfig from policyengine_core.holders import Holder from policyengine_core.simulations import SimulationBuilder diff --git a/tests/core/test_microsimulation_person_accessor.py b/tests/core/test_microsimulation_person_accessor.py index 0f9cebd64..7ba3cfff0 100644 --- a/tests/core/test_microsimulation_person_accessor.py +++ b/tests/core/test_microsimulation_person_accessor.py @@ -11,7 +11,6 @@ """ import numpy as np -import pytest from microdf import MicroSeries from policyengine_core.country_template import Microsimulation diff --git a/tests/core/test_pandas3_compatibility.py b/tests/core/test_pandas3_compatibility.py index 8687bf225..a0a128288 100644 --- a/tests/core/test_pandas3_compatibility.py +++ b/tests/core/test_pandas3_compatibility.py @@ -20,8 +20,8 @@ def test_filled_array_with_string_dtype(self): In pandas 3.0.0, string columns use StringDtype by default. numpy.full() cannot handle StringDtype, so we need to handle this case. """ - from policyengine_core.populations.population import Population from policyengine_core.entities import Entity + from policyengine_core.populations.population import Population # Create a minimal entity for testing entity = Entity( @@ -53,8 +53,8 @@ def test_filled_array_with_pyarrow_string_dtype(self): """ pa = pytest.importorskip("pyarrow") - from policyengine_core.populations.population import Population from policyengine_core.entities import Entity + from policyengine_core.populations.population import Population entity = Entity( key="person", @@ -101,11 +101,13 @@ def test_parameter_node_at_instant_getitem_with_string_array(self): This is issue #429. """ - from policyengine_core.parameters import ParameterNode - import tempfile import os + import tempfile + import yaml + from policyengine_core.parameters import ParameterNode + # Create a minimal parameter tree for testing with tempfile.TemporaryDirectory() as tmpdir: # Create parameter YAML files diff --git a/tests/core/test_projectors.py b/tests/core/test_projectors.py index b1795336e..b52decdd5 100644 --- a/tests/core/test_projectors.py +++ b/tests/core/test_projectors.py @@ -4,7 +4,6 @@ from policyengine_core.entities import build_entity from policyengine_core.model_api import ETERNITY, Enum, Variable from policyengine_core.simulations.simulation_builder import SimulationBuilder - from policyengine_core.taxbenefitsystems import TaxBenefitSystem diff --git a/tests/core/test_reforms.py b/tests/core/test_reforms.py index a6075ed9d..55611a54f 100644 --- a/tests/core/test_reforms.py +++ b/tests/core/test_reforms.py @@ -2,7 +2,6 @@ import pytest -from policyengine_core import periods from policyengine_core.country_template.entities import Household, Person from policyengine_core.model_api import * from policyengine_core.parameters import ParameterNode diff --git a/tests/core/test_simulations.py b/tests/core/test_simulations.py index c6cf3140c..00ee7e2df 100644 --- a/tests/core/test_simulations.py +++ b/tests/core/test_simulations.py @@ -1,11 +1,13 @@ +import importlib.metadata +from pathlib import Path + +import numpy as np + from policyengine_core.country_template.situation_examples import single from policyengine_core.simulations import SimulationBuilder from policyengine_core.simulations.simulation_macro_cache import ( SimulationMacroCache, ) -import importlib.metadata -import numpy as np -from pathlib import Path def test_calculate_full_tracer(tax_benefit_system): diff --git a/tests/core/test_tracers.py b/tests/core/test_tracers.py index e653f39be..2a9a818d5 100644 --- a/tests/core/test_tracers.py +++ b/tests/core/test_tracers.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- -import csv import json -import os import numpy as np from pytest import approx, fixture, mark, raises diff --git a/tests/core/tools/test_google_cloud.py b/tests/core/tools/test_google_cloud.py index ccb0403ba..0ec1e2a41 100644 --- a/tests/core/tools/test_google_cloud.py +++ b/tests/core/tools/test_google_cloud.py @@ -1,4 +1,5 @@ import pytest + from policyengine_core.tools.google_cloud import parse_gs_url diff --git a/tests/core/tools/test_hugging_face.py b/tests/core/tools/test_hugging_face.py index 2a68682e2..52d508c46 100644 --- a/tests/core/tools/test_hugging_face.py +++ b/tests/core/tools/test_hugging_face.py @@ -1,11 +1,13 @@ import os +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import patch, MagicMock from huggingface_hub import ModelInfo from huggingface_hub.errors import RepositoryNotFoundError + from policyengine_core.tools.hugging_face import ( - get_or_prompt_hf_token, download_huggingface_dataset, + get_or_prompt_hf_token, parse_hf_url, ) diff --git a/tests/core/tools/test_runner/test_yaml_runner.py b/tests/core/tools/test_runner/test_yaml_runner.py index 72e3faadb..3443e8501 100644 --- a/tests/core/tools/test_runner/test_yaml_runner.py +++ b/tests/core/tools/test_runner/test_yaml_runner.py @@ -1,9 +1,9 @@ import os +from pathlib import Path from typing import List import numpy as np import pytest -from pathlib import Path from policyengine_core.entities import Entity from policyengine_core.errors import VariableNotFoundError diff --git a/tests/core/variables/test_adds.py b/tests/core/variables/test_adds.py index ff6f5bdd9..01f00ca74 100644 --- a/tests/core/variables/test_adds.py +++ b/tests/core/variables/test_adds.py @@ -1,5 +1,3 @@ -import numpy as np - from policyengine_core.entities import Entity from policyengine_core.model_api import * from policyengine_core.simulations import SimulationBuilder @@ -32,5 +30,5 @@ class some_income(Variable): try: simulation.calculate("some_income") raise Exception("Should have raised an error.") - except ValueError as e: + except ValueError: pass diff --git a/tests/core/variables/test_bounds.py b/tests/core/variables/test_bounds.py index b76285b69..912369c6b 100644 --- a/tests/core/variables/test_bounds.py +++ b/tests/core/variables/test_bounds.py @@ -1,8 +1,9 @@ +from test_variables import get_message + import policyengine_core.country_template as country_template from policyengine_core.country_template.entities import Person -from policyengine_core.variables import Variable from policyengine_core.periods import YEAR -from test_variables import get_message +from policyengine_core.variables import Variable tax_benefit_system = country_template.CountryTaxBenefitSystem() diff --git a/tests/core/variables/test_subtracts.py b/tests/core/variables/test_subtracts.py index eeba872fa..822d6055f 100644 --- a/tests/core/variables/test_subtracts.py +++ b/tests/core/variables/test_subtracts.py @@ -1,5 +1,3 @@ -import numpy as np - from policyengine_core.entities import Entity from policyengine_core.model_api import * from policyengine_core.simulations import SimulationBuilder @@ -32,5 +30,5 @@ class some_income(Variable): try: simulation.calculate("some_income") raise Exception("Should have raised an error.") - except ValueError as e: + except ValueError: pass diff --git a/tests/fixtures/variables.py b/tests/fixtures/variables.py index 600107515..b99417e5b 100644 --- a/tests/fixtures/variables.py +++ b/tests/fixtures/variables.py @@ -1,5 +1,4 @@ from policyengine_core import periods -from policyengine_core.entities import Entity from policyengine_core.variables import Variable diff --git a/tests/smoke/test_us.py b/tests/smoke/test_us.py index 65d328681..f8a92fcbb 100644 --- a/tests/smoke/test_us.py +++ b/tests/smoke/test_us.py @@ -1,4 +1,5 @@ import os + import pytest