Skip to content

Commit

Permalink
Package fully typed
Browse files Browse the repository at this point in the history
  • Loading branch information
JB Lovland committed Jan 9, 2024
1 parent 49011ad commit 37fa0ac
Show file tree
Hide file tree
Showing 19 changed files with 479 additions and 319 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci-fmudataio.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ jobs:
os: [ubuntu-latest]

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v2
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/fmudataio-documention.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.8"]
python-version: ["3.10"]
os: [ubuntu-latest]

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v4
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/fmudataio-publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ jobs:
name: Build and publish Python 🐍 distributions 📦 to PyPI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
Expand Down
11 changes: 7 additions & 4 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ jobs:
matrix:
python-version: ["3.10"]
steps:
- uses: actions/checkout@v2

- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up python
uses: actions/setup-python@v4
- name: Check black style and linting
run: pip install ruff
- name: Install dev-env.
run: |
pip install -U pip
pip install ".[dev]"
- name: Ruff check
if: ${{ always() }}
run: ruff check .
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Mypy

on: [push, pull_request]

jobs:
mypy:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10"]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up python
uses: actions/setup-python@v4
- name: Install dev-env.
run: |
pip install -U pip
pip install ".[dev]"
- name: Mypy
run: mypy .
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,6 @@ venv.bak/

# setuptools_scm version
src/fmu/dataio/version.py

# mypy
.dmypy.json
2 changes: 0 additions & 2 deletions examples/s/d/nn/_project/aggregate_surfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ def main():
# This is the ID we assign to this set of aggregations
aggregation_id = "something_very_unique" # IRL this will usually be a uuid

# We aggregate these source surfaces and collect results in list of dictionaries

