Skip to content

Commit

Permalink
Merge pull request #126 from timmeinhardt/pretty_docstring_printing
Browse files Browse the repository at this point in the history
Pretty docstring printing
  • Loading branch information
Qwlouse committed Dec 22, 2016
2 parents 408e43e + 766abbf commit 6a9ad6e
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 22 deletions.
19 changes: 13 additions & 6 deletions sacred/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
BLUE = '\033[94m'
GREEN = '\033[92m'
RED = '\033[91m'
GREY = '\033[90m'
ENDC = '\033[0m'

LEGEND = '(' + BLUE + 'modified' + ENDC +\
', ' + GREEN + 'added' + ENDC +\
', ' + RED + 'typechanged' + ENDC + ')'
', ' + RED + 'typechanged' + ENDC +\
', ' + GREY + 'doc' + ENDC + ')'

ConfigEntry = namedtuple('ConfigEntry',
'key value added modified typechanged doc')
Expand Down Expand Up @@ -85,7 +87,7 @@ def print_dependencies(_run):


def _iterate_marked(cfg, config_mods):
for path, value in iterate_flattened_separately(cfg):
for path, value in iterate_flattened_separately(cfg, ['__doc__']):
if value is PATHCHANGE:
yield path, PathEntry(
key=path.rpartition('.')[2],
Expand All @@ -112,16 +114,21 @@ def _format_entry(indent, entry):
color = GREEN
elif entry.modified:
color = BLUE
end = ENDC if color else ""
if isinstance(entry, ConfigEntry):
if entry.key == '__doc__':
color = GREY
doc_string = entry.value.replace('\n', '\n' + indent)
assign = '{}"""{}"""'.format(indent, doc_string)
elif isinstance(entry, ConfigEntry):
assign = indent + entry.key + " = " + PRINTER.pformat(entry.value)
else: # isinstance(entry, PathEntry):
assign = indent + entry.key + ":"
if entry.doc:
doc_string = GREY + '# ' + entry.doc + ENDC
if len(assign) <= 35:
assign = "{:<35} # {}".format(assign, entry.doc)
assign = "{:<35} {}".format(assign, doc_string)
else:
assign += ' # ' + entry.doc
assign += ' ' + doc_string
end = ENDC if color else ""
return color + assign + end


Expand Down
29 changes: 19 additions & 10 deletions sacred/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,26 +162,35 @@ def tee_output(target):
os.close(saved_stderr_fd)


def iterate_flattened_separately(dictionary):
def iterate_flattened_separately(dictionary, manually_sorted_keys=None):
"""
Recursively iterate over the items of a dictionary in a special order.
First iterate over all items that are non-dictionary values
(sorted by keys), then over the rest (sorted by keys), providing full
dotted paths for every leaf.
First iterate over manually sorted keys and then over all items that are
non-dictionary values (sorted by keys), then over the rest
(sorted by keys), providing full dotted paths for every leaf.
"""
if manually_sorted_keys is None:
manually_sorted_keys = []
for key in manually_sorted_keys:
if key in dictionary:
yield key, dictionary[key]

single_line_keys = [key for key in dictionary.keys() if
not dictionary[key] or
not isinstance(dictionary[key], dict)]
key not in manually_sorted_keys and
(not dictionary[key] or
not isinstance(dictionary[key], dict))]
for key in sorted(single_line_keys):
yield key, dictionary[key]

multi_line_keys = [key for key in dictionary.keys()
if (dictionary[key] and
isinstance(dictionary[key], dict))]
multi_line_keys = [key for key in dictionary.keys() if
key not in manually_sorted_keys and
(dictionary[key] and
isinstance(dictionary[key], dict))]
for key in sorted(multi_line_keys):
yield key, PATHCHANGE
for k, val in iterate_flattened_separately(dictionary[key]):
for k, val in iterate_flattened_separately(dictionary[key],
manually_sorted_keys):
yield join_paths(key, k), val


Expand Down
9 changes: 6 additions & 3 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import pprint

import pytest
from sacred.commands import (BLUE, ENDC, GREEN, RED, ConfigEntry, PathEntry,
_format_config, _format_entry, help_for_command,
_iterate_marked, _non_unicode_repr)
from sacred.commands import (BLUE, ENDC, GREY, GREEN, RED, ConfigEntry,
PathEntry, _format_config, _format_entry,
help_for_command, _iterate_marked, _non_unicode_repr)
from sacred.config.config_summary import ConfigSummary


Expand Down Expand Up @@ -107,6 +107,9 @@ def test_iterate_marked_typechanged(cfg):
(ConfigEntry('e', {}, False, False, None, None), "e = {}"),
# Path entries
(PathEntry('f', False, False, None, None), "f:"),
# Docstring entry
(ConfigEntry('__doc__', 'multiline\ndocstring', False, False, None, None),
GREY + '"""multiline\ndocstring"""' + ENDC),
])
def test_format_entry(entry, expected):
assert _format_entry(0, entry) == expected
Expand Down
6 changes: 3 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ def test_recursive_update():

def test_iterate_flattened_separately():
d = {'a1': 1,
'b2': {'foo': 'bar'},
'b2': {'bar': 'foo', 'foo': 'bar'},
'c1': 'f',
'd1': [1, 2, 3],
'e2': {}}
res = list(iterate_flattened_separately(d))
res = list(iterate_flattened_separately(d, ['foo', 'bar']))
assert res == [('a1', 1), ('c1', 'f'), ('d1', [1, 2, 3]), ('e2', {}),
('b2', PATHCHANGE), ('b2.foo', 'bar')]
('b2', PATHCHANGE), ('b2.foo', 'bar'), ('b2.bar', 'foo')]


def test_iterate_flattened():
Expand Down

0 comments on commit 6a9ad6e

Please sign in to comment.