Skip to content

Commit 4596499

Browse files
committed
Fix compatibility with pydantic v2
1 parent f7275c1 commit 4596499

File tree

8 files changed

+31
-31
lines changed

8 files changed

+31
-31
lines changed

diffsync/__init__.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,24 +106,24 @@ class DiffSyncModel(BaseModel):
106106
"""Message, if any, associated with the create/update/delete status value."""
107107
model_config = ConfigDict(arbitrary_types_allowed=True)
108108

109-
def __init_subclass__(cls) -> None:
109+
@classmethod
110+
def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:
110111
"""Validate that the various class attribute declarations correspond to actual instance fields.
111112
112113
Called automatically on subclass declaration.
113114
"""
114-
variables = cls.__fields__.keys()
115115
# Make sure that any field referenced by name actually exists on the model
116116
for attr in cls._identifiers:
117-
if attr not in variables and not hasattr(cls, attr):
117+
if attr not in cls.model_fields and not hasattr(cls, attr):
118118
raise AttributeError(f"_identifiers {cls._identifiers} references missing or un-annotated attr {attr}")
119119
for attr in cls._shortname:
120-
if attr not in variables:
120+
if attr not in cls.model_fields:
121121
raise AttributeError(f"_shortname {cls._shortname} references missing or un-annotated attr {attr}")
122122
for attr in cls._attributes:
123-
if attr not in variables:
123+
if attr not in cls.model_fields:
124124
raise AttributeError(f"_attributes {cls._attributes} references missing or un-annotated attr {attr}")
125125
for attr in cls._children.values():
126-
if attr not in variables:
126+
if attr not in cls.model_fields:
127127
raise AttributeError(f"_children {cls._children} references missing or un-annotated attr {attr}")
128128

129129
# Any given field can only be in one of (_identifiers, _attributes, _children)
@@ -147,15 +147,15 @@ def dict(self, **kwargs: Any) -> Dict:
147147
"""Convert this DiffSyncModel to a dict, excluding the diffsync field by default as it is not serializable."""
148148
if "exclude" not in kwargs:
149149
kwargs["exclude"] = {"diffsync"}
150-
return super().dict(**kwargs)
150+
return super().model_dump(**kwargs)
151151

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

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

856856

857857
# DiffSyncModel references DiffSync and DiffSync references DiffSyncModel. Break the typing loop:
858-
DiffSyncModel.update_forward_refs()
858+
DiffSyncModel.model_rebuild()

examples/01-multiple-data-sources/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class Device(DiffSyncModel):
4040
_children = {"interface": "interfaces"}
4141

4242
name: str
43-
site_name: Optional[str] # note that this attribute is NOT included in _attributes
44-
role: Optional[str] # note that this attribute is NOT included in _attributes
43+
site_name: Optional[str] = None # note that this attribute is NOT included in _attributes
44+
role: Optional[str] = None # note that this attribute is NOT included in _attributes
4545
interfaces: List = []
4646

4747

@@ -56,4 +56,4 @@ class Interface(DiffSyncModel):
5656
name: str
5757
device_name: str
5858

59-
description: Optional[str]
59+
description: Optional[str] = None

examples/03-remote-system/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ class Country(DiffSyncModel):
3232
slug: str
3333
name: str
3434
region: str
35-
population: Optional[int]
35+
population: Optional[int] = 0

examples/04-get-update-instantiate/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ class Device(DiffSyncModel):
3838
_children = {"interface": "interfaces", "site": "sites"}
3939

4040
name: str
41-
site_name: Optional[str] # note that this attribute is NOT included in _attributes
42-
role: Optional[str] # note that this attribute is NOT included in _attributes
41+
site_name: Optional[str] = None # note that this attribute is NOT included in _attributes
42+
role: Optional[str] = None # note that this attribute is NOT included in _attributes
4343
interfaces: List = []
4444
sites: List = []
4545

@@ -55,4 +55,4 @@ class Interface(DiffSyncModel):
5555
name: str
5656
device_name: str
5757

58-
description: Optional[str]
58+
description: Optional[str] = None

examples/05-nautobot-peeringdb/models.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class RegionModel(DiffSyncModel):
2121
# Data type declarations for all identifiers and attributes
2222
name: str
2323
slug: str
24-
description: Optional[str]
25-
parent_name: Optional[str] # may be None
24+
description: Optional[str] = None
25+
parent_name: Optional[str] = None
2626
sites: List = []
2727

2828
# Not in _attributes or _identifiers, hence not included in diff calculations
@@ -49,10 +49,10 @@ class SiteModel(DiffSyncModel):
4949
name: str
5050
slug: str
5151
status_slug: str
52-
region_name: Optional[str] # may be None
53-
description: Optional[str]
54-
latitude: Optional[float]
55-
longitude: Optional[float]
52+
region_name: Optional[str] = None
53+
description: Optional[str] = None
54+
latitude: Optional[float] = None
55+
longitude: Optional[float] = None
5656

5757
# Not in _attributes or _identifiers, hence not included in diff calculations
5858
pk: Optional[Union[UUID, int]]

examples/06-ip-prefixes/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ class Prefix(DiffSyncModel):
1111
_attributes = ("vrf", "vlan_id", "tenant")
1212

1313
prefix: str
14-
vrf: Optional[str]
15-
vlan_id: Optional[int]
16-
tenant: Optional[str]
14+
vrf: Optional[str] = None
15+
vlan_id: Optional[int] = None
16+
tenant: Optional[str] = None

tests/unit/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class Device(DiffSyncModel):
115115
_children = {"interface": "interfaces"}
116116

117117
name: str
118-
site_name: Optional[str] # note this is not included in _attributes
118+
site_name: Optional[str] = None # note this is not included in _attributes
119119
role: str
120120
interfaces: List = []
121121

@@ -143,7 +143,7 @@ class Interface(DiffSyncModel):
143143
name: str
144144

145145
interface_type: str = "ethernet"
146-
description: Optional[str]
146+
description: Optional[str] = None
147147

148148

149149
@pytest.fixture

tests/unit/test_diffsync_model.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def test_diffsync_model_dict_with_data(make_interface):
107107
def test_diffsync_model_json_with_data(make_interface):
108108
intf = make_interface()
109109
# json() omits default values for brevity
110-
assert intf.json() == '{"device_name": "device1", "name": "eth0"}'
110+
assert intf.json() == '{"device_name":"device1","name":"eth0"}'
111111

112112

113113
def test_diffsync_model_str_with_data(make_interface):
@@ -182,7 +182,7 @@ def test_diffsync_model_json_with_children(generic_diffsync, make_site, make_dev
182182
generic_diffsync.add(site1)
183183
generic_diffsync.add(device1)
184184

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

187187

188188
def test_diffsync_model_str_with_children(generic_diffsync, make_site, make_device, make_interface):
@@ -294,7 +294,7 @@ class BadAttributes(DiffSyncModel):
294294

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

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

312312
name: str
313-
short_name = "short_name"
313+
short_name: str = "short_name"
314314
my_attr: int = 0
315315

316316
assert "_children" in str(excinfo.value)

0 commit comments

Comments
 (0)