From b5152edc68f27be291f22b283cf01d3add991af7 Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Tue, 1 Aug 2023 10:03:02 -0300 Subject: [PATCH] fix .format calls --- cchecker.py | 8 +- compliance_checker/acdd.py | 4 +- compliance_checker/base.py | 5 +- compliance_checker/cf/cf_1_6.py | 102 ++++-------------- compliance_checker/cf/cf_1_7.py | 52 ++------- compliance_checker/cf/cf_base.py | 43 ++------ compliance_checker/cf/util.py | 9 +- compliance_checker/ioos.py | 39 ++----- compliance_checker/runner.py | 12 +-- compliance_checker/suite.py | 6 +- compliance_checker/tests/test_cf.py | 6 +- .../tests/test_cf_integration.py | 32 ++---- .../tests/test_feature_detection.py | 8 +- 13 files changed, 76 insertions(+), 250 deletions(-) diff --git a/cchecker.py b/cchecker.py index 90329cdf..72d022df 100755 --- a/cchecker.py +++ b/cchecker.py @@ -293,9 +293,7 @@ def main(): if output_len == 1: if args.format != "json": print( - "Running Compliance Checker on the datasets from: {}".format( - args.dataset_location, - ), + f"Running Compliance Checker on the datasets from: {args.dataset_location}", file=sys.stderr, ) return_value, errors = ComplianceChecker.run_checker( @@ -315,9 +313,7 @@ def main(): for output, dataset in zip(args.output, args.dataset_location): if args.format != "json": print( - "Running Compliance Checker on the dataset from: {}".format( - dataset, - ), + f"Running Compliance Checker on the dataset from: {dataset}", file=sys.stderr, ) return_value, errors = ComplianceChecker.run_checker( diff --git a/compliance_checker/acdd.py b/compliance_checker/acdd.py index 6502f45d..6ea610ac 100644 --- a/compliance_checker/acdd.py +++ b/compliance_checker/acdd.py @@ -676,9 +676,7 @@ def verify_convention_version(self, ds): return ratable_result((1, 2), "Global Attributes", m) except AttributeError: # NetCDF attribute not found m = [ - "No Conventions attribute present; must contain ACDD-{}".format( - self._cc_spec_version, - ), + f"No Conventions attribute present; must contain ACDD-{self._cc_spec_version}", ] # Result will have name "Global Attributes" to group with globals return ratable_result((0, 2), "Global Attributes", m) diff --git a/compliance_checker/base.py b/compliance_checker/base.py index 347bee7d..c2674e85 100644 --- a/compliance_checker/base.py +++ b/compliance_checker/base.py @@ -480,10 +480,7 @@ def attr_check(kvp, ds, priority, ret_val, gname=None, var_name=None): msgs.append(f"{display_name} not present") elif res == 1: msgs.append( - "{} present, but not in expected value list ({})".format( - display_name, - sorted(other), - ), + f"{display_name} present, but not in expected value list ({sorted(other)})", ) ret_val.append( diff --git a/compliance_checker/cf/cf_1_6.py b/compliance_checker/cf/cf_1_6.py index 04ec8962..2cc5a74d 100644 --- a/compliance_checker/cf/cf_1_6.py +++ b/compliance_checker/cf/cf_1_6.py @@ -88,10 +88,7 @@ def check_data_types(self, ds): and v.dtype.type not in self._allowed_numeric_var_types ): fails.append( - "The variable {} failed because the datatype is {}".format( - k, - v.datatype, - ), + f"The variable {k} failed because the datatype is {v.datatype}", ) return Result( BaseCheck.HIGH, @@ -423,9 +420,7 @@ def check_fill_value_equal_missing_value(self, ds): total = total + 1 if variable._FillValue != variable.missing_value: fails.append( - "For the variable {} the missing_value must be equal to the _FillValue".format( - variable.name, - ), + f"For the variable {variable.name} the missing_value must be equal to the _FillValue", ) return Result( @@ -496,10 +491,7 @@ def check_fill_value_outside_valid_range(self, ds): m = "§2.5.1 Fill Values should be outside the range specified by valid_range" # subsection message valid_fill_range.assert_true( False, - "{};\n\t{}:valid_range must be a numeric type not a string".format( - m, - name, - ), + f"{m};\n\t{name}:valid_range must be a numeric type not a string", ) continue rmin, rmax = variable.valid_range @@ -720,10 +712,7 @@ def check_units(self, ds): # side effects, but better than teasing out the individual result if units is not None and units_attr_is_string.assert_true( isinstance(units, str), - "units ({}) attribute of '{}' must be a string compatible with UDUNITS".format( - units, - variable.name, - ), + f"units ({units}) attribute of '{variable.name}' must be a string compatible with UDUNITS", ): valid_udunits = self._check_valid_udunits(ds, name) ret_val.append(valid_udunits) @@ -808,9 +797,7 @@ def _check_valid_cf_units(self, ds, variable_name): # 1) Units must exist valid_units.assert_true( should_be_dimensionless or units is not None, - "units attribute is required for {} when variable is not a dimensionless quantity".format( - variable_name, - ), + f"units attribute is required for {variable_name} when variable is not a dimensionless quantity", ) # Don't bother checking the rest @@ -875,10 +862,7 @@ def _check_valid_udunits(self, ds, variable_name): are_udunits = units is not None and util.units_known(units) valid_udunits.assert_true( should_be_dimensionless or are_udunits or units is None, - 'units for {}, "{}" are not recognized by UDUNITS'.format( - variable_name, - units, - ), + f'units for {variable_name}, "{units}" are not recognized by UDUNITS', ) return valid_udunits.to_result() @@ -1039,9 +1023,7 @@ def check_standard_name(self, ds): valid_std_name = TestCtx(BaseCheck.HIGH, self.section_titles["3.3"]) valid_std_name.assert_true( isinstance(standard_name, str), - "Attribute standard_name for variable {} must be a string".format( - name, - ), + f"Attribute standard_name for variable {name} must be a string", ) valid_std_name.out_of += 1 if standard_name not in self._std_names: @@ -1080,9 +1062,7 @@ def check_standard_name(self, ds): # IMPLEMENTATION CONFORMANCE 3 RECOMMENDED long_or_std_name.assert_true( long_name_present or standard_name_present, - "Attribute long_name or/and standard_name is highly recommended for variable {}".format( - name, - ), + f"Attribute long_name or/and standard_name is highly recommended for variable {name}", ) ret_val.append(long_or_std_name.to_result()) return ret_val @@ -1209,9 +1189,7 @@ def check_flags(self, ds): allvr = Result(BaseCheck.MEDIUM, allv, self.section_titles["3.5"]) if not allvr.value: allvr.msgs = [ - "flag masks and flag values for '{}' combined don't equal flag values".format( - name, - ), + f"flag masks and flag values for '{name}' combined don't equal flag values", ] ret_val.append(allvr) @@ -1367,9 +1345,7 @@ def _check_flag_meanings(self, ds, name): if flag_regx.match(meaning) is None: valid_meanings.assert_true( False, - "{}'s flag_meanings attribute defined an illegal flag meaning ".format( - name, - ) + f"{name}'s flag_meanings attribute defined an illegal flag meaning " + f"{meaning}", ) return valid_meanings.to_result() @@ -2761,10 +2737,7 @@ def check_cell_boundaries(self, ds): if boundary_variable_name not in ds.variables: valid = False reasoning.append( - "Boundary variable {} referenced by {} not ".format( - boundary_variable_name, - variable.name, - ) + f"Boundary variable {boundary_variable_name} referenced by {variable.name} not " + "found in dataset variables", ) else: @@ -2774,10 +2747,7 @@ def check_cell_boundaries(self, ds): if boundary_variable.ndim < 2: valid = False reasoning.append( - "Boundary variable {} specified by {}".format( - boundary_variable.name, - variable.name, - ) + f"Boundary variable {boundary_variable.name} specified by {variable.name}" + " should have at least two dimensions to enclose the base " + "case of a one dimensionsal variable", ) @@ -3073,10 +3043,7 @@ def _check_cell_methods_paren_info(self, paren_contents, var): # attempt to get the number for the interval if not interval_matches: valid_info.messages.append( - '§7.3.3 {}:cell_methods contains an interval specification that does not parse: "{}". Should be in format "interval: "'.format( - var.name, - val, - ), + f'§7.3.3 {var.name}:cell_methods contains an interval specification that does not parse: "{val}". Should be in format "interval: "', ) else: try: @@ -3111,17 +3078,13 @@ def _check_cell_methods_paren_info(self, paren_contents, var): valid_info.out_of += 1 if len(pmatches) == 1: valid_info.messages.append( - "§7.3.3 If there is no standardized information, the keyword comment: should be omitted for variable {}".format( - var.name, - ), + f"§7.3.3 If there is no standardized information, the keyword comment: should be omitted for variable {var.name}", ) # otherwise check that the comment is the last # item in the parentheses elif i != len(pmatches) - 1: valid_info.messages.append( - '§7.3.3 The non-standard "comment:" element must come after any standard elements in cell_methods for variable {}'.format( - var.name, - ), + f'§7.3.3 The non-standard "comment:" element must come after any standard elements in cell_methods for variable {var.name}', ) # else: @@ -3129,20 +3092,14 @@ def _check_cell_methods_paren_info(self, paren_contents, var): else: valid_info.out_of += 1 valid_info.messages.append( - '§7.3.3 Invalid cell_methods keyword "{}" for variable {}. Must be one of [interval, comment]'.format( - keyword, - var.name, - ), + f'§7.3.3 Invalid cell_methods keyword "{keyword}" for variable {var.name}. Must be one of [interval, comment]', ) # Ensure concatenated reconstructed matches are the same as the # original string. If they're not, there's likely a formatting error valid_info.assert_true( "".join(m.group(0) for m in pmatches) == paren_contents, - "§7.3.3 Parenthetical content inside {}:cell_methods is not well formed: {}".format( - var.name, - paren_contents, - ), + f"§7.3.3 Parenthetical content inside {var.name}:cell_methods is not well formed: {paren_contents}", ) return valid_info @@ -3281,9 +3238,7 @@ def check_climatological_statistics(self, ds): ): total_climate_count += 1 reasoning.append( - "Climatology variable coordinates are in improper order: {}. Bounds-specific dimensions should be last".format( - ds.variables[clim_coord_var.climatology].dimensions, - ), + f"Climatology variable coordinates are in improper order: {ds.variables[clim_coord_var.climatology].dimensions}. Bounds-specific dimensions should be last", ) result = Result( BaseCheck.MEDIUM, @@ -3302,9 +3257,7 @@ def check_climatological_statistics(self, ds): != 2 ): reasoning.append( - 'Climatology dimension "{}" should only contain two elements'.format( - ds.variables[clim_coord_var.climatology].name, - ), + f'Climatology dimension "{ds.variables[clim_coord_var.climatology].name}" should only contain two elements', ) total_climate_count += 1 result = Result( @@ -3346,9 +3299,7 @@ def check_climatological_statistics(self, ds): total_climate_count += 1 if not regex.search(re_string, cell_method_var.cell_methods): reasoning.append( - 'The "time: method within years/days over years/days" format is not correct in variable {}.'.format( - cell_method_var.name, - ), + f'The "time: method within years/days over years/days" format is not correct in variable {cell_method_var.name}.', ) else: valid_climate_count += 1 @@ -3536,9 +3487,7 @@ def check_compression_gathering(self, ds): if compress_var.ndim != 1: valid = False reasoning.append( - "Compression variable {} may only have one dimension".format( - compress_var.name, - ), + f"Compression variable {compress_var.name} may only have one dimension", ) # IMPLEMENTATION CONFORMANCE 8.2 REQUIRED 1/3 # ensure compression variable is a proper index, and thus is an @@ -3548,9 +3497,7 @@ def check_compression_gathering(self, ds): ): valid = False reasoning.append( - "Compression variable {} must be an integer type to form a proper array index".format( - compress_var.name, - ), + f"Compression variable {compress_var.name} must be an integer type to form a proper array index", ) # IMPLEMENTATION CONFORMANCE 8.2 REQUIRED 2/3 # make sure all the variables referred to are contained by the @@ -3559,10 +3506,7 @@ def check_compression_gathering(self, ds): not_in_dims = sorted(compress_set.difference(ds.dimensions)) valid = False reasoning.append( - "The following dimensions referenced by the compress attribute of variable {} do not exist: {}".format( - compress_var.name, - not_in_dims, - ), + f"The following dimensions referenced by the compress attribute of variable {compress_var.name} do not exist: {not_in_dims}", ) # IMPLEMENTATION CONFORMANCE 8.2 REQUIRED 3/3 # The values of the associated coordinate variable must be in the range diff --git a/compliance_checker/cf/cf_1_7.py b/compliance_checker/cf/cf_1_7.py index 1ff97520..14d6430c 100644 --- a/compliance_checker/cf/cf_1_7.py +++ b/compliance_checker/cf/cf_1_7.py @@ -167,9 +167,7 @@ def check_actual_range(self, ds): variable[:].min(), ) or not np.isclose(variable.actual_range[1], variable[:].max()): msgs.append( - "actual_range elements of '{}' inconsistent with its min/max values".format( - name, - ), + f"actual_range elements of '{name}' inconsistent with its min/max values", ) else: score += 1 @@ -181,9 +179,7 @@ def check_actual_range(self, ds): variable.actual_range[1] > variable.valid_range[1] ): msgs.append( - '"{}"\'s actual_range must be within valid_range'.format( - name, - ), + f'"{name}"\'s actual_range must be within valid_range', ) else: score += 1 @@ -194,10 +190,7 @@ def check_actual_range(self, ds): out_of += 1 if variable.actual_range[0] < variable.valid_min: msgs.append( - '"{}"\'s actual_range first element must be >= valid_min ({})'.format( - name, - variable.valid_min, - ), + f'"{name}"\'s actual_range first element must be >= valid_min ({variable.valid_min})', ) else: score += 1 @@ -205,10 +198,7 @@ def check_actual_range(self, ds): out_of += 1 if variable.actual_range[1] > variable.valid_max: msgs.append( - '"{}"\'s actual_range second element must be <= valid_max ({})'.format( - name, - variable.valid_max, - ), + f'"{name}"\'s actual_range second element must be <= valid_max ({variable.valid_max})', ) else: score += 1 @@ -254,10 +244,7 @@ def check_cell_boundaries(self, ds): if boundary_variable_name not in ds.variables: valid = False reasoning.append( - "Boundary variable {} referenced by {} not ".format( - boundary_variable_name, - variable.name, - ) + f"Boundary variable {boundary_variable_name} referenced by {variable.name} not " + "found in dataset variables", ) else: @@ -269,10 +256,7 @@ def check_cell_boundaries(self, ds): if boundary_variable.ndim < 2: valid = False reasoning.append( - "Boundary variable {} specified by {}".format( - boundary_variable.name, - variable.name, - ) + f"Boundary variable {boundary_variable.name} specified by {variable.name}" + " should have at least two dimensions to enclose the base " + "case of a one dimensionsal variable", ) @@ -318,10 +302,7 @@ def check_cell_boundaries(self, ds): if boundary_variable.dtype.kind not in "biufc": valid = False reasoning.append( - "Boundary variable {} specified by {}".format( - boundary_variable.name, - variable.name, - ) + f"Boundary variable {boundary_variable.name} specified by {variable.name}" + "must be a numeric data type ", ) @@ -352,10 +333,7 @@ def check_cell_boundaries(self, ds): if not hasattr(boundary_variable, "formula_terms"): valid = False reasoning.append( - "'{}' has 'formula_terms' attr, bounds variable '{}' must also have 'formula_terms'".format( - variable_name, - boundary_variable_name, - ), + f"'{variable_name}' has 'formula_terms' attr, bounds variable '{boundary_variable_name}' must also have 'formula_terms'", ) # 7.1 Recommendations 2/2 @@ -380,10 +358,7 @@ def check_cell_boundaries(self, ds): if unwanted_attributes: valid = False reasoning.append( - "The Boundary variables '{}' should not have the attributes: '{}'".format( - boundary_variable_name, - unwanted_attributes, - ), + f"The Boundary variables '{boundary_variable_name}' should not have the attributes: '{unwanted_attributes}'", ) result = Result( @@ -818,9 +793,7 @@ def check_grid_mapping(self, ds): pyproj.CRS.from_wkt(crs_wkt) except pyproj.exceptions.CRSError as crs_error: test_ctx.messages.append( - "Cannot parse crs_wkt attribute to CRS using Proj4. Proj4 error: {}".format( - str(crs_error), - ), + f"Cannot parse crs_wkt attribute to CRS using Proj4. Proj4 error: {str(crs_error)}", ) else: test_ctx.score += 1 @@ -943,10 +916,7 @@ def _check_dimensionless_vertical_coordinate_1_7( _comp_std_name = dim_vert_coords_dict[standard_name][1] correct_computed_std_name_ctx.assert_true( getattr(variable, "computed_standard_name", None) in _comp_std_name, - "§4.3.3 The standard_name of `{}` must map to the correct computed_standard_name, `{}`".format( - vname, - sorted(_comp_std_name), - ), + f"§4.3.3 The standard_name of `{vname}` must map to the correct computed_standard_name, `{sorted(_comp_std_name)}`", ) ret_val.append(correct_computed_std_name_ctx.to_result()) diff --git a/compliance_checker/cf/cf_base.py b/compliance_checker/cf/cf_base.py index 2e420c81..422815cf 100644 --- a/compliance_checker/cf/cf_base.py +++ b/compliance_checker/cf/cf_base.py @@ -206,26 +206,19 @@ def check_grid_mapping(self, ds): for grid_var_name, coord_var_str in re_all: defines_grid_mapping.assert_true( grid_var_name in ds.variables, - "grid mapping variable {} must exist in this dataset".format( - grid_var_name, - ), + f"grid mapping variable {grid_var_name} must exist in this dataset", ) for ref_var in coord_var_str.split(): defines_grid_mapping.assert_true( ref_var in ds.variables, - "Coordinate-related variable {} referenced by grid_mapping variable {} must exist in this dataset".format( - ref_var, - grid_var_name, - ), + f"Coordinate-related variable {ref_var} referenced by grid_mapping variable {grid_var_name} must exist in this dataset", ) else: for grid_var_name in grid_mapping.split(): defines_grid_mapping.assert_true( grid_var_name in ds.variables, - "grid mapping variable {} must exist in this dataset".format( - grid_var_name, - ), + f"grid mapping variable {grid_var_name} must exist in this dataset", ) ret_val[variable.name] = defines_grid_mapping.to_result() @@ -264,10 +257,7 @@ def check_grid_mapping(self, ds): for req in required_attrs: valid_grid_mapping.assert_true( hasattr(grid_var, req), - "{} is a required attribute for grid mapping {}".format( - req, - grid_mapping_name, - ), + f"{req} is a required attribute for grid mapping {grid_mapping_name}", ) # Make sure that exactly one of the exclusive attributes exist @@ -313,10 +303,7 @@ def check_conventions_version(self, ds): valid = False reasoning = [] - correct_version_string = "{}-{}".format( - self._cc_spec, - self._cc_spec_version, - ).upper() + correct_version_string = f"{self._cc_spec}-{self._cc_spec_version}".upper() if hasattr(ds, "Conventions"): conventions = regex.split(r",|\s+", getattr(ds, "Conventions", "")) for convention in conventions: @@ -682,10 +669,7 @@ def _find_cf_standard_name_table(self, ds): ) else: print( - "Using cached standard name table v{} from {}".format( - version, - location, - ), + f"Using cached standard name table v{version} from {location}", file=sys.stderr, ) @@ -1056,16 +1040,14 @@ def _att_loc_msg(att_loc): if att_loc_len == 1: valid_loc = att_loc_print_helper(loc_sort[0]) elif att_loc_len == 2: - valid_loc = "{} and {}".format( - att_loc_print_helper(loc_sort[0]), - att_loc_print_helper(loc_sort[1]), - ) + valid_loc = f"{att_loc_print_helper(loc_sort[0])} and {att_loc_print_helper(loc_sort[1])}" # shouldn't be reached under normal circumstances, as any attribute # should be either G, C, or D but if another # category is added, this will be useful. else: - valid_loc = ", ".join(loc_sort[:-1]) + ", and {}".format( - att_loc_print_helper(loc_sort[-1]), + valid_loc = ( + ", ".join(loc_sort[:-1]) + + f", and {att_loc_print_helper(loc_sort[-1])}" ) return f"This attribute may only appear in {valid_loc}." @@ -1188,10 +1170,7 @@ def _check_attr_type(self, attr_name, attr_type, attribute, variable=None): if temp_ctx.messages: return ( False, - "{} must be numeric and must be equivalent to {} dtype".format( - attr_name, - var_dtype, - ), + f"{attr_name} must be numeric and must be equivalent to {var_dtype} dtype", ) else: # If we reached here, we fell off with an unrecognized type diff --git a/compliance_checker/cf/util.py b/compliance_checker/cf/util.py index d57f7d86..fa87357e 100644 --- a/compliance_checker/cf/util.py +++ b/compliance_checker/cf/util.py @@ -292,18 +292,13 @@ def download_cf_standard_name_table(version, location=None): if version == "latest": url = "http://cfconventions.org/Data/cf-standard-names/current/src/cf-standard-name-table.xml" else: - url = "http://cfconventions.org/Data/cf-standard-names/{}/src/cf-standard-name-table.xml".format( - version, - ) + url = f"http://cfconventions.org/Data/cf-standard-names/{version}/src/cf-standard-name-table.xml" r = requests.get(url, allow_redirects=True) r.raise_for_status() print( - "Downloading cf-standard-names table version {} from: {}".format( - version, - url, - ), + f"Downloading cf-standard-names table version {version} from: {url}", file=sys.stderr, ) with open(location, "wb") as f: diff --git a/compliance_checker/ioos.py b/compliance_checker/ioos.py index fe7dbbfd..3264843e 100644 --- a/compliance_checker/ioos.py +++ b/compliance_checker/ioos.py @@ -46,10 +46,7 @@ def _has_attr(cls, ds, attr, concept_name, priority=BaseCheck.HIGH): if not val: msgs.append( - "Attr '{}' (IOOS concept: '{}') not found in dataset".format( - attr, - concept_name, - ), + f"Attr '{attr}' (IOOS concept: '{concept_name}') not found in dataset", ) return Result(priority, val, concept_name, msgs) @@ -64,22 +61,14 @@ def _has_var_attr(cls, dataset, vname, attr, concept_name, priority=BaseCheck.HI if vname not in dataset.variables: val = False msgs.append( - "Variable '{}' not present while checking for attr '{}' for IOOS concept: '{}'".format( - vname, - attr, - concept_name, - ), + f"Variable '{vname}' not present while checking for attr '{attr}' for IOOS concept: '{concept_name}'", ) else: v = dataset.variables[vname] if attr not in v.ncattrs(): val = False msgs.append( - "Attr '{}' not present on var '{}' while checking for IOOS concept: '{}'".format( - attr, - vname, - concept_name, - ), + f"Attr '{attr}' not present on var '{vname}' while checking for IOOS concept: '{concept_name}'", ) return Result(priority, val, concept_name, msgs) @@ -796,9 +785,7 @@ def check_contributor_role_and_vocabulary(self, ds): False, "contributor_role_vocabulary", [ - "contributor_role_vocabulary '{}' must be of type 'string'".format( - vocb, - ), + f"contributor_role_vocabulary '{vocb}' must be of type 'string'", ], ), ) @@ -1302,9 +1289,7 @@ def check_single_platform(self, ds): num_platforms = len(platform_set) if num_platforms > 1 and glb_platform: - msg = "A dataset may only have one platform; {} found".format( - len(platform_set), - ) + msg = f"A dataset may only have one platform; {len(platform_set)} found" val = False elif (not glb_platform) and num_platforms > 0: @@ -1586,10 +1571,7 @@ def check_instrument_variables(self, ds): if instr in ds.variables: compnt = getattr(ds.variables[instr], "component", None) m = [ - "component attribute of {} ({}) must be a string".format( - instr, - compnt, - ), + f"component attribute of {instr} ({compnt}) must be a string", ] if compnt: results.append( @@ -1607,10 +1589,7 @@ def check_instrument_variables(self, ds): disct = getattr(ds.variables[instr], "discriminant", None) m = [ - "discriminant attribute of {} ({}) must be a string".format( - instr, - disct, - ), + f"discriminant attribute of {instr} ({disct}) must be a string", ] if disct: results.append( @@ -1711,9 +1690,7 @@ def check_qartod_variables_references(self, ds): ).format(v.name) val = False else: - msg = '"references" attribute for variable "{}" must be a valid URL'.format( - v.name, - ) + msg = f'"references" attribute for variable "{v.name}" must be a valid URL' val = bool(validators.url(attval)) results.append( diff --git a/compliance_checker/runner.py b/compliance_checker/runner.py index 114bcac1..0a8c6d2f 100644 --- a/compliance_checker/runner.py +++ b/compliance_checker/runner.py @@ -107,9 +107,7 @@ def run_checker( else: if len(output_format) > 1: # Update file name if needed - output_filename = "{}.txt".format( - os.path.splitext(output_filename)[0], - ) + output_filename = f"{os.path.splitext(output_filename)[0]}.txt" with open(output_filename, "w", encoding="utf-8") as f: with stdout_redirector(f): cls.stdout_output(cs, score_dict, verbose, limit) @@ -117,17 +115,13 @@ def run_checker( elif out_fmt == "html": # Update file name if needed if len(output_format) > 1 and output_filename != "-": - output_filename = "{}.html".format( - os.path.splitext(output_filename)[0], - ) + output_filename = f"{os.path.splitext(output_filename)[0]}.html" cls.html_output(cs, score_dict, output_filename, ds_loc, limit) elif out_fmt in {"json", "json_new"}: # Update file name if needed if len(output_format) > 1 and output_filename != "-": - output_filename = "{}.json".format( - os.path.splitext(output_filename)[0], - ) + output_filename = f"{os.path.splitext(output_filename)[0]}.json" cls.json_output(cs, score_dict, output_filename, ds_loc, limit, out_fmt) else: diff --git a/compliance_checker/suite.py b/compliance_checker/suite.py index 7f435208..5db72b67 100644 --- a/compliance_checker/suite.py +++ b/compliance_checker/suite.py @@ -644,11 +644,7 @@ def standard_output(self, ds, limit, check_name, groups): print("Corrective Actions".center(width)) plural = "" if issue_count == 1 else "s" print( - "{} has {} potential issue{}".format( - os.path.basename(ds), - issue_count, - plural, - ), + f"{os.path.basename(ds)} has {issue_count} potential issue{plural}", ) return [groups, points, out_of] diff --git a/compliance_checker/tests/test_cf.py b/compliance_checker/tests/test_cf.py index 70c8677c..367ffc6d 100644 --- a/compliance_checker/tests/test_cf.py +++ b/compliance_checker/tests/test_cf.py @@ -110,7 +110,7 @@ def test_coord_data_vars(self): "temp", np.float64, dimensions=("time",), - fill_value=float(99999999999999999999.0), + fill_value=99999999999999999999.0, ) temp.coordinates = "sigma noexist" ds.createVariable("sigma", np.float64, dimensions=("siglev",)) @@ -193,7 +193,7 @@ def test_check_child_attr_data_types(self): "temp", np.float64, dimensions=("time",), - fill_value=float(99999999999999999999.0), + fill_value=99999999999999999999.0, ) # give temp _FillValue as a float, expect good result @@ -2816,7 +2816,7 @@ def test_check_add_offset_scale_factor_type(self): # set same dtype dataset = MockTimeSeries() # time lat lon depth temp = dataset.createVariable("temp", int, dimensions=("time",)) - temp.setncattr("scale_factor", int(5)) + temp.setncattr("scale_factor", 5) r = self.cf.check_add_offset_scale_factor_type(dataset) self.assertTrue(r[1].value) self.assertFalse(r[1].msgs) diff --git a/compliance_checker/tests/test_cf_integration.py b/compliance_checker/tests/test_cf_integration.py index bb344f5e..5d162672 100644 --- a/compliance_checker/tests/test_cf_integration.py +++ b/compliance_checker/tests/test_cf_integration.py @@ -21,9 +21,7 @@ "attribute lat:_CoordianteAxisType should begin with a letter and be composed of letters, digits, and underscores", "attribute lon:_CoordianteAxisType should begin with a letter and be composed of letters, digits, and underscores", "§2.6.2 global attribute history should exist and be a non-empty string", - "standard_name temperature is not defined in Standard Name Table v{}. Possible close match(es): ['air_temperature', 'soil_temperature', 'snow_temperature']".format( - std_names._version, - ), + f"standard_name temperature is not defined in Standard Name Table v{std_names._version}. Possible close match(es): ['air_temperature', 'soil_temperature', 'snow_temperature']", "temperature's auxiliary coordinate specified by the coordinates attribute, precise_lat, is not a variable in this dataset", "temperature's auxiliary coordinate specified by the coordinates attribute, precise_lon, is not a variable in this dataset", ], @@ -45,30 +43,20 @@ "Attribute 'valid_range' (type: ) and parent variable 'wind_direction_qc' (type: ) must have equivalent datatypes", "Attribute 'valid_range' (type: ) and parent variable 'visibility_qc' (type: ) must have equivalent datatypes", '§2.6.1 Conventions global attribute does not contain "CF-1.8"', - "standard_name visibility is not defined in Standard Name Table v{}. Possible close match(es): ['visibility_in_air']".format( - std_names._version, - ), + f"standard_name visibility is not defined in Standard Name Table v{std_names._version}. Possible close match(es): ['visibility_in_air']", 'Standard name modifier "data_quality" for variable visibility_qc is not a valid modifier according to CF Appendix C', "standard_name wind_direction is not defined in Standard Name Table v{}. Possible close match(es): ['wind_to_direction', 'wind_from_direction', 'wind_gust_from_direction']".format( std_names._version, ), 'Standard name modifier "data_quality" for variable wind_direction_qc is not a valid modifier according to CF Appendix C', - "standard_name wind_gust is not defined in Standard Name Table v{}. Possible close match(es): ['y_wind_gust', 'x_wind_gust', 'wind_speed_of_gust']".format( - std_names._version, - ), + f"standard_name wind_gust is not defined in Standard Name Table v{std_names._version}. Possible close match(es): ['y_wind_gust', 'x_wind_gust', 'wind_speed_of_gust']", 'Standard name modifier "data_quality" for variable wind_gust_qc is not a valid modifier according to CF Appendix C', 'Standard name modifier "data_quality" for variable air_temperature_qc is not a valid modifier according to CF Appendix C', - "standard_name use_wind is not defined in Standard Name Table v{}. Possible close match(es): ['y_wind', 'x_wind']".format( - std_names._version, - ), - "standard_name barometric_pressure is not defined in Standard Name Table v{}. Possible close match(es): ['air_pressure', 'reference_pressure', 'barometric_altitude']".format( - std_names._version, - ), + f"standard_name use_wind is not defined in Standard Name Table v{std_names._version}. Possible close match(es): ['y_wind', 'x_wind']", + f"standard_name barometric_pressure is not defined in Standard Name Table v{std_names._version}. Possible close match(es): ['air_pressure', 'reference_pressure', 'barometric_altitude']", 'Standard name modifier "data_quality" for variable barometric_pressure_qc is not a valid modifier according to CF Appendix C', 'Standard name modifier "data_quality" for variable wind_speed_qc is not a valid modifier according to CF Appendix C', - "standard_name barometric_pressure is not defined in Standard Name Table v{}. Possible close match(es): ['air_pressure', 'reference_pressure', 'barometric_altitude']".format( - std_names._version, - ), + f"standard_name barometric_pressure is not defined in Standard Name Table v{std_names._version}. Possible close match(es): ['air_pressure', 'reference_pressure', 'barometric_altitude']", "CF recommends latitude variable 'lat' to use units degrees_north", "CF recommends longitude variable 'lon' to use units degrees_east", ], @@ -151,12 +139,8 @@ [ # TODO: referenced/relative time is treated like time units 'Units "hours since 2016-01-01T12:00:00Z" for variable time_offset must be convertible to canonical units "s"', - "standard_name cloud_cover is not defined in Standard Name Table v{}. Possible close match(es): ['land_cover', 'land_cover_lccs', 'cloud_albedo']".format( - std_names._version, - ), - "standard_name dew_point is not defined in Standard Name Table v{}. Possible close match(es): ['dew_point_depression', 'dew_point_temperature']".format( - std_names._version, - ), + f"standard_name cloud_cover is not defined in Standard Name Table v{std_names._version}. Possible close match(es): ['land_cover', 'land_cover_lccs', 'cloud_albedo']", + f"standard_name dew_point is not defined in Standard Name Table v{std_names._version}. Possible close match(es): ['dew_point_depression', 'dew_point_temperature']", ( "GRID is not a valid CF featureType. It must be one of point, timeseries, " "trajectory, profile, timeseriesprofile, trajectoryprofile" diff --git a/compliance_checker/tests/test_feature_detection.py b/compliance_checker/tests/test_feature_detection.py index 53665e94..11f88fdb 100644 --- a/compliance_checker/tests/test_feature_detection.py +++ b/compliance_checker/tests/test_feature_detection.py @@ -31,9 +31,7 @@ def test_timeseries(self): """ with Dataset(resources.STATIC_FILES["timeseries"]) as nc: for variable in util.get_geophysical_variables(nc): - assert util.is_timeseries(nc, variable), "{} is timeseries".format( - variable, - ) + assert util.is_timeseries(nc, variable), f"{variable} is timeseries" def test_multi_timeseries_orthogonal(self): """ @@ -63,9 +61,7 @@ def test_trajectory(self): """ with Dataset(resources.STATIC_FILES["trajectory"]) as nc: for variable in util.get_geophysical_variables(nc): - assert util.is_cf_trajectory(nc, variable), "{} is trajectory".format( - variable, - ) + assert util.is_cf_trajectory(nc, variable), f"{variable} is trajectory" def test_trajectory_single(self): """