Skip to content

Commit

Permalink
Elevate warning to errors for unknown attributes (#788)
Browse files Browse the repository at this point in the history
* replace CunfigureWarning with ConfigureError for unknown attributes

* fix tests broken by ConfigurationError

* Restore test_requirement Test4 and add test for readonly attribute conficts

* use assertIn idiom for readonly attribute test
  • Loading branch information
filimarc committed Dec 31, 2023
1 parent 95c7018 commit b0714eb
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 11 deletions.
8 changes: 3 additions & 5 deletions bsb/config/_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from ..exceptions import (
CastError,
ConfigurationWarning,
ConfigurationError,
DynamicClassError,
DynamicClassInheritanceError,
DynamicObjectNotFoundError,
Expand Down Expand Up @@ -293,17 +293,15 @@ def __post_new__(self, _parent=None, _key=None, **kwargs):
try:
_try_catch_attrs(self, catch_attrs, key, value)
except UncaughtAttributeError:
warning = ConfigurationWarning(f"Unknown attribute: '{key}'")
warning.node = self
warn(warning, ConfigurationWarning)
try:
setattr(self, key, value)
except AttributeError:
raise AttributeError(
f"Unknown configuration attribute key '{key}' conflicts with"
f"Configuration attribute key '{key}' conflicts with"
+ f" readonly class attribute on `{self.__class__.__module__}"
+ f".{self.__class__.__name__}`."
) from None
raise ConfigurationError(f"Unknown attribute: '{key}'") from None

return __post_new__

Expand Down
19 changes: 15 additions & 4 deletions tests/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
CastError,
CfgReferenceError,
ClassMapMissingError,
ConfigurationError,
ConfigurationWarning,
DynamicClassInheritanceError,
DynamicObjectNotFoundError,
Expand All @@ -21,6 +22,7 @@
UnresolvedClassCastError,
)
from bsb.storage import NrrdDependencyNode, YamlDependencyNode
from bsb.topology.partition import Partition
from bsb.topology.region import RegionGroup


Expand Down Expand Up @@ -51,12 +53,20 @@ def test_no_unknown_attributes(self):
def test_unknown_attributes(self):
tree = Configuration.default().__tree__()
tree["shouldntexistasattr"] = 15
with self.assertWarns(ConfigurationWarning) as warning:
with self.assertRaises(ConfigurationError) as e:
Configuration(tree)

self.assertIn(
"""Unknown attribute: 'shouldntexistasattr'""", str(warning.warning)
)
def test_readonly_attributes(self):
tree = Configuration.default().__tree__()
tree["partitions"] = {
"base_layer": {"type": "layer", "thickness": 100, "region": "x"}
}
with self.assertRaises(CastError) as ec:
Configuration(tree)
# Need a further check since CastError is raised before AttributeError
check_str = "Configuration attribute key 'region' conflicts with readonly"
msg_str = "Readonly class attribute conflicts"
self.assertIn(check_str, str(ec.exception), msg_str)


class TestConfigAttrs(unittest.TestCase):
Expand Down Expand Up @@ -134,6 +144,7 @@ class Test3:

@config.node
class Test4:
timmy = config.attr(type=str)
name = config.attr(type=str, required=regular)

Test(name="required")
Expand Down
4 changes: 2 additions & 2 deletions tests/test_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def test_partition_chunking(self):
class TestAllenVoxels(unittest.TestCase):
def test_val(self):
cfg = Configuration.default(
region=dict(br=dict(children=["a"])),
regions=dict(br=dict(children=["a"])),
partitions=dict(a=dict(type="allen", struct_name="VAL")),
)
part = cfg.partitions.a
Expand All @@ -93,7 +93,7 @@ def test_val(self):

def test_mask_nrrd(self):
cfg = Configuration.default(
region=dict(br=dict(children=["a"])),
regions=dict(br=dict(children=["a"])),
partitions=dict(
a=dict(
type="allen",
Expand Down

0 comments on commit b0714eb

Please sign in to comment.