From 04079993476b98e85f5b7998e5448e32c3640588 Mon Sep 17 00:00:00 2001 From: Emily Soth Date: Thu, 15 May 2025 12:30:35 -0700 Subject: [PATCH] fix variable name conflicts and get tests passing --- src/natcap/invest/spec.py | 5 +++- src/natcap/invest/validation.py | 26 +++++++++---------- .../archive_extraction.py | 3 +-- .../duplicate_filepaths.py | 3 +-- .../nonspatial_files.py | 3 +-- tests/test_datastack_modules/raster.py | 3 +-- .../simple_parameters.py | 3 +-- .../ui_parameter_archive.py | 3 +-- tests/test_datastack_modules/vector.py | 3 +-- tests/test_model_specs.py | 5 ---- tests/test_spec.py | 1 - tests/test_ui_server.py | 3 ++- tests/test_usage_logging.py | 3 +-- tests/test_validation.py | 24 ++++------------- 14 files changed, 32 insertions(+), 56 deletions(-) diff --git a/src/natcap/invest/spec.py b/src/natcap/invest/spec.py index 3e5a10a65..6e95027a0 100644 --- a/src/natcap/invest/spec.py +++ b/src/natcap/invest/spec.py @@ -1321,6 +1321,9 @@ def build_model_spec(model_spec): for argkey, argspec in model_spec['args'].items()] outputs = [ build_output_spec(argkey, argspec) for argkey, argspec in model_spec['outputs'].items()] + different_projections_ok = False + if 'args_with_spatial_overlap' in model_spec: + different_projections_ok = model_spec['args_with_spatial_overlap'].get('different_projections_ok', False) return ModelSpec( model_id=model_spec['model_id'], model_title=model_spec['model_title'], @@ -1330,7 +1333,7 @@ def build_model_spec(model_spec): outputs=outputs, input_field_order=model_spec['ui_spec']['order'], validate_spatial_overlap=True, - different_projections_ok=model_spec['args_with_spatial_overlap'].get('different_projections_ok', False)) + different_projections_ok=different_projections_ok) def build_input_spec(argkey, arg): diff --git a/src/natcap/invest/validation.py b/src/natcap/invest/validation.py index 97cdef5ef..1b8544814 100644 --- a/src/natcap/invest/validation.py +++ b/src/natcap/invest/validation.py @@ -249,7 +249,7 @@ def _format_bbox_list(file_list, bbox_list): file_list, bbox_list)]) -def validate(args, spec): +def validate(args, model_spec): """Validate an args dict against a model spec. Validates an arguments dictionary according to the rules laid out in @@ -257,7 +257,7 @@ def validate(args, spec): Args: args (dict): The InVEST model args dict to validate. - spec (dict): The InVEST model spec dict to validate against. + model_spec (dict): The InVEST model spec dict to validate against. Returns: A list of tuples where the first element of the tuple is an iterable of @@ -272,9 +272,9 @@ def validate(args, spec): missing_keys = set() required_keys_with_no_value = set() expression_values = { - input_spec.id: args.get(input_spec.id, False) for input_spec in spec.inputs} + input_spec.id: args.get(input_spec.id, False) for input_spec in model_spec.inputs} keys_with_falsey_values = set() - for parameter_spec in spec.inputs: + for parameter_spec in model_spec.inputs: key = parameter_spec.id required = parameter_spec.required @@ -312,7 +312,7 @@ def validate(args, spec): # we don't need to try to validate them try: # Using deepcopy to make sure we don't modify the original spec - parameter_spec = copy.deepcopy(spec.get_input(key)) + parameter_spec = copy.deepcopy(model_spec.get_input(key)) except KeyError: LOGGER.debug(f'Provided key {key} does not exist in MODEL_SPEC') continue @@ -341,10 +341,10 @@ def validate(args, spec): validation_warnings.append(([key], get_message('UNEXPECTED_ERROR'))) # Phase 3: Check spatial overlap if applicable - if spec.validate_spatial_overlap: + if model_spec.validate_spatial_overlap: spatial_keys = set() - i in spec.inputs: - if isinstance(i, spec.SingleBandRasterInput) or isinstance(i, spec.VectorInput): + for i in model_spec.inputs: + if i.type in['raster', 'vector']: spatial_keys.add(i.id) # Only test for spatial overlap once all the sufficient spatial keys @@ -361,7 +361,7 @@ def validate(args, spec): checked_keys.append(key) spatial_overlap_error = check_spatial_overlap( - spatial_files, spec.different_projections_ok) + spatial_files, model_spec.different_projections_ok) if spatial_overlap_error: validation_warnings.append( (checked_keys, spatial_overlap_error)) @@ -459,12 +459,12 @@ def invest_validator(validate_func): return _wrapped_validate_func -def args_enabled(args, spec): +def args_enabled(args, model_spec): """Get enabled/disabled status of arg fields given their values and spec. Args: args (dict): Dict mapping arg keys to user-provided values - spec (dict): MODEL_SPEC dictionary + model_spec (dict): MODEL_SPEC dictionary Returns: Dictionary mapping each arg key to a boolean value - True if the @@ -472,8 +472,8 @@ def args_enabled(args, spec): """ enabled = {} expression_values = { - arg_spec.id: args.get(arg_spec.id, False) for arg_spec in spec.inputs} - for arg_spec in spec.inputs: + arg_spec.id: args.get(arg_spec.id, False) for arg_spec in model_spec.inputs} + for arg_spec in model_spec.inputs: if isinstance(arg_spec.allowed, str): enabled[arg_spec.id] = bool(_evaluate_expression( arg_spec.allowed, expression_values)) diff --git a/tests/test_datastack_modules/archive_extraction.py b/tests/test_datastack_modules/archive_extraction.py index ef97906ea..1308016ff 100644 --- a/tests/test_datastack_modules/archive_extraction.py +++ b/tests/test_datastack_modules/archive_extraction.py @@ -26,6 +26,5 @@ MODEL_SPEC = spec.ModelSpec(inputs=[ model_id='archive_extraction_model', model_title='', userguide='', - input_field_order=[], - args_with_spatial_overlap={} + input_field_order=[] ) diff --git a/tests/test_datastack_modules/duplicate_filepaths.py b/tests/test_datastack_modules/duplicate_filepaths.py index 7b5dac1c0..fda6aea64 100644 --- a/tests/test_datastack_modules/duplicate_filepaths.py +++ b/tests/test_datastack_modules/duplicate_filepaths.py @@ -9,6 +9,5 @@ MODEL_SPEC = spec.ModelSpec( model_id='duplicate_filepaths_model', model_title='', userguide='', - input_field_order=[], - args_with_spatial_overlap={} + input_field_order=[] ) diff --git a/tests/test_datastack_modules/nonspatial_files.py b/tests/test_datastack_modules/nonspatial_files.py index d9d002e76..00d79b333 100644 --- a/tests/test_datastack_modules/nonspatial_files.py +++ b/tests/test_datastack_modules/nonspatial_files.py @@ -9,6 +9,5 @@ MODEL_SPEC = spec.ModelSpec(inputs=[ model_id='nonspatial_model', model_title='', userguide='', - input_field_order=[], - args_with_spatial_overlap={} + input_field_order=[] ) diff --git a/tests/test_datastack_modules/raster.py b/tests/test_datastack_modules/raster.py index 4084ee0dd..74284994f 100644 --- a/tests/test_datastack_modules/raster.py +++ b/tests/test_datastack_modules/raster.py @@ -6,6 +6,5 @@ MODEL_SPEC = spec.ModelSpec(inputs=[ model_id='raster_model', model_title='', userguide='', - input_field_order=[], - args_with_spatial_overlap={} + input_field_order=[] ) diff --git a/tests/test_datastack_modules/simple_parameters.py b/tests/test_datastack_modules/simple_parameters.py index 6fb7f3828..54b80dee2 100644 --- a/tests/test_datastack_modules/simple_parameters.py +++ b/tests/test_datastack_modules/simple_parameters.py @@ -13,6 +13,5 @@ MODEL_SPEC = spec.ModelSpec(inputs=[ model_id='simple_model', model_title='', userguide='', - input_field_order=[], - args_with_spatial_overlap={} + input_field_order=[] ) diff --git a/tests/test_datastack_modules/ui_parameter_archive.py b/tests/test_datastack_modules/ui_parameter_archive.py index 13f62ba1d..2276bd1f8 100644 --- a/tests/test_datastack_modules/ui_parameter_archive.py +++ b/tests/test_datastack_modules/ui_parameter_archive.py @@ -7,6 +7,5 @@ MODEL_SPEC = SimpleNamespace(inputs=[ model_id='ui_parameters_model', model_title='', userguide='', - input_field_order=[], - args_with_spatial_overlap={} + input_field_order=[] ) diff --git a/tests/test_datastack_modules/vector.py b/tests/test_datastack_modules/vector.py index bc0d46ef5..9952d6da8 100644 --- a/tests/test_datastack_modules/vector.py +++ b/tests/test_datastack_modules/vector.py @@ -7,6 +7,5 @@ MODEL_SPEC = spec.ModelSpec(inputs=[ model_id='vector_model', model_title='', userguide='', - input_field_order=[], - args_with_spatial_overlap={} + input_field_order=[] ) diff --git a/tests/test_model_specs.py b/tests/test_model_specs.py index 7a9bfd987..19ec29400 100644 --- a/tests/test_model_specs.py +++ b/tests/test_model_specs.py @@ -132,11 +132,6 @@ class ValidateModelSpecs(unittest.TestCase): ("Required key(s) missing from MODEL_SPEC: " f"{set(required_keys).difference(set(dir(model.MODEL_SPEC)))}")) - if model.MODEL_SPEC.args_with_spatial_overlap: - self.assertTrue( - set(model.MODEL_SPEC.args_with_spatial_overlap).issubset( - {'spatial_keys', 'different_projections_ok'})) - self.assertIsInstance(model.MODEL_SPEC.input_field_order, list) found_keys = set() for group in model.MODEL_SPEC.input_field_order: diff --git a/tests/test_spec.py b/tests/test_spec.py index 956eb53b8..efac9d60a 100644 --- a/tests/test_spec.py +++ b/tests/test_spec.py @@ -362,7 +362,6 @@ class TestMetadataFromSpec(unittest.TestCase): aliases=[], input_field_order=[], inputs={}, - args_with_spatial_overlap={}, outputs=output_spec ) ) diff --git a/tests/test_ui_server.py b/tests/test_ui_server.py index 4a19619a3..ddf81a5ec 100644 --- a/tests/test_ui_server.py +++ b/tests/test_ui_server.py @@ -45,7 +45,8 @@ class EndpointFunctionTests(unittest.TestCase): self.assertEqual( set(spec), {'model_id', 'model_title', 'userguide', 'aliases', - 'input_field_order', 'args_with_spatial_overlap', 'args', 'outputs'}) + 'input_field_order', 'different_projections_ok', + 'validate_spatial_overlap', 'args', 'outputs'}) def test_get_invest_validate(self): """UI server: get_invest_validate endpoint.""" diff --git a/tests/test_usage_logging.py b/tests/test_usage_logging.py index 84fcc5e89..4159f1a93 100644 --- a/tests/test_usage_logging.py +++ b/tests/test_usage_logging.py @@ -75,8 +75,7 @@ class UsageLoggingTests(unittest.TestCase): spec.VectorInput(id='blank_vector_path', geometry_types={}, fields={}) ], outputs={}, - input_field_order=[], - args_with_spatial_overlap=None) + input_field_order=[]) output_logfile = os.path.join(self.workspace_dir, 'logfile.txt') with utils.log_to_file(output_logfile): diff --git a/tests/test_validation.py b/tests/test_validation.py index fb84fc4be..ae7b68c02 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -40,12 +40,10 @@ from natcap.invest.spec import ( gdal.UseExceptions() def model_spec_with_defaults(model_id='', model_title='', userguide='', aliases=None, - inputs={}, outputs={}, input_field_order=[], - args_with_spatial_overlap=[]): + inputs={}, outputs={}, input_field_order=[]): return ModelSpec(model_id=model_id, model_title=model_title, userguide=userguide, aliases=aliases, inputs=inputs, outputs=outputs, - input_field_order=input_field_order, - args_with_spatial_overlap=args_with_spatial_overlap) + input_field_order=input_field_order) def number_input_spec_with_defaults(id='', units=u.none, expression='', **kwargs): return NumberInput(id=id, units=units, expression=expression, **kwargs) @@ -2050,11 +2048,7 @@ class TestValidationFromSpec(unittest.TestCase): fields={}, geometry_types={'POINT'} ) - ], - args_with_spatial_overlap={ - 'spatial_keys': ['raster_a', 'raster_b', 'vector_a'], - 'different_projections_ok': True - } + ] ) driver = gdal.GetDriverByName('GTiff') @@ -2117,11 +2111,7 @@ class TestValidationFromSpec(unittest.TestCase): data_type=float, units=u.none ) - ], - args_with_spatial_overlap={ - 'spatial_keys': ['raster_a', 'raster_b'], - 'different_projections_ok': True - } + ] ) driver = gdal.GetDriverByName('GTiff') @@ -2170,11 +2160,7 @@ class TestValidationFromSpec(unittest.TestCase): fields=[], geometry_types={'POINT'} ) - ], - args_with_spatial_overlap={ - 'spatial_keys': ['raster_a', 'raster_b', 'vector_a'], - 'different_projections_ok': True - } + ] ) driver = gdal.GetDriverByName('GTiff')