Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Black linting check to CI and add to test reqs #170

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,30 @@ jobs:
python-version: [ '3.5', '3.8' ]
steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install "numpy<1.19.0"
pip install -r test_requirements.txt
pip install pytest-cov

- name: Run Black check for formatting
if: ${{ matrix.python-version != '3.5' }}
run: |
# Need to manually install Black while we support Python 3.5
pip install black
black --check .

- name: Test with pytest
run: |
pytest --cov=./ --cov-report=xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Python files
*.pyc
*.egg-info
build

# PyCharm settings
.idea

# vscode settings
.hypothesis
2 changes: 1 addition & 1 deletion aodntools/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.0.0'
__version__ = "0.0.0"
12 changes: 6 additions & 6 deletions aodntools/ncwriter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from .imos_template import ImosTemplate, TIMESTAMP_FORMAT

__all__ = [
'ImosTemplate',
'DatasetTemplate',
'ValidationError',
'metadata_attributes',
'special_attributes',
'TIMESTAMP_FORMAT'
"ImosTemplate",
"DatasetTemplate",
"ValidationError",
"metadata_attributes",
"special_attributes",
"TIMESTAMP_FORMAT",
]
45 changes: 28 additions & 17 deletions aodntools/ncwriter/imos_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

from .template import DatasetTemplate

IMOS_GLOBAL_JSON = resource_filename(__name__, 'imos_global.json')
IMOS_GLOBAL_JSON = resource_filename(__name__, "imos_global.json")
IMOS_GLOBAL_ATTRIBUTES = DatasetTemplate.from_json(IMOS_GLOBAL_JSON).global_attributes

TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%SZ"


class ImosTemplate(DatasetTemplate):
Expand All @@ -19,7 +19,9 @@ def __init__(self, global_attributes=None, *args, **kwargs):
combined_attributes = IMOS_GLOBAL_ATTRIBUTES.copy()
if global_attributes is not None:
combined_attributes.update(global_attributes)
super(ImosTemplate, self).__init__(global_attributes=combined_attributes, *args, **kwargs)
super(ImosTemplate, self).__init__(
global_attributes=combined_attributes, *args, **kwargs
)
self._date_created = None

@property
Expand All @@ -30,9 +32,13 @@ def date_created(self):
return self._date_created

def add_date_created_attribute(self):
self.global_attributes['date_created'] = self.date_created.strftime(TIMESTAMP_FORMAT)
self.global_attributes["date_created"] = self.date_created.strftime(
TIMESTAMP_FORMAT
)

def add_extent_attributes(self, time_var='TIME', vert_var='DEPTH', lat_var='LATITUDE', lon_var='LONGITUDE'):
def add_extent_attributes(
self, time_var="TIME", vert_var="DEPTH", lat_var="LATITUDE", lon_var="LONGITUDE"
):
"""
Calculate spatial and temporal extents from coordinate variables in the template and add/update
the relevant global attributes. Set an input variable name to None to skip that coordinate.
Expand All @@ -46,28 +52,33 @@ def add_extent_attributes(self, time_var='TIME', vert_var='DEPTH', lat_var='LATI
if time_var:
data_range = self.get_data_range(time_var)
time = self.variables[time_var]
units = time.get('units')
units = time.get("units")
if not units:
raise ValueError("Time variable '{time_var}' has no units".format(time_var=time_var))
calendar = time.get('calendar', 'gregorian')
raise ValueError(
"Time variable '{time_var}' has no units".format(time_var=time_var)
)
calendar = time.get("calendar", "gregorian")
time_range = num2date(data_range, units, calendar)
self.global_attributes['time_coverage_start'] = time_range[0].strftime(TIMESTAMP_FORMAT)
self.global_attributes['time_coverage_end'] = time_range[1].strftime(TIMESTAMP_FORMAT)
self.global_attributes["time_coverage_start"] = time_range[0].strftime(
TIMESTAMP_FORMAT
)
self.global_attributes["time_coverage_end"] = time_range[1].strftime(
TIMESTAMP_FORMAT
)

if vert_var:
vmin, vmax = self.get_data_range(vert_var)
self.global_attributes['geospatial_vertical_min'] = vmin
self.global_attributes['geospatial_vertical_max'] = vmax
self.global_attributes["geospatial_vertical_min"] = vmin
self.global_attributes["geospatial_vertical_max"] = vmax

if lat_var:
vmin, vmax = self.get_data_range(lat_var)
self.global_attributes['geospatial_lat_min'] = vmin
self.global_attributes['geospatial_lat_max'] = vmax
self.global_attributes["geospatial_lat_min"] = vmin
self.global_attributes["geospatial_lat_max"] = vmax

if lon_var:
vmin, vmax = self.get_data_range(lon_var)
self.global_attributes['geospatial_lon_min'] = vmin
self.global_attributes['geospatial_lon_max'] = vmax
self.global_attributes["geospatial_lon_min"] = vmin
self.global_attributes["geospatial_lon_max"] = vmax

# TODO: def set_imos_filename(self):

29 changes: 18 additions & 11 deletions aodntools/ncwriter/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
# Create a new validator class (based on Draft4Validator) to allow templates to use
# * Python types or numpy dtypes to specify variable data types; and
# * numpy arrays to specify variable data.
TemplateValidator = validators.create(meta_schema=Draft4Validator.META_SCHEMA,
validators=Draft4Validator.VALIDATORS)
TemplateValidator = validators.create(
meta_schema=Draft4Validator.META_SCHEMA, validators=Draft4Validator.VALIDATORS
)
format_checker = FormatChecker()


@format_checker.checks('datatype')
@format_checker.checks("datatype")
def is_python_datatype(value):
"""Return whether the given value is a valid data type specification for a NetCDF variable"""
if isinstance(value, np.dtype):
Expand All @@ -28,31 +29,37 @@ def is_python_datatype(value):
return False


TYPES = {'array': (list, np.ndarray)}
TYPES = {"array": (list, np.ndarray)}

TEMPLATE_SCHEMA_JSON = resource_filename(__name__, 'template_schema.json')
TEMPLATE_SCHEMA_JSON = resource_filename(__name__, "template_schema.json")
with open(TEMPLATE_SCHEMA_JSON) as f:
TEMPLATE_SCHEMA = json.load(f)
TemplateValidator.check_schema(TEMPLATE_SCHEMA)

template_validator = TemplateValidator(TEMPLATE_SCHEMA, types=TYPES, format_checker=format_checker)
template_validator = TemplateValidator(
TEMPLATE_SCHEMA, types=TYPES, format_checker=format_checker
)


def validate_template(t):
template_validator.validate(t)


def validate_dimensions(d):
validate_template({'_dimensions': d})
validate_template({"_dimensions": d})


def validate_variables(v):
validate_template({'_variables': v})
validate_template({"_variables": v})


def validate_global_attributes(a):
if hasattr(a, 'keys'):
special = [k for k in a.keys() if k.startswith('_')]
if hasattr(a, "keys"):
special = [k for k in a.keys() if k.startswith("_")]
if special:
raise ValidationError('Special attributes {} not allowed in global attributes dict'.format(special))
raise ValidationError(
"Special attributes {} not allowed in global attributes dict".format(
special
)
)
template_validator.validate(a)
Loading