Skip to content

Commit

Permalink
Allow __init__ kwargs to be assigned as object attributes in the de…
Browse files Browse the repository at this point in the history
…sign (#95)

* refactor: Test case refactoring

Refactored builder unit tests to make the tests clearer and easier to define. This should make it easier to have tests for different versions of Nautobot

* fix: Fixed error message construction

When constructing an error string there was an issue where another exception could render the string unreadable. This fix wraps the errant code with try/except to continue producing a usable error string.

* feat: Added the ability to mark YAML tests to be skipped

* test: Initial tests for Nautobot 2.0

* feat: Allow kwargs as design object attributes.
  • Loading branch information
abates authored Jan 22, 2024
1 parent b47028c commit 675f064
Show file tree
Hide file tree
Showing 29 changed files with 1,132 additions and 791 deletions.
5 changes: 5 additions & 0 deletions invoke.nautobot_2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
nautobot_design_builder:
project_name: "nautobot_design_builder_v2"
python_ver: "3.9"
nautobot_ver: "2.1"
12 changes: 10 additions & 2 deletions nautobot_design_builder/design.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ def __init__(
self.filter = {}
self.action = None
self.instance_fields = {}
self._kwargs = {}
for direction in Relationship.objects.get_for_model(model_class):
for relationship in direction:
self.instance_fields[relationship.slug] = field_factory(self, relationship)
Expand Down Expand Up @@ -225,7 +226,11 @@ def _parse_attributes(self): # pylint: disable=too-many-branches
raise errors.DesignImplementationError(f"{fieldname} is not a property", self.model_class)
self.attributes[fieldname] = {search: self.attributes.pop(key)}
elif not hasattr(self.model_class, key) and key not in self.instance_fields:
raise errors.DesignImplementationError(f"{key} is not a property", self.model_class)
value = self.creator.resolve_values(self.attributes.pop(key))
if isinstance(value, ModelInstance):
value = value.instance
self._kwargs[key] = value
# raise errors.DesignImplementationError(f"{key} is not a property", self.model_class)

if self.action is None:
self.action = self.CREATE
Expand Down Expand Up @@ -280,7 +285,10 @@ def _load_instance(self):
self.attributes.update(query_filter)
elif self.action != "create":
raise errors.DesignImplementationError(f"Unknown database action {self.action}", self.model_class)
self.instance = self.model_class()
try:
self.instance = self.model_class(**self._kwargs)
except TypeError as ex:
raise errors.DesignImplementationError(str(ex), self.model_class)

def _update_fields(self): # pylint: disable=too-many-branches
if self.action == self.GET and self.attributes:
Expand Down
20 changes: 18 additions & 2 deletions nautobot_design_builder/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,15 @@ def _model_str(model):
if not isinstance(model, Model) and not hasattr(model, "instance"):
if isclass(model):
return model.__name__
return str(model)
try:
return str(model)
except Exception: # pylint: disable=broad-exception-caught
# Sometimes when converting a model to a string the __str__
# method itself produces an exceptions, like when an attribute
# hasn't been set or something. Whatever it is commonly is
# the cause of the original exception, we don't want to
# cause *another* exception because of that.
return model.__class__.__name__

model_class = model.__class__
# if it looks like a duck...
Expand All @@ -63,7 +71,15 @@ def _model_str(model):
model = model.instance

if model:
instance_str = str(model)
try:
instance_str = str(model)
except Exception: # pylint: disable=broad-exception-caught
# Sometimes when converting a model to a string the __str__
# method itself produces an exceptions, like when an attribute
# hasn't been set or something. Whatever it is commonly is
# the cause of the original exception, we don't want to
# cause *another* exception because of that.
instance_str = model.__class__.__name__
model_str = model_class._meta.verbose_name.capitalize()
if instance_str:
model_str = f"{model_str} {instance_str}"
Expand Down
Loading

0 comments on commit 675f064

Please sign in to comment.