Skip to content

Commit a26b7e3

Browse files
authored
Merge pull request #1403 from compas-dev/fix-data-name
Fix bug in data copy name
2 parents d60c4c1 + 793a241 commit a26b7e3

File tree

3 files changed

+88
-11
lines changed

3 files changed

+88
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
* Added instructions for creating new data types to the dev guide.
13+
* Added `compact=False`, `minimal=False` to `compas.data.Data.to_json()` to `compas.data.Data.to_jsonstring()`.
14+
* Added `copy_guid=False` to `compas.data.Data.copy()`. If true, the copy has the same guid as the original.
1315

1416
### Changed
1517

16-
* Fixed `RuntimeError` when using `compas_rhino.unload_modules` in CPython`.
18+
* Fixed `RuntimeError` when using `compas_rhino.unload_modules` in CPython`.
1719
* Fixed bug in `Box.scaled` causing a `TypeError` due to incorrect parameter forwarding.
1820
* Changed argument names of `Box.scale()` to `x`, `y`, `z`, instead of `factor` and made `y` and `z` optional to keep positional arguments backwards compatible.
1921
* Fixed import errors in `compas_rhino.conduits` for Rhino 8.
2022
* Fixed doctest failures.
2123
* Fixed bug in serialization when `compas.datastructures.attributes.AttributeView` is used.
2224
* Fixed bug in the serialisation of empty scenes.
25+
* Fixed bug in serialisation process due to `name` attribute appearing in json representation after copy even if not present before copy.
2326

2427
### Removed
2528

src/compas/data/data.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,19 +210,22 @@ def from_json(cls, filepath): # type: (...) -> Data
210210
raise TypeError("The data in the file is not a {}.".format(cls))
211211
return data
212212

213-
def to_json(self, filepath, pretty=False):
213+
def to_json(self, filepath, pretty=False, compact=False, minimal=False):
214214
"""Convert an object to its native data representation and save it to a JSON file.
215215
216216
Parameters
217217
----------
218218
filepath : str
219219
The path to the JSON file.
220220
pretty : bool, optional
221-
If True, the JSON file will be pretty printed.
222-
Defaults to False.
221+
If True, format the output with newlines and indentation.
222+
compact : bool, optional
223+
If True, format the output without any whitespace.
224+
minimal : bool, optional
225+
If True, exclude the GUID from the JSON output.
223226
224227
"""
225-
compas.json_dump(self, filepath, pretty=pretty)
228+
compas.json_dump(self, filepath, pretty=pretty, compact=compact, minimal=minimal)
226229

227230
@classmethod
228231
def from_jsonstring(cls, string): # type: (...) -> Data
@@ -249,31 +252,36 @@ def from_jsonstring(cls, string): # type: (...) -> Data
249252
raise TypeError("The data in the string is not a {}.".format(cls))
250253
return data
251254

252-
def to_jsonstring(self, pretty=False):
255+
def to_jsonstring(self, pretty=False, compact=False, minimal=False):
253256
"""Convert an object to its native data representation and save it to a JSON string.
254257
255258
Parameters
256259
----------
257260
pretty : bool, optional
258-
If True, the JSON string will be pretty printed.
259-
Defaults to False.
261+
If True, format the output with newlines and indentation.
262+
compact : bool, optional
263+
If True, format the output without any whitespace.
264+
minimal : bool, optional
265+
If True, exclude the GUID from the JSON output.
260266
261267
Returns
262268
-------
263269
str
264270
The JSON string.
265271
266272
"""
267-
return compas.json_dumps(self, pretty=pretty)
273+
return compas.json_dumps(self, pretty=pretty, compact=compact, minimal=minimal)
268274

269-
def copy(self, cls=None): # type: (...) -> D
275+
def copy(self, cls=None, copy_guid=False): # type: (...) -> D
270276
"""Make an independent copy of the data object.
271277
272278
Parameters
273279
----------
274280
cls : Type[:class:`compas.data.Data`], optional
275281
The type of data object to return.
276282
Defaults to the type of the current data object.
283+
copy_guid : bool, optional
284+
If True, the copy will have the same guid as the original.
277285
278286
Returns
279287
-------
@@ -284,7 +292,10 @@ def copy(self, cls=None): # type: (...) -> D
284292
if not cls:
285293
cls = type(self)
286294
obj = cls.__from_data__(deepcopy(self.__data__))
287-
obj.name = self.name
295+
if self._name is not None:
296+
obj._name = self.name
297+
if copy_guid:
298+
obj._guid = self.guid
288299
return obj # type: ignore
289300

290301
def sha256(self, as_string=False):

tests/compas/data/test_copy.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from compas.data import Data
2+
3+
4+
class TestData(Data):
5+
@property
6+
def __data__(self):
7+
return {}
8+
9+
10+
def test_copy_noname():
11+
data = TestData()
12+
13+
assert data._name is None
14+
assert data.name == "TestData"
15+
16+
assert data.copy()._name is None
17+
assert data.copy().name == "TestData"
18+
19+
assert data.name == data.copy().name
20+
assert data.__dtype__ == data.copy().__dtype__
21+
22+
assert data.guid != data.copy().guid
23+
assert data.guid == data.copy(copy_guid=True).guid
24+
25+
assert data.__jsondump__() != data.copy().__jsondump__()
26+
assert data.__jsondump__() == data.copy(copy_guid=True).__jsondump__()
27+
28+
assert data.to_jsonstring() != data.copy().to_jsonstring()
29+
assert data.to_jsonstring() == data.copy(copy_guid=True).to_jsonstring()
30+
31+
assert data.__jsondump__(minimal=True) == data.copy().__jsondump__(minimal=True)
32+
assert data.__jsondump__(minimal=True) == data.copy(copy_guid=False).__jsondump__(minimal=True)
33+
34+
assert data.to_jsonstring(minimal=True) == data.copy().to_jsonstring(minimal=True)
35+
assert data.to_jsonstring(minimal=True) == data.copy(copy_guid=False).to_jsonstring(minimal=True)
36+
37+
38+
def test_copy():
39+
data = TestData(name="test")
40+
41+
assert data._name == "test"
42+
assert data.name == "test"
43+
44+
assert data.copy()._name == "test"
45+
assert data.copy().name == "test"
46+
47+
assert data.name == data.copy().name
48+
assert data.__dtype__ == data.copy().__dtype__
49+
50+
assert data.guid != data.copy().guid
51+
assert data.guid == data.copy(copy_guid=True).guid
52+
53+
assert data.__jsondump__() != data.copy().__jsondump__()
54+
assert data.__jsondump__() == data.copy(copy_guid=True).__jsondump__()
55+
56+
assert data.to_jsonstring() != data.copy().to_jsonstring()
57+
assert data.to_jsonstring() == data.copy(copy_guid=True).to_jsonstring()
58+
59+
assert data.__jsondump__(minimal=True) == data.copy().__jsondump__(minimal=True)
60+
assert data.__jsondump__(minimal=True) == data.copy(copy_guid=False).__jsondump__(minimal=True)
61+
62+
assert data.to_jsonstring(minimal=True) == data.copy().to_jsonstring(minimal=True)
63+
assert data.to_jsonstring(minimal=True) == data.copy(copy_guid=False).to_jsonstring(minimal=True)

0 commit comments

Comments
 (0)