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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Changelog
## 6.0.1
### Fixes
- Improve error messages when loading fails

## 6.0.0
### Breaking changes
- Remove support for Python 3.8
Expand Down
10 changes: 7 additions & 3 deletions configue/configue_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os
import re
from collections.abc import Hashable
from typing import Any, List, Mapping, Union
from typing import Any, List, Mapping, Optional, Union

import yaml
from yaml.constructor import ConstructorError
Expand All @@ -25,6 +25,7 @@ def construct_yaml_map(self, node: yaml.MappingNode) -> Any:
path = mapping.pop(CONSTRUCTOR_KEY)
object_path_elements = path.split(".")
remaining_path_elements: List[str] = []
exceptions: list[Optional[str]] = []
while object_path_elements:
try:
cls = self.find_python_name(
Expand All @@ -33,10 +34,13 @@ def construct_yaml_map(self, node: yaml.MappingNode) -> Any:
unsafe=True,
)
break
except ConstructorError:
except ConstructorError as error:
exceptions.append(error.problem)
remaining_path_elements.insert(0, object_path_elements.pop(-1))
else:
raise NotFoundError(f"Could not load element {path} {node.start_mark}")
raise NotFoundError(
f"Could not load element {path} {node.start_mark}, exceptions encountered: {exceptions!r}"
) from None
for path_element in remaining_path_elements:
cls = getattr(cls, path_element)

Expand Down
8 changes: 6 additions & 2 deletions configue/file_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def _load_ext(self, loader: ConfigueLoader, node: ScalarNode) -> Any:
path = loader.construct_scalar(node)
object_path_elements = path.split(".")
remaining_path_elements: List[str] = []
exceptions: list[Optional[str]] = []
while object_path_elements:
try:
loaded_object = loader.find_python_name(
Expand All @@ -128,10 +129,13 @@ def _load_ext(self, loader: ConfigueLoader, node: ScalarNode) -> Any:
unsafe=True,
)
break
except ConstructorError:
except ConstructorError as error:
exceptions.append(error.problem)
remaining_path_elements.insert(0, object_path_elements.pop(-1))
else:
raise NotFoundError(f"Could not load element {path} {node.start_mark}")
raise NotFoundError(
f"Could not load element {path} {node.start_mark}, encountered exceptions: {exceptions!r}"
) from None
remaining_path = ".".join(remaining_path_elements)
if remaining_path:
return self._get_element_at_sub_path(remaining_path, loaded_object)
Expand Down
6 changes: 3 additions & 3 deletions tests/test_configue.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from unittest import TestCase

import configue
from configue.exceptions import NonCallableError, SubPathNotFound, NotFoundError
from configue.exceptions import ConfigueError, NonCallableError, SubPathNotFound, NotFoundError
from tests.external_module import CONSTANT, MyObject, Color


Expand Down Expand Up @@ -178,11 +178,11 @@ def test_ext_raises_exception_on_submodule_not_found(self):
configue.load(self._get_path("test_file_2.yml"), "invalid_ext.wrong_sub_module")

def test_ext_raises_exception_on_element_not_found(self):
with self.assertRaises(NotFoundError):
with self.assertRaises(ConfigueError):
configue.load(self._get_path("test_file_2.yml"), "invalid_ext.wrong_element")

def test_ext_raises_exception_on_property_not_found(self):
with self.assertRaises(NotFoundError):
with self.assertRaises(KeyError):
configue.load(self._get_path("test_file_2.yml"), "invalid_ext.wrong_property")

def test_loading_empty_file(self):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_file_2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ enum_loading: !ext tests.external_module.Color.RED
invalid_ext:
wrong_module: !ext invalid.test.Color.RED
wrong_sub_module: !ext tests.invalid.Color.RED
wrong_element: !ext tests.invalid.Invalid.RED
wrong_property: !ext tests.invalid.Color.GREEN
wrong_element: !ext tests.external_module.Invalid.RED
wrong_property: !ext tests.external_module.Color.GREEN

static_loading:
(): tests.external_module.Static.get_static_value
Expand Down