From 17b248f8f9122079cfae88c1353c323a8f8e950a Mon Sep 17 00:00:00 2001 From: Filipe Fernandes Date: Tue, 12 Nov 2024 20:52:54 +0100 Subject: [PATCH] make cf-units optional --- compliance_checker/cfutil.py | 48 +++++++++++++++++++++++++++--------- pyproject.toml | 4 +-- requirements.txt | 1 - 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/compliance_checker/cfutil.py b/compliance_checker/cfutil.py index 25ebc874..345f8301 100644 --- a/compliance_checker/cfutil.py +++ b/compliance_checker/cfutil.py @@ -9,9 +9,6 @@ from functools import lru_cache, partial from importlib_resources import files -from pyudunits2 import UnitSystem, UnresolvableUnitException - -ut_system = UnitSystem.from_udunits2_xml() _UNITLESS_DB = None _SEA_NAMES = None @@ -2032,30 +2029,59 @@ def guess_feature_type(nc, variable): return "reduced-grid" +class _CCUnit: + def __init__(self, units): + import cf_units + + self.u = cf_units.Unit(units) + self.is_time_reference = self.u.is_time_reference() + + def __eq__(self, other): + return self.u == other.u + + def is_convertible_to(self, other): + if isinstance(other, str): + ret = self.u.is_convertible(other) + else: + ret = self.u.is_convertible(other.u) + return ret + + def is_dimensionless(self): + return self.u.is_dimensionless() + + def expanded(self): + return self.u.definition + + def _units(units: str): """PLACEHOLDER.""" - # FIXME: - # cf_units will create: - # cf_units.Unit(None) - # Unit('unknown') - # that will contain all the methods we use here. + # FIXME: Try to make cf_units optional + try: + return _CCUnit(units) + except ImportError: + from pyudunits2 import UnitSystem, UnresolvableUnitException + + ut_system = UnitSystem.from_udunits2_xml() + + # FIXME: cf_units.Unit(None) -> Unit('unknown') if units is None: units = "" + # FIXME: Syntax Error when HH:MM:SS is present in time reference. if "T00:00:00" in units: units = units.replace("T00:00:00", "") + # FIXME: cf_units raised only ValueError try: u = ut_system.unit(units) except (SyntaxError, UnresolvableUnitException) as err: raise ValueError from err + # FIXME: cf_units defined .is_time_reference for time reference units. u.is_time_reference = False - u.is_long_time_interval = False try: if hasattr(u._definition, "shift_from"): u.is_time_reference = True - if u._definition.unit.content in ("months", "years"): - u.is_long_time_interval = True except KeyError: + # FIXME: hasattr should return None in that case. # pyudunits2/_expr_graph.py:27, in Node.__getattr__(self, name) # 25 def __getattr__(self, name): # 26 # Allow the dictionary to raise KeyError if the key doesn't exist. diff --git a/pyproject.toml b/pyproject.toml index 696cf98f..618e9291 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ requires = [ [project] name = "compliance-checker" description = "Checks Datasets and SOS endpoints for standards compliance" -readme = "README.md" +readme = { file = "README.md", content-type = "text/markdown" } license = { text = "Apache-2.0" } maintainers = [ { name = "Dave Foster", email = "dave@axiomdatascience.com" }, @@ -40,6 +40,7 @@ dynamic = [ "dependencies", "version", ] +optional-dependencies.extras = [ "cf-units>=2" ] urls.documentation = "https://ioos.github.io/compliance-checker" urls.homepage = "https://compliance.ioos.us/index.html" urls.repository = "https://github.com/ioos/compliance-checker" @@ -81,7 +82,6 @@ compliance_checker = [ dependencies = { file = [ "requirements.txt", ] } -readme = { file = "README.md", content-type = "text/markdown" } [tool.setuptools_scm] write_to = "compliance_checker/_version.py" diff --git a/requirements.txt b/requirements.txt index 1a61c43b..40c38f38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -cf-units>=2 cftime>=1.1.0 importlib-metadata importlib-resources