diff --git a/CHANGELOG.md b/CHANGELOG.md index b982428bc..795ac7b20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## neptune-client 0.16.15 + +### Fixes +- Correct detection of missing attributes ([#1155](https://github.com/neptune-ai/neptune-client/pull/1155)) + ## neptune-client 0.16.14 ### Features diff --git a/src/neptune/new/handler.py b/src/neptune/new/handler.py index 0f89ab93c..7cf6689a4 100644 --- a/src/neptune/new/handler.py +++ b/src/neptune/new/handler.py @@ -167,7 +167,7 @@ def assign(self, value, wait: bool = False) -> None: """ with self._container.lock(): attr = self._container.get_attribute(self._path) - if not attr: + if attr is None: self._container.define(self._path, value) else: if isinstance(value, Handler): @@ -210,7 +210,7 @@ def upload(self, value, wait: bool = False) -> None: with self._container.lock(): attr = self._container.get_attribute(self._path) - if not attr: + if attr is None: attr = File(self._container, parse_path(self._path)) self._container.set_attribute(self._path, attr) attr.upload(value, wait) @@ -224,7 +224,7 @@ def upload_files(self, value: Union[str, Iterable[str]], wait: bool = False) -> with self._container.lock(): attr = self._container.get_attribute(self._path) - if not attr: + if attr is None: attr = FileSet(self._container, parse_path(self._path)) self._container.set_attribute(self._path, attr) attr.upload_files(value, wait) @@ -267,7 +267,7 @@ def log( with self._container.lock(): attr = self._container.get_attribute(self._path) - if not attr: + if attr is None: if is_collection(value): if value: first_value = next(iter(value)) @@ -387,7 +387,7 @@ def extend( with self._container.lock(): attr = self._container.get_attribute(self._path) - if not attr: + if attr is None: neptune_value = cast_value_for_extend(values) attr = ValueToAttributeVisitor(self._container, parse_path(self._path)).visit(neptune_value) self._container.set_attribute(self._path, attr) @@ -414,7 +414,7 @@ def add(self, values: Union[str, Iterable[str]], wait: bool = False) -> None: verify_type("values", values, (str, Iterable)) with self._container.lock(): attr = self._container.get_attribute(self._path) - if not attr: + if attr is None: attr = StringSet(self._container, parse_path(self._path)) self._container.set_attribute(self._path, attr) attr.add(values, wait) @@ -623,7 +623,7 @@ def track_files(self, path: str, destination: str = None, wait: bool = False) -> """ with self._container.lock(): attr = self._container.get_attribute(self._path) - if not attr: + if attr is None: attr = Artifact(self._container, parse_path(self._path)) self._container.set_attribute(self._path, attr) diff --git a/tests/unit/neptune/new/test_experiment.py b/tests/unit/neptune/new/test_experiment.py index 995fa556e..6406acc4b 100644 --- a/tests/unit/neptune/new/test_experiment.py +++ b/tests/unit/neptune/new/test_experiment.py @@ -102,6 +102,13 @@ def test_define_conflict(self): with self.assertRaises(MetadataInconsistency): exp.define("some/path/value", Float(1)) + def test_define_conflict_with_empty_namespace(self): + for exp in self.get_experiments(flush_period=0.5): + with self.subTest(msg=f"For type {exp.container_type}"): + exp.define("some/path/value", {}) + with self.assertRaises(MetadataInconsistency): + exp.define("some/path/value", {}) + def test_pop(self): for exp in self.get_experiments(flush_period=0.5): with self.subTest(msg=f"For type {exp.container_type}"): diff --git a/tests/unit/neptune/new/test_handler.py b/tests/unit/neptune/new/test_handler.py index c0ef0e9ad..66d3ccca2 100644 --- a/tests/unit/neptune/new/test_handler.py +++ b/tests/unit/neptune/new/test_handler.py @@ -491,6 +491,12 @@ def test_assign_dict(self): self.assertEqual(exp["params/toys"].fetch_last(), "hat") self.assertEqual(exp["params/nested/nested/deep_secret"].fetch_last(), 15) + def test_assign_empty_dict(self): + with init_run(mode="debug", flush_period=0.5) as exp: + exp["params"] = {} + exp["params"] = {"foo": 5} + self.assertEqual(exp["params/foo"].fetch(), 5) + def test_argparse_namespace(self): with init_run(mode="debug", flush_period=0.5) as exp: exp["params"] = argparse.Namespace(