Skip to content

Commit

Permalink
Fix compatibility with pydantic v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Kircheneer committed Aug 18, 2023
1 parent eac352b commit be92683
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 27 deletions.
11 changes: 6 additions & 5 deletions diffsync/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,13 @@ class DiffSyncModel(BaseModel):
"""Message, if any, associated with the create/update/delete status value."""
model_config = ConfigDict(arbitrary_types_allowed=True)

def __init_subclass__(cls) -> None:
@classmethod
def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:
"""Validate that the various class attribute declarations correspond to actual instance fields.
Called automatically on subclass declaration.
"""
variables = cls.__fields__.keys()
variables = cls.model_fields
# Make sure that any field referenced by name actually exists on the model
for attr in cls._identifiers:
if attr not in variables and not hasattr(cls, attr):
Expand Down Expand Up @@ -142,15 +143,15 @@ def dict(self, **kwargs: Any) -> Dict:
"""Convert this DiffSyncModel to a dict, excluding the diffsync field by default as it is not serializable."""
if "exclude" not in kwargs:
kwargs["exclude"] = {"diffsync"}
return super().dict(**kwargs)
return super().model_dump(**kwargs)

def json(self, **kwargs: Any) -> StrType:
"""Convert this DiffSyncModel to a JSON string, excluding the diffsync field by default as it is not serializable."""
if "exclude" not in kwargs:
kwargs["exclude"] = {"diffsync"}
if "exclude_defaults" not in kwargs:
kwargs["exclude_defaults"] = True
return super().json(**kwargs)
return super().model_dump_json(**kwargs)

def str(self, include_children: bool = True, indent: int = 0) -> StrType:
"""Build a detailed string representation of this DiffSyncModel and optionally its children."""
Expand Down Expand Up @@ -850,4 +851,4 @@ def count(self, model: Union[StrType, "DiffSyncModel", Type["DiffSyncModel"], No


# DiffSyncModel references DiffSync and DiffSync references DiffSyncModel. Break the typing loop:
DiffSyncModel.update_forward_refs()
DiffSyncModel.model_rebuild()
6 changes: 3 additions & 3 deletions examples/01-multiple-data-sources/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class Device(DiffSyncModel):
_children = {"interface": "interfaces"}

name: str
site_name: Optional[str] # note that this attribute is NOT included in _attributes
role: Optional[str] # note that this attribute is NOT included in _attributes
site_name: Optional[str] = None # note that this attribute is NOT included in _attributes
role: Optional[str] = None # note that this attribute is NOT included in _attributes
interfaces: List = []


Expand All @@ -56,4 +56,4 @@ class Interface(DiffSyncModel):
name: str
device_name: str

description: Optional[str]
description: Optional[str] = None
2 changes: 1 addition & 1 deletion examples/03-remote-system/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ class Country(DiffSyncModel):
slug: str
name: str
region: str
population: Optional[int]
population: Optional[int] = 0
6 changes: 3 additions & 3 deletions examples/04-get-update-instantiate/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class Device(DiffSyncModel):
_children = {"interface": "interfaces", "site": "sites"}

name: str
site_name: Optional[str] # note that this attribute is NOT included in _attributes
role: Optional[str] # note that this attribute is NOT included in _attributes
site_name: Optional[str] = None # note that this attribute is NOT included in _attributes
role: Optional[str] = None # note that this attribute is NOT included in _attributes
interfaces: List = []
sites: List = []

Expand All @@ -55,4 +55,4 @@ class Interface(DiffSyncModel):
name: str
device_name: str

description: Optional[str]
description: Optional[str] = None
12 changes: 6 additions & 6 deletions examples/05-nautobot-peeringdb/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class RegionModel(DiffSyncModel):
# Data type declarations for all identifiers and attributes
name: str
slug: str
description: Optional[str]
parent_name: Optional[str] # may be None
description: Optional[str] = None
parent_name: Optional[str] = None
sites: List = []

# Not in _attributes or _identifiers, hence not included in diff calculations
Expand All @@ -49,10 +49,10 @@ class SiteModel(DiffSyncModel):
name: str
slug: str
status_slug: str
region_name: Optional[str] # may be None
description: Optional[str]
latitude: Optional[float]
longitude: Optional[float]
region_name: Optional[str] = None
description: Optional[str] = None
latitude: Optional[float] = None
longitude: Optional[float] = None

# Not in _attributes or _identifiers, hence not included in diff calculations
pk: Optional[Union[UUID, int]]
6 changes: 3 additions & 3 deletions examples/06-ip-prefixes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ class Prefix(DiffSyncModel):
_attributes = ("vrf", "vlan_id", "tenant")

prefix: str
vrf: Optional[str]
vlan_id: Optional[int]
tenant: Optional[str]
vrf: Optional[str] = None
vlan_id: Optional[int] = None
tenant: Optional[str] = None
4 changes: 2 additions & 2 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class Device(DiffSyncModel):
_children = {"interface": "interfaces"}

name: str
site_name: Optional[str] # note this is not included in _attributes
site_name: Optional[str] = None # note this is not included in _attributes
role: str
interfaces: List = []

Expand Down Expand Up @@ -143,7 +143,7 @@ class Interface(DiffSyncModel):
name: str

interface_type: str = "ethernet"
description: Optional[str]
description: Optional[str] = None


@pytest.fixture
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/test_diffsync_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def test_diffsync_model_dict_with_data(make_interface):
def test_diffsync_model_json_with_data(make_interface):
intf = make_interface()
# json() omits default values for brevity
assert intf.json() == '{"device_name": "device1", "name": "eth0"}'
assert intf.json() == '{"device_name":"device1","name":"eth0"}'


def test_diffsync_model_str_with_data(make_interface):
Expand Down Expand Up @@ -182,7 +182,7 @@ def test_diffsync_model_json_with_children(generic_diffsync, make_site, make_dev
generic_diffsync.add(site1)
generic_diffsync.add(device1)

assert site1.json() == '{"name": "site1", "devices": ["device1"]}'
assert site1.json() == '{"name":"site1","devices":["device1"]}'


def test_diffsync_model_str_with_children(generic_diffsync, make_site, make_device, make_interface):
Expand Down Expand Up @@ -294,7 +294,7 @@ class BadAttributes(DiffSyncModel):

name: str
# Note that short_name doesn't have a type annotation - making sure this works too
short_name = "short_name"
short_name: str = "short_name"

assert "_attributes" in str(excinfo.value)
assert "my_attr" in str(excinfo.value)
Expand All @@ -310,7 +310,7 @@ class BadChildren(DiffSyncModel):
_children = {"device": "devices"}

name: str
short_name = "short_name"
short_name: str = "short_name"
my_attr: int = 0

assert "_children" in str(excinfo.value)
Expand Down

0 comments on commit be92683

Please sign in to comment.