Skip to content
Merged
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
12 changes: 5 additions & 7 deletions esmvalcore/_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import pprint
import subprocess
import sys
import textwrap
import threading
import time
from copy import deepcopy
Expand Down Expand Up @@ -264,13 +265,10 @@ def get_product_attributes(self) -> dict:
for product in self.products
}

def str(self):
def print_ancestors(self):
"""Return a nicely formatted description."""
def _indent(txt):
return '\n'.join('\t' + line for line in txt.split('\n'))

txt = 'ancestors:\n{}'.format('\n\n'.join(
_indent(str(task))
textwrap.indent(str(task), prefix=' ')
for task in self.ancestors) if self.ancestors else 'None')
return txt

Expand Down Expand Up @@ -642,8 +640,8 @@ def __repr__(self):
settings_string = pprint.pformat(self.settings)
string = (f"{self.__class__.__name__}: {self.name}\n"
f"script: {self.script}\n"
f"settings:\n{settings_string}\n")

f"settings:\n{settings_string}\n"
f"{self.print_ancestors()}\n")
Comment thread
stefsmeets marked this conversation as resolved.
return string


Expand Down
5 changes: 3 additions & 2 deletions esmvalcore/preprocessor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,11 @@ def __str__(self):
]
products = '\n\n'.join('\n'.join([str(p), pformat(p.settings)])
for p in self.products)
txt = "{}:\norder: {}\n{}\n{}".format(
txt = "{}: {}\norder: {}\n{}\n{}".format(
self.__class__.__name__,
self.name,
order,
products,
super(PreprocessingTask, self).str(),
self.print_ancestors(),
)
return txt
159 changes: 159 additions & 0 deletions tests/unit/task/test_print.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
"""Test that a task tree can be printed in a human readable form."""
import copy
import textwrap

import pytest

from esmvalcore._task import DiagnosticTask
from esmvalcore.preprocessor import PreprocessingTask, PreprocessorFile


@pytest.fixture
def preproc_file():
return PreprocessorFile(
attributes={'filename': '/output/preproc/file.nc'},
settings={
'extract_levels': {
'scheme': 'linear',
'levels': [95000]
},
},
)


@pytest.fixture
def preproc_task(preproc_file):
return PreprocessingTask(products=[preproc_file])


@pytest.fixture
def diagnostic_task(tmp_path):
mock_script = tmp_path / 'script.py'
mock_script.touch()
settings = {
'run_dir': str('/output/run'),
'profile_diagnostic': False,
}
task = DiagnosticTask(mock_script, settings, output_dir='/output/run')
task.script = '/some/where/esmvaltool/diag_scripts/test.py'
return task


def test_repr_preproc_task(preproc_task):
"""Test printing a preprocessor task."""
preproc_task.name = 'diag_1/tas'
result = str(preproc_task)
print(result)

reference = textwrap.dedent("""
PreprocessingTask: diag_1/tas
order: ['extract_levels', 'save']
PreprocessorFile: /output/preproc/file.nc
{'extract_levels': {'levels': [95000], 'scheme': 'linear'},
'save': {'filename': '/output/preproc/file.nc'}}
ancestors:
None
""")

assert result.strip() == reference.strip()


def test_repr_diagnostic_task(diagnostic_task):
"""Test printing a diagnostic task."""
diagnostic_task.name = 'diag_1/script_1'
result = str(diagnostic_task)
print(result)

reference = textwrap.dedent("""
DiagnosticTask: diag_1/script_1
script: /some/where/esmvaltool/diag_scripts/test.py
settings:
{'profile_diagnostic': False, 'run_dir': '/output/run'}
ancestors:
None
""")

assert result.strip() == reference.strip()


def test_repr_simple_tree(preproc_task, diagnostic_task):
"""Test the most common task tree."""
preproc_task.name = 'diag_1/tas'
diagnostic_task.name = 'diag_1/script_1'
diagnostic_task.ancestors = [preproc_task]
result = str(diagnostic_task)
print(result)

reference = textwrap.dedent("""
DiagnosticTask: diag_1/script_1
script: /some/where/esmvaltool/diag_scripts/test.py
settings:
{'profile_diagnostic': False, 'run_dir': '/output/run'}
ancestors:
PreprocessingTask: diag_1/tas
order: ['extract_levels', 'save']
PreprocessorFile: /output/preproc/file.nc
{'extract_levels': {'levels': [95000], 'scheme': 'linear'},
'save': {'filename': '/output/preproc/file.nc'}}
ancestors:
None
""")

assert result.strip() == reference.strip()


def test_repr_full_tree(preproc_task, diagnostic_task):
"""Test a more comlicated task tree."""
derive_input_task_1 = copy.deepcopy(preproc_task)
derive_input_task_1.name = 'diag_1/tas_derive_input_1'

derive_input_task_2 = copy.deepcopy(preproc_task)
derive_input_task_2.name = 'diag_1/tas_derive_input_2'

preproc_task.name = 'diag_1/tas'
preproc_task.ancestors = [derive_input_task_1, derive_input_task_2]

diagnostic_task_1 = copy.deepcopy(diagnostic_task)
diagnostic_task_1.name = 'diag_1/script_1'
diagnostic_task_1.ancestors = [preproc_task]

diagnostic_task.name = 'diag_1/script_2'
diagnostic_task.ancestors = [diagnostic_task_1]
result = str(diagnostic_task)
print(result)

reference = textwrap.dedent("""
DiagnosticTask: diag_1/script_2
script: /some/where/esmvaltool/diag_scripts/test.py
settings:
{'profile_diagnostic': False, 'run_dir': '/output/run'}
ancestors:
DiagnosticTask: diag_1/script_1
script: /some/where/esmvaltool/diag_scripts/test.py
settings:
{'profile_diagnostic': False, 'run_dir': '/output/run'}
ancestors:
PreprocessingTask: diag_1/tas
order: ['extract_levels', 'save']
PreprocessorFile: /output/preproc/file.nc
{'extract_levels': {'levels': [95000], 'scheme': 'linear'},
'save': {'filename': '/output/preproc/file.nc'}}
ancestors:
PreprocessingTask: diag_1/tas_derive_input_1
order: ['extract_levels', 'save']
PreprocessorFile: /output/preproc/file.nc
{'extract_levels': {'levels': [95000], 'scheme': 'linear'},
'save': {'filename': '/output/preproc/file.nc'}}
ancestors:
None

PreprocessingTask: diag_1/tas_derive_input_2
order: ['extract_levels', 'save']
PreprocessorFile: /output/preproc/file.nc
{'extract_levels': {'levels': [95000], 'scheme': 'linear'},
'save': {'filename': '/output/preproc/file.nc'}}
ancestors:
None
""")

assert result.strip() == reference.strip()