Skip to content

Commit

Permalink
fix(config): stop __line__ entries appearing in dict config properties
Browse files Browse the repository at this point in the history
This uses a custom dict subclass to store the line numbers, rather than
a special `__line__` key in the dict itself.
  • Loading branch information
jrs65 committed Jan 16, 2021
1 parent 8055bf7 commit 468a7bd
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 15 deletions.
18 changes: 11 additions & 7 deletions caput/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,10 +462,6 @@ def _prop(config):
loglevels = ["DEBUG", "INFO", "WARNING", "ERROR", "NOTSET"]
for key, level in config.items():

# ignore hint at yaml file line number
if key == "__line__":
continue

level = level.upper()
if level not in loglevels:
raise ValueError(
Expand All @@ -488,6 +484,12 @@ def _prop(config):
return prop


class _line_dict(dict):
"""A private dict subclass that also stores line numbers for debugging."""

__line__ = None


class SafeLineLoader(SafeLoader):
"""
YAML loader that tracks line numbers.
Expand All @@ -498,8 +500,10 @@ class SafeLineLoader(SafeLoader):

def construct_mapping(self, node, deep=False):
mapping = super(SafeLineLoader, self).construct_mapping(node, deep=deep)
mapping = _line_dict(mapping)

# Add 1 so numbering starts at 1
mapping["__line__"] = node.start_mark.line + 1
mapping.__line__ = node.start_mark.line + 1
return mapping


Expand All @@ -521,8 +525,8 @@ class CaputConfigError(Exception):
def __init__(self, message, file_=None, location=None):
self.message = message
self.file = file_
if isinstance(location, dict):
self.line = location.get("__line__", None)
if isinstance(location, _line_dict):
self.line = location.__line__
else:
self.line = None

Expand Down
6 changes: 2 additions & 4 deletions caput/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ def _setup_task(self, task_spec):

# Check that only the expected keys are in the task spec.
for key in task_spec.keys():
if key not in ["type", "params", "requires", "in", "out", "__line__"]:
if key not in ["type", "params", "requires", "in", "out"]:
raise config.CaputConfigError(
"Task got an unexpected key '{}' in 'tasks' list.".format(key)
)
Expand Down Expand Up @@ -882,9 +882,7 @@ def cacheable(self):
def _from_config(cls, config):
self = cls.__new__(cls)
# Check for unused keys, but ignore the ones not put there by the user.
self.read_config(
config, compare_keys=["versions", "pipeline_config", "__line__"]
)
self.read_config(config, compare_keys=["versions", "pipeline_config"])
self.__init__()
return self

Expand Down
4 changes: 0 additions & 4 deletions caput/tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ def test_default_params(self):
self.assertDictEqual(man.all_tasks_params["versions"], {})
# remove line numbers
pipeline_config = man.all_tasks_params["pipeline_config"]
del pipeline_config["__line__"]
del pipeline_config["pipeline"]["__line__"]
self.assertDictEqual(
pipeline_config,
yaml.load(testconfig, Loader=yaml.SafeLoader),
Expand Down Expand Up @@ -50,8 +48,6 @@ def test_metadata_params(self):

# remove line numbers
pipeline_config = man.all_tasks_params["pipeline_config"]
del pipeline_config["__line__"]
del pipeline_config["pipeline"]["__line__"]
self.assertDictEqual(
pipeline_config,
yaml.load(testconfig, Loader=yaml.SafeLoader),
Expand Down

0 comments on commit 468a7bd

Please sign in to comment.