diff --git a/python/ribasim/ribasim/config.py b/python/ribasim/ribasim/config.py index 78a59e85e..a9acd3350 100644 --- a/python/ribasim/ribasim/config.py +++ b/python/ribasim/ribasim/config.py @@ -80,6 +80,7 @@ class Results(ChildModel): class Solver(ChildModel): """ Defines the numerical solver options. + For more details see . Attributes diff --git a/python/ribasim/ribasim/delwaq/__init__.py b/python/ribasim/ribasim/delwaq/__init__.py index 9aaec6658..d9de44392 100644 --- a/python/ribasim/ribasim/delwaq/__init__.py +++ b/python/ribasim/ribasim/delwaq/__init__.py @@ -7,7 +7,6 @@ "generate", "parse", "run_delwaq", - "plot", "add_tracer", "plot_fraction", "plot_spatial", diff --git a/python/ribasim/ribasim/delwaq/generate.py b/python/ribasim/ribasim/delwaq/generate.py index 44c6f4355..309f7a67b 100644 --- a/python/ribasim/ribasim/delwaq/generate.py +++ b/python/ribasim/ribasim/delwaq/generate.py @@ -57,8 +57,8 @@ def _quote(value): def _make_boundary(data, boundary_type): """ Create a Delwaq boundary definition with the given data and boundary type. - Pivot our data from long to wide format, and convert the time to a string. + Pivot our data from long to wide format, and convert the time to a string. Specifically, we go from a table: `node_id, substance, time, concentration` to @@ -300,7 +300,6 @@ def generate( output_path: Path = output_path, ) -> tuple[nx.DiGraph, set[str]]: """Generate a Delwaq model from a Ribasim model and results.""" - # Read in model and results model = ribasim.Model.read(toml_path) results_folder = toml_path.parent / model.results_dir diff --git a/python/ribasim/ribasim/geometry/edge.py b/python/ribasim/ribasim/geometry/edge.py index 9142c6817..dc8f6e202 100644 --- a/python/ribasim/ribasim/geometry/edge.py +++ b/python/ribasim/ribasim/geometry/edge.py @@ -77,8 +77,10 @@ def add( edge_id: Optional[NonNegativeInt] = None, **kwargs, ): - """Add an edge between nodes. The type of the edge (flow or control) - is automatically inferred from the type of the `from_node`. + """ + Add an edge between nodes. + + The type of the edge (flow or control) is automatically inferred from the type of the `from_node`. Parameters ---------- @@ -185,7 +187,6 @@ def plot(self, **kwargs) -> Axes: **kwargs : Dict Supported: 'ax', 'color_flow', 'color_control' """ - assert self.df is not None kwargs = kwargs.copy() # Avoid side-effects ax = kwargs.get("ax", None) diff --git a/python/ribasim/ribasim/model.py b/python/ribasim/ribasim/model.py index d7274a67c..39d16cb39 100644 --- a/python/ribasim/ribasim/model.py +++ b/python/ribasim/ribasim/model.py @@ -300,7 +300,6 @@ def write(self, filepath: str | PathLike[str]) -> Path: filepath : str | PathLike[str] A file path with .toml extension. """ - if self.use_validation: self._validate_model() @@ -351,7 +350,6 @@ def _has_valid_neighbor_amount( nodes, ) -> bool: """Check if the neighbor amount of the two nodes connected by the given edge meet the minimum requirements.""" - is_valid = True # filter graph by edge type @@ -419,7 +417,6 @@ def _add_source_sink_node( Specify that their occurrence in from_node table or to_node table is 0. """ - # loop over nodes, add the one that is not the downstream (from) or upstream (to) of any other nodes for index, node in enumerate(nodes): if nodes.index[index] not in node_info[f"{direction}_node_id"].to_numpy(): @@ -463,7 +460,6 @@ def _reset_contextvar(self) -> "Model": def plot_control_listen(self, ax): """Plot the implicit listen edges of the model.""" - df_listen_edge = pd.DataFrame( data={ "control_node_id": pd.Series([], dtype="int32[pyarrow]"), @@ -598,7 +594,6 @@ def to_xugrid(self, add_flow: bool = False, add_allocation: bool = False): add_allocation : bool add allocation results (Optional, defaults to False) """ - if add_flow and add_allocation: raise ValueError("Cannot add both allocation and flow results.") diff --git a/python/ribasim/ribasim/utils.py b/python/ribasim/ribasim/utils.py index 42fd638b1..c8ed18e29 100644 --- a/python/ribasim/ribasim/utils.py +++ b/python/ribasim/ribasim/utils.py @@ -32,6 +32,7 @@ def __getattr__( def _node_lookup_numpy(node_id) -> Series[Int32]: """Create a lookup table from from node_id to the node dimension index. + Used when adding data onto the nodes of an xugrid dataset. """ return pd.Series( @@ -43,6 +44,7 @@ def _node_lookup_numpy(node_id) -> Series[Int32]: def _node_lookup(uds) -> Series[Int32]: """Create a lookup table from from node_id to the node dimension index. + Used when adding data onto the nodes of an xugrid dataset. """ return pd.Series( @@ -57,7 +59,6 @@ def _edge_lookup(uds) -> Series[Int32]: Used when adding data onto the edges of an xugrid dataset. """ - return pd.Series( index=uds["edge_id"], data=uds[uds.grid.edge_dimension], diff --git a/python/ribasim_api/tests/test_bmi.py b/python/ribasim_api/tests/test_bmi.py index f11383721..a8c25b186 100644 --- a/python/ribasim_api/tests/test_bmi.py +++ b/python/ribasim_api/tests/test_bmi.py @@ -175,8 +175,9 @@ def test_get_value_ptr_allocation(libribasim, user_demand, tmp_path): def test_err_unknown_var(libribasim, basic, tmp_path): """ - Unknown or invalid variable address should trigger Python Exception, - print the kernel error, and not crash the library + Unknown or invalid variable address. + + Should trigger Python Exception, print the kernel error, and not crash the library. """ basic.write(tmp_path / "ribasim.toml") config_file = str(tmp_path / "ribasim.toml") diff --git a/python/ribasim_testmodels/ribasim_testmodels/allocation.py b/python/ribasim_testmodels/ribasim_testmodels/allocation.py index e51fbbe40..9ef4c0be9 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/allocation.py +++ b/python/ribasim_testmodels/ribasim_testmodels/allocation.py @@ -22,7 +22,6 @@ def user_demand_model() -> Model: """Create a UserDemand test model with static and dynamic UserDemand on the same basin.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -90,9 +89,9 @@ def user_demand_model() -> Model: def subnetwork_model() -> Model: """Create a UserDemand testmodel representing a subnetwork. + This model is merged into main_network_with_subnetworks_model. """ - model = Model( starttime="2020-01-01", endtime="2020-04-01", @@ -175,9 +174,9 @@ def subnetwork_model() -> Model: def looped_subnetwork_model() -> Model: """Create a UserDemand testmodel representing a subnetwork containing a loop in the topology. + This model is merged into main_network_with_subnetworks_model. """ - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -304,7 +303,6 @@ def looped_subnetwork_model() -> Model: def minimal_subnetwork_model() -> Model: """Create a subnetwork that is minimal with non-trivial allocation.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -361,7 +359,6 @@ def minimal_subnetwork_model() -> Model: def allocation_example_model() -> Model: """Generate a model that is used as an example of allocation in the docs.""" - model = Model( starttime="2020-01-01", endtime="2020-01-20", @@ -424,7 +421,6 @@ def allocation_example_model() -> Model: def main_network_with_subnetworks_model() -> Model: """Generate a model which consists of a main network and multiple connected subnetworks.""" - model = Model( starttime="2020-01-01", endtime="2020-03-01", @@ -701,7 +697,6 @@ def main_network_with_subnetworks_model() -> Model: def subnetworks_with_sources_model() -> Model: """Generate a model with subnetworks which contain sources.""" - model = main_network_with_subnetworks_model() model.flow_boundary.add( @@ -721,7 +716,6 @@ def subnetworks_with_sources_model() -> Model: def level_demand_model() -> Model: """Small model with LevelDemand nodes.""" - model = Model( starttime="2020-01-01", endtime="2020-02-01", @@ -782,7 +776,6 @@ def level_demand_model() -> Model: def flow_demand_model() -> Model: """Small model with a FlowDemand.""" - model = Model( starttime="2020-01-01 00:00:00", endtime="2021-01-01 00:00:00", @@ -858,7 +851,6 @@ def flow_demand_model() -> Model: def linear_resistance_demand_model(): """Small model with a FlowDemand for a node with a max flow rate.""" - model = Model( starttime="2020-01-01 00:00:00", endtime="2021-01-01 00:00:00", @@ -893,11 +885,7 @@ def linear_resistance_demand_model(): def fair_distribution_model(): - """ - Small model with little restrictions within the graph to see the behavior of - allocation in that case. - """ - + """See the behavior of allocation with few restrictions within the graph.""" model = Model( starttime="2020-01-01 00:00:00", endtime="2020-01-07 00:00:00", diff --git a/python/ribasim_testmodels/ribasim_testmodels/backwater.py b/python/ribasim_testmodels/ribasim_testmodels/backwater.py index 81f6fa2a0..686a2ad16 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/backwater.py +++ b/python/ribasim_testmodels/ribasim_testmodels/backwater.py @@ -10,8 +10,7 @@ def backwater_model(): - """Backwater curve as an integration test for ManningResistance""" - + """Backwater curve as an integration test for ManningResistance.""" node_type = np.full(102, "ManningResistance") node_type[1::2] = "Basin" node_type[0] = "FlowBoundary" diff --git a/python/ribasim_testmodels/ribasim_testmodels/basic.py b/python/ribasim_testmodels/ribasim_testmodels/basic.py index 8618631de..f50dc714a 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/basic.py +++ b/python/ribasim_testmodels/ribasim_testmodels/basic.py @@ -213,8 +213,7 @@ def basic_arrow_model() -> ribasim.Model: def basic_transient_model() -> ribasim.Model: - """Update the basic model with transient forcing""" - + """Update the basic model with transient forcing.""" model = basic_model() time = pd.date_range(model.starttime, model.endtime) day_of_year = time.day_of_year.to_numpy() @@ -265,11 +264,11 @@ def basic_transient_model() -> ribasim.Model: def tabulated_rating_curve_model() -> ribasim.Model: """ Set up a model where the upstream Basin has two TabulatedRatingCurve attached. + They both flow to the same downstream Basin, but one has a static rating curve, and the other one a time-varying rating curve. Only the upstream Basin receives a (constant) precipitation. """ - # Setup a model: model = ribasim.Model( starttime="2020-01-01", diff --git a/python/ribasim_testmodels/ribasim_testmodels/bucket.py b/python/ribasim_testmodels/ribasim_testmodels/bucket.py index 8634e8b1d..804a83f88 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/bucket.py +++ b/python/ribasim_testmodels/ribasim_testmodels/bucket.py @@ -10,7 +10,6 @@ def bucket_model() -> ribasim.Model: """Bucket model with just a single basin at Deltares' headquarter.""" - model = ribasim.Model( starttime="2020-01-01", endtime="2021-01-01", @@ -38,7 +37,6 @@ def bucket_model() -> ribasim.Model: def leaky_bucket_model() -> ribasim.Model: """Bucket model with dynamic forcing with missings at Deltares' headquarter.""" - model = ribasim.Model( starttime="2020-01-01", endtime="2020-01-05", diff --git a/python/ribasim_testmodels/ribasim_testmodels/continuous_control.py b/python/ribasim_testmodels/ribasim_testmodels/continuous_control.py index 0da7fdca2..ba18c0d88 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/continuous_control.py +++ b/python/ribasim_testmodels/ribasim_testmodels/continuous_control.py @@ -14,7 +14,6 @@ def outlet_continuous_control_model() -> Model: """Set up a small model that distributes flow over 2 branches.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", diff --git a/python/ribasim_testmodels/ribasim_testmodels/discrete_control.py b/python/ribasim_testmodels/ribasim_testmodels/discrete_control.py index c325fbfb5..e28d62f33 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/discrete_control.py +++ b/python/ribasim_testmodels/ribasim_testmodels/discrete_control.py @@ -17,10 +17,10 @@ def pump_discrete_control_model() -> Model: """ - Set up a basic model with a pump controlled based on basin levels. + Set up a basic model with a Pump controlled based on Basin levels. + The LinearResistance is deactivated when the levels are almost equal. """ - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -119,8 +119,7 @@ def pump_discrete_control_model() -> Model: def flow_condition_model() -> Model: - """Set up a basic model that involves discrete control based on a flow condition""" - + """Set up a basic model that involves discrete control based on a flow condition.""" model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -184,7 +183,6 @@ def flow_condition_model() -> Model: def level_boundary_condition_model() -> Model: """Set up a small model with a condition on a level boundary.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -259,7 +257,6 @@ def tabulated_rating_curve_control_model() -> Model: node will effectively increase the crest level to prevent further drainage at some threshold level. """ - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -321,11 +318,7 @@ def tabulated_rating_curve_control_model() -> Model: def compound_variable_condition_model() -> Model: - """ - Set up a minimal model containing a condition on a compound variable - for discrete control. - """ - + """Model with a condition on a compound variable for DiscreteControl.""" model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -379,11 +372,10 @@ def compound_variable_condition_model() -> Model: def level_range_model() -> Model: """ - Set up a minimal model in which the level of a basin is kept within an acceptable range - around a setpoint while being affected by time-varying forcing. + Keep the level of a Basin within a range around a setpoint, under the influence of time-varying forcing. + This is done by bringing the level back to the setpoint once the level goes beyond this range. """ - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -472,11 +464,7 @@ def level_range_model() -> Model: def connector_node_flow_condition_model() -> Model: - """ - Set up a minimal model with discrete control with a condition on - the flow through a connector node. - """ - + """DiscreteControl with a condition on the flow through a connector node.""" model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -526,11 +514,7 @@ def connector_node_flow_condition_model() -> Model: def concentration_condition_model() -> Model: - """ - Set up a minimal model with discrete control based on a - concentration condition. - """ - + """DiscreteControl based on a concentration condition.""" model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -585,10 +569,9 @@ def concentration_condition_model() -> Model: def continuous_concentration_condition_model() -> Model: """ - Set up a minimal model with discrete control based on a - continuous (calculated) concentration condition. - In this case, we setup a salt concentration and mimic - the Dutch coast. + DiscreteControl based on a continuous (calculated) concentration condition. + + In this case, we setup a salt concentration and mimic the Dutch coast. dc / | @@ -598,7 +581,6 @@ def continuous_concentration_condition_model() -> Model: | term """ - model = Model( starttime="2020-01-01", endtime="2020-02-01", diff --git a/python/ribasim_testmodels/ribasim_testmodels/doc_example.py b/python/ribasim_testmodels/ribasim_testmodels/doc_example.py index b097d9cc2..1ed15519c 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/doc_example.py +++ b/python/ribasim_testmodels/ribasim_testmodels/doc_example.py @@ -11,8 +11,7 @@ def local_pidcontrolled_cascade_model(): - """Demonstrating model for the cascade polder project from our partner""" - + """Demonstrating model for the cascade polder project from our partner.""" model = Model(starttime="2020-01-01", endtime="2021-01-01", crs="EPSG:28992") # Set up basins diff --git a/python/ribasim_testmodels/ribasim_testmodels/equations.py b/python/ribasim_testmodels/ribasim_testmodels/equations.py index cb03ce7ee..87b3e284e 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/equations.py +++ b/python/ribasim_testmodels/ribasim_testmodels/equations.py @@ -19,7 +19,6 @@ def linear_resistance_model() -> Model: """Set up a minimal model which uses a linear_resistance node.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -50,7 +49,6 @@ def linear_resistance_model() -> Model: def rating_curve_model() -> Model: """Set up a minimal model which uses a tabulated_rating_curve node.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -89,7 +87,6 @@ def rating_curve_model() -> Model: def manning_resistance_model() -> Model: """Set up a minimal model which uses a manning_resistance node.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -123,7 +120,6 @@ def manning_resistance_model() -> Model: def misc_nodes_model() -> Model: """Set up a minimal model using flow_boundary and pump nodes.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -160,8 +156,7 @@ def misc_nodes_model() -> Model: def pid_control_equation_model() -> Model: - """Set up a model with pid control for an analytical solution test""" - + """Set up a model with pid control for an analytical solution test.""" model = Model( starttime="2020-01-01", endtime="2020-01-01 00:05:00", crs="EPSG:28992" ) diff --git a/python/ribasim_testmodels/ribasim_testmodels/invalid.py b/python/ribasim_testmodels/ribasim_testmodels/invalid.py index 995d30993..049562e6d 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/invalid.py +++ b/python/ribasim_testmodels/ribasim_testmodels/invalid.py @@ -19,7 +19,8 @@ def invalid_qh_model() -> Model: """ - Invalid TabulatedRatingCurve Q(h) table: + Invalid TabulatedRatingCurve Q(h) table. + - levels must be unique - flow_rate must start at 0 - flow_rate must not be decreasing @@ -113,7 +114,6 @@ def invalid_discrete_control_model() -> Model: def invalid_edge_types_model() -> Model: """Set up a minimal model with invalid edge types.""" - model = Model( starttime="2020-01-01", endtime="2020-12-01", @@ -147,7 +147,6 @@ def invalid_edge_types_model() -> Model: def invalid_unstable_model() -> Model: """Model with several extremely quickly emptying basins.""" - model = Model( starttime="2020-01-01", endtime="2021-01-01", @@ -174,7 +173,6 @@ def invalid_unstable_model() -> Model: def invalid_priorities_model() -> Model: """Model with allocation active but missing priority parameter(s).""" - model = Model( starttime="2020-01-01 00:00:00", endtime="2021-01-01 00:00:00", diff --git a/python/ribasim_testmodels/ribasim_testmodels/pid_control.py b/python/ribasim_testmodels/ribasim_testmodels/pid_control.py index 435d60e7a..fd395798f 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/pid_control.py +++ b/python/ribasim_testmodels/ribasim_testmodels/pid_control.py @@ -15,7 +15,6 @@ def pid_control_model() -> Model: """Set up a basic model with a PID controlled pump controlling a basin with abundant inflow.""" - model = Model( starttime="2020-01-01", endtime="2020-12-01", @@ -87,7 +86,6 @@ def pid_control_model() -> Model: def discrete_control_of_pid_control_model() -> Model: """Set up a basic model where a discrete control node sets the target level of a pid control node.""" - model = Model( starttime="2020-01-01", endtime="2020-12-01", diff --git a/python/ribasim_testmodels/ribasim_testmodels/time.py b/python/ribasim_testmodels/ribasim_testmodels/time.py index b77f46c2f..ef8b9063a 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/time.py +++ b/python/ribasim_testmodels/ribasim_testmodels/time.py @@ -7,8 +7,7 @@ def flow_boundary_time_model() -> Model: - """Set up a minimal model with time-varying flow boundary""" - + """Set up a minimal model with time-varying flow boundary.""" model = Model( starttime="2020-01-01", endtime="2021-01-01", diff --git a/python/ribasim_testmodels/ribasim_testmodels/trivial.py b/python/ribasim_testmodels/ribasim_testmodels/trivial.py index 42ef8650f..6380e27ea 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/trivial.py +++ b/python/ribasim_testmodels/ribasim_testmodels/trivial.py @@ -5,8 +5,7 @@ def trivial_model() -> Model: - """Trivial model with just a basin, tabulated rating curve and terminal node""" - + """Trivial model with just a basin, tabulated rating curve and terminal node.""" model = Model( starttime="2020-01-01", endtime="2021-01-01", diff --git a/python/ribasim_testmodels/ribasim_testmodels/two_basin.py b/python/ribasim_testmodels/ribasim_testmodels/two_basin.py index 9cedb312f..bbdab74e1 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/two_basin.py +++ b/python/ribasim_testmodels/ribasim_testmodels/two_basin.py @@ -18,7 +18,6 @@ def two_basin_model() -> Model: infiltrates in the left basin, and exfiltrates in the right basin. The right basin fills up and discharges over the rating curve. """ - model = Model(starttime="2020-01-01", endtime="2021-01-01", crs="EPSG:28992") model.flow_boundary.add( diff --git a/ribasim_qgis/core/nodes.py b/ribasim_qgis/core/nodes.py index 9a1859c77..0f6eb5e7e 100644 --- a/ribasim_qgis/core/nodes.py +++ b/ribasim_qgis/core/nodes.py @@ -1,5 +1,5 @@ """ -This module contains the classes to represent the Ribasim node layers. +Classes to represent the Ribasim node layers. The classes specify: @@ -93,8 +93,9 @@ def create( def new_layer(self, crs: QgsCoordinateReferenceSystem) -> QgsVectorLayer: """ - Separate creation of the instance with creating the layer, since the - layer might also come from an existing geopackage. + Separate creation of the instance with creating the layer. + + Needed since the layer might also come from an existing geopackage. """ layer = QgsVectorLayer(self.geometry_type(), self.input_type(), "memory") provider = layer.dataProvider() diff --git a/ribasim_qgis/core/topology.py b/ribasim_qgis/core/topology.py index 709aa6441..c03321b7a 100644 --- a/ribasim_qgis/core/topology.py +++ b/ribasim_qgis/core/topology.py @@ -97,17 +97,15 @@ def infer_edge_type(from_node_type: str) -> str: def set_edge_properties(node: QgsVectorLayer, edge: QgsVectorLayer) -> None: """ + Set edge properties based on the node and edge geometries. + Based on the location of the first and last vertex of every edge geometry, derive which nodes it connects. Sets values for: - - * from_node_type * from_node_id - * to_node_type * to_node_id * edge_type - """ node_xy, node_index, node_identifiers = collect_node_properties(node) edge_xy = collect_edge_coordinates(edge) diff --git a/ribasim_qgis/scripts/qgis_testrunner.py b/ribasim_qgis/scripts/qgis_testrunner.py index 726341abc..fb532d6f5 100644 --- a/ribasim_qgis/scripts/qgis_testrunner.py +++ b/ribasim_qgis/scripts/qgis_testrunner.py @@ -1,7 +1,6 @@ #!/usr/bin/env python """ -*************************************************************************** Launches a unit test inside QGIS and exit the application. Arguments: @@ -51,13 +50,19 @@ import sys import traceback +# Monkey patch QGIS Python console +from console.console_output import writeOut + +# Start as soon as the initializationCompleted signal is fired +from qgis.core import QgsApplication, QgsProject, QgsProjectBadLayerHandler +from qgis.PyQt.QtCore import QDir from qgis.utils import iface assert iface is not None def __get_test_function(test_module_name): - """Load the test module and return the test function""" + """Load the test module and return the test function.""" print(f"QGIS Test Runner - Trying to import {test_module_name}") try: test_module = importlib.import_module(test_module_name) @@ -82,20 +87,12 @@ def __get_test_function(test_module_name): return getattr(test_module, function_name, None) -# Start as soon as the initializationCompleted signal is fired -from qgis.core import QgsApplication, QgsProject, QgsProjectBadLayerHandler -from qgis.PyQt.QtCore import QDir - - class QgsProjectBadLayerDefaultHandler(QgsProjectBadLayerHandler): def handleBadLayers(self, layers, dom): + # Ignore bad layers pass -# Monkey patch QGIS Python console -from console.console_output import writeOut - - def _write(self, m): sys.stdout.write(m) diff --git a/ribasim_qgis/tests/ui/test_load_plugin.py b/ribasim_qgis/tests/ui/test_load_plugin.py index 325d7772e..dd138e441 100644 --- a/ribasim_qgis/tests/ui/test_load_plugin.py +++ b/ribasim_qgis/tests/ui/test_load_plugin.py @@ -15,7 +15,6 @@ def test_plugin_is_loaded(self): def test_plugin(self): """Triggers Ribasim button and checks that Dock is added.""" - # This checks the *actual* QGIS interface, not just a stub self.assertTrue(iface is not None, "QGIS interface not available") diff --git a/ribasim_qgis/widgets/dataset_widget.py b/ribasim_qgis/widgets/dataset_widget.py index f45f12132..079fad59f 100644 --- a/ribasim_qgis/widgets/dataset_widget.py +++ b/ribasim_qgis/widgets/dataset_widget.py @@ -1,8 +1,7 @@ """ -This widgets displays the available input layers in the GeoPackage. +A widget that displays the available input layers in the GeoPackage. -This widget also allows enabling or disabling individual elements for a -computation. +It also allows enabling or disabling individual elements for a computation. """ from __future__ import annotations @@ -73,14 +72,7 @@ def add_node_layer(self, element: Input) -> QTreeWidgetItem: return item def remove_geopackage_layers(self) -> None: - """ - Remove layers from: - - * The dataset tree widget - * The QGIS layer panel - * The geopackage - """ - + """Remove layers from the dataset tree widget, QGIS layer panel and the GeoPackage.""" # Collect the selected items selection = self.selectedItems() @@ -169,7 +161,7 @@ def __init__(self, parent: QWidget): @property def path(self) -> Path: - """Returns currently active path to Ribasim model (.toml)""" + """Returns currently active path to Ribasim model (.toml).""" return Path(self.dataset_line_edit.text()) def connect_nodes(self) -> None: @@ -240,7 +232,7 @@ def add_relationship(from_layer, to_layer_id, name, fk="node_id") -> None: from_layer.setEditorWidgetSetup(field_index, setup) def load_geopackage(self) -> None: - """Load the layers of a GeoPackage into the Layers Panel""" + """Load the layers of a GeoPackage into the Layers Panel.""" self.dataset_tree.clear() geo_path = get_database_path_from_model_file(self.path) nodes = load_nodes_from_geopackage(geo_path) @@ -364,12 +356,7 @@ def _open_model(self, path: str) -> None: self.dataset_tree.sortByColumn(0, Qt.SortOrder.AscendingOrder) def remove_geopackage_layer(self) -> None: - """ - Remove layers from: - * The dataset tree widget - * The QGIS layer panel - * The geopackage - """ + """Remove layers from the dataset tree widget, QGIS layer panel and the GeoPackage.""" self.dataset_tree.remove_geopackage_layers() def suppress_popup_changed(self): diff --git a/ribasim_qgis/widgets/ribasim_widget.py b/ribasim_qgis/widgets/ribasim_widget.py index 8af4689c4..77beeded3 100644 --- a/ribasim_qgis/widgets/ribasim_widget.py +++ b/ribasim_qgis/widgets/ribasim_widget.py @@ -1,5 +1,5 @@ """ -This module forms the high level DockWidget. +High level RibasimWidget. It ensures the underlying widgets can talk to each other. It also manages the connection to the QGIS Layers Panel, and ensures there is a group for the @@ -70,7 +70,7 @@ def edge_layer(self) -> QgsVectorLayer | None: @property def crs(self) -> QgsCoordinateReferenceSystem: - """Returns coordinate reference system of current mapview""" + """Returns coordinate reference system of current mapview.""" map_canvas = self.iface.mapCanvas() assert map_canvas is not None map_settings = map_canvas.mapSettings() @@ -110,9 +110,9 @@ def create_groups(self, name: str) -> None: self.create_subgroup(name, "Ribasim Input") def add_to_group(self, maplayer: Any, destination: str, on_top: bool): - """ - Try to add to a group; it might have been deleted. In that case, we add - as many groups as required. + """Try to add to a group. + + It might have been deleted. In that case, we add as many groups as required. """ group = self.groups[destination] try: @@ -138,7 +138,7 @@ def add_layer( labels: QgsAbstractVectorLayerLabeling | None = None, ) -> QgsMapLayer | None: """ - Add a layer to the Layers Panel + Add a layer to the Layers Panel. Parameters ---------- diff --git a/ruff.toml b/ruff.toml index ab710a111..608f4db18 100644 --- a/ruff.toml +++ b/ruff.toml @@ -6,14 +6,7 @@ target-version = "py39" # See https://docs.astral.sh/ruff/rules/ select = ["C4", "D2", "D3", "D4", "E", "F", "I", "NPY", "PD", "UP"] ignore = [ - "D202", - "D205", - "D206", - "D400", - "D404", - "E402", "E501", - "E703", "PD002", "PD901", ]