# Initialize an AggregatedData object for this set of aggregations
exp = fmu.dataio.AggregatedData(
source_metadata=source_metadata,
Expand Down
11 changes: 8 additions & 3 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
[mypy]

[mypy-numpy.*]
# Applies to Python 3.6:
disallow_untyped_defs = True
exclude = ^((tests|docs|examples|bin)/|conftest.py?)
extra_checks = True
ignore_missing_imports = True
python_version = 3.8
strict_equality = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unused_ignores = True
59 changes: 40 additions & 19 deletions src/fmu/dataio/_definitions.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,62 @@
"""Various definitions and hard settings used in fmu-dataio."""
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Final

SCHEMA = (
SCHEMA: Final = (
"https://main-fmu-schemas-prod.radix.equinor.com/schemas/0.8.0/fmu_results.json"
)
VERSION = "0.8.0"
SOURCE = "fmu"
VERSION: Final = "0.8.0"
SOURCE: Final = "fmu"


@dataclass
class _ValidFormats:
surface: dict = field(default_factory=dict)
grid: dict = field(default_factory=dict)
cube: dict = field(default_factory=dict)
table: dict = field(default_factory=dict)
polygons: dict = field(default_factory=dict)
points: dict = field(default_factory=dict)
dictionary: dict = field(default_factory=dict)

def __post_init__(self):
self.surface = {"irap_binary": ".gri"}
self.grid = {"hdf": ".hdf", "roff": ".roff"}
self.cube = {"segy": ".segy"}
self.table = {"hdf": ".hdf", "csv": ".csv", "arrow": ".arrow"}
self.polygons = {
surface: dict = field(
default_factory=lambda: {
"irap_binary": ".gri",
}
)
grid: dict = field(
default_factory=lambda: {
"hdf": ".hdf",
"roff": ".roff",
}
)
cube: dict = field(
default_factory=lambda: {
"segy": ".segy",
}
)
table: dict = field(
default_factory=lambda: {
"hdf": ".hdf",
"csv": ".csv",
"arrow": ".arrow",
}
)
polygons: dict = field(
default_factory=lambda: {
"hdf": ".hdf",
"csv": ".csv", # columns will be X Y Z, ID
"csv|xtgeo": ".csv", # use default xtgeo columns: X_UTME, ... POLY_ID
"irap_ascii": ".pol",
}
self.points = {
)
points: dict = field(
default_factory=lambda: {
"hdf": ".hdf",
"csv": ".csv", # columns will be X Y Z
"csv|xtgeo": ".csv", # use default xtgeo columns: X_UTME, Y_UTMN, Z_TVDSS
"irap_ascii": ".poi",
}
self.dictionary = {"json": ".json"}
)
dictionary: dict = field(
default_factory=lambda: {
"json": ".json",
}
)


ALLOWED_CONTENTS = {
Expand Down
64 changes: 33 additions & 31 deletions src/fmu/dataio/_design_kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,31 @@
It is copied here instead of pip-installed in order to avoid dragging
along all dependencies of semeio"""

# pylint: disable=logging-fstring-interpolation
from __future__ import annotations

import logging
import re
import shlex
from typing import Any, Final, Iterable

_STATUS_FILE_NAME = "DESIGN_KW.OK"
_STATUS_FILE_NAME: Final = "DESIGN_KW.OK"

_logger = logging.getLogger(__name__)
_logger: Final = logging.getLogger(__name__)


def run(
template_file_name,
result_file_name,
log_level,
parameters_file_name="parameters.txt",
):
template_file_name: str,
result_file_name: str,
log_level: str,
parameters_file_name: str = "parameters.txt",
) -> None:
# Get all key, value pairs
# If FWL key is having multiple entries in the parameters file
# KeyError is raised. This will be logged, and no OK
# file is written

_logger.setLevel(log_level)

valid = True

with open(parameters_file_name) as parameters_file:
parameters = parameters_file.readlines()

Expand All @@ -40,24 +40,22 @@ def run(
with open(template_file_name) as template_file:
template = template_file.readlines()

if valid:
with open(result_file_name, "w") as result_file:
for line in template:
if not is_comment(line):
for key, value in key_vals.items():
line = line.replace(f"<{key}>", str(value))
with open(result_file_name, "w") as result_file:
for line in template:
if not is_comment(line):
for key, value in key_vals.items():
line = line.replace(f"<{key}>", str(value))

if not all_matched(line, template_file_name, template):
valid = False
if not all_matched(line, template_file_name, template):
pass

result_file.write(line)
result_file.write(line)

if valid:
with open(_STATUS_FILE_NAME, "w") as status_file:
status_file.write("DESIGN_KW OK\n")
with open(_STATUS_FILE_NAME, "w") as status_file:
status_file.write("DESIGN_KW OK\n")


def all_matched(line, template_file_name, template):
def all_matched(line: str, template_file_name: str, template: list[str]) -> bool:
valid = True
for unmatched in unmatched_templates(line):
if is_perl(template_file_name, template):
Expand All @@ -73,24 +71,24 @@ def all_matched(line, template_file_name, template):
return valid


def is_perl(file_name, template):
return file_name.endswith(".pl") or template[0].find("perl") != -1
def is_perl(file_name: str, template: list[str]) -> bool:
return bool(file_name.endswith(".pl") or template[0].find("perl") != -1)


def unmatched_templates(line):
def unmatched_templates(line: str) -> list[str]:
bracketpattern = re.compile("<.+?>")
if bracketpattern.search(line):
return bracketpattern.findall(line)
return []


def is_comment(line):
def is_comment(line: str) -> bool:
ecl_comment_pattern = re.compile("^--")
std_comment_pattern = re.compile("^#")
return ecl_comment_pattern.search(line) or std_comment_pattern.search(line)
return bool(ecl_comment_pattern.search(line) or std_comment_pattern.search(line))


def extract_key_value(parameters):
def extract_key_value(parameters: Iterable[str]) -> dict[str, str]:
"""Parses a list of strings, looking for key-value pairs pr. line
separated by whitespace, into a dictionary.
Expand Down Expand Up @@ -128,7 +126,10 @@ def extract_key_value(parameters):
return res


def rm_genkw_prefix(paramsdict, ignoreprefixes="LOG10_"):
def rm_genkw_prefix(
paramsdict: dict[str, Any],
ignoreprefixes: str | list[str] | None = "LOG10_",
) -> dict[str, Any]:
"""Strip prefixes from keys in a dictionary.
Prefix is any string before a colon. No colon means no prefix.
Expand All @@ -152,7 +153,8 @@ def rm_genkw_prefix(paramsdict, ignoreprefixes="LOG10_"):
ignoreprefixes = []
if isinstance(ignoreprefixes, str):
ignoreprefixes = [ignoreprefixes]
ignoreprefixes = filter(None, ignoreprefixes)

ignoreprefixes = list(filter(None, ignoreprefixes))

for ignore_str in ignoreprefixes:
paramsdict = {
Expand Down
Loading

0 comments on commit 37fa0ac

Please sign in to comment.