Skip to content

Commit db002cf

Browse files
committed
feat(sw360_objects): better __repr__ and __str__
This allows for easy copy'n'pasting of an object in interactive sessions plus nicer print output.
1 parent d72c2fa commit db002cf

File tree

4 files changed

+98
-15
lines changed

4 files changed

+98
-15
lines changed

sw360/sw360_objects.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,20 @@ def from_json(self, json, copy_attributes=list(), snake_case=True):
102102
else:
103103
self.details[key] = value
104104

105+
def __repr__(self):
106+
repr_ = []
107+
for k, v in self.__dict__.items():
108+
if v is None:
109+
continue
110+
if (k in ("name", "version", "filename", "attachment_type")
111+
or k.endswith("_id")):
112+
repr_.append(f'{k}={v!r}')
113+
if k == "id":
114+
repr_.append(f'{self.__class__.__name__.lower()}_id={v!r}')
115+
return (f'{self.__class__.__name__}('
116+
+ ", ".join(repr_)
117+
+ ")")
118+
105119

106120
class Release(SW360Resource):
107121
"""A release is the SW360 abstraction for a single version of a component.
@@ -129,11 +143,12 @@ class Release(SW360Resource):
129143
:type kwargs: dictionary
130144
"""
131145
def __init__(self, json=None, release_id=None, component_id=None,
132-
version=None, downloadurl=None, sw360=None, **kwargs):
146+
name=None, version=None, downloadurl=None, sw360=None, **kwargs):
133147
self.attachments = {}
134148

135-
self.component_id = component_id
149+
self.name = name
136150
self.version = version
151+
self.component_id = component_id
137152
self.downloadurl = downloadurl
138153
super().__init__(json, release_id, sw360=sw360, **kwargs)
139154

@@ -166,9 +181,8 @@ def get_component(self, sw360=None):
166181
self.sw360 = sw360
167182
return Component().get(self.sw360, self.component_id)
168183

169-
def __repr__(self):
170-
"""Representation string."""
171-
return "<Release %s %s id:%s>" % (self.name, self.version, self.id)
184+
def __str__(self):
185+
return f'{self.name} {self.version} ({self.id})'
172186

173187

174188
class Attachment(SW360Resource):
@@ -207,9 +221,9 @@ class Attachment(SW360Resource):
207221
def __init__(self, json=None, attachment_id=None, resources={},
208222
filename=None, sha1=None, attachment_type=None, sw360=None, **kwargs):
209223
self.resources = resources
224+
self.attachment_type = attachment_type
210225
self.filename = filename
211226
self.sha1 = sha1
212-
self.attachment_type = attachment_type
213227
self.download_link = None
214228
super().__init__(json, attachment_id, sw360, **kwargs)
215229

@@ -261,9 +275,8 @@ def download(self, target_path, filename=None):
261275
self.sw360.download_attachment(os.path.join(target_path, filename),
262276
self.download_link)
263277

264-
def __repr__(self):
265-
"""Representation string."""
266-
return "<Attachment %s id:%s>" % (self.filename, self.id)
278+
def __str__(self):
279+
return f'{self.filename} ({self.id})'
267280

268281

269282
class Component(SW360Resource):
@@ -332,9 +345,8 @@ def get(self, sw360=None, id_=None):
332345
self.from_json(self.sw360.get_component(self.id))
333346
return self
334347

335-
def __repr__(self):
336-
"""Representation string."""
337-
return "<Component %s id:%s>" % (self.name, self.id)
348+
def __str__(self):
349+
return f'{self.name} ({self.id})'
338350

339351

340352
class Project(SW360Resource):
@@ -408,6 +420,5 @@ def get(self, sw360=None, id_=None):
408420
self.from_json(self.sw360.get_project(self.id))
409421
return self
410422

411-
def __repr__(self):
412-
"""Representation string."""
413-
return "<Project %s id:%s>" % (self.name, self.id)
423+
def __str__(self):
424+
return f'{self.name} {self.version} ({self.id})'

tests/test_sw360obj_component.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@
55

66

77
class Sw360ObjTestComponent(Sw360ObjTestBase):
8+
def test_repr(self):
9+
comp = Component(component_id="123", name="TestCmp", homepage="http://www",
10+
component_type="INTERNAL")
11+
comp = eval(repr(comp))
12+
assert comp.id == "123"
13+
assert comp.name == "TestCmp"
14+
self.assertEqual(str(comp), "TestCmp (123)")
15+
16+
comp = Component()
17+
comp = eval(repr(comp))
18+
assert comp.id is None
19+
assert comp.name is None
20+
821
@responses.activate
922
def test_get_component(self):
1023
responses.add(

tests/test_sw360obj_project.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@
55

66

77
class Sw360ObjTestProject(Sw360ObjTestBase):
8+
def test_repr(self):
9+
prj = Project(project_id="123", name="TestPrj", version="12")
10+
prj = eval(repr(prj))
11+
assert prj.id == "123"
12+
assert prj.name == "TestPrj"
13+
assert prj.version == "12"
14+
self.assertEqual(str(prj), "TestPrj 12 (123)")
15+
16+
prj = Project()
17+
prj = eval(repr(prj))
18+
assert prj.id is None
19+
assert prj.name is None
20+
821
@responses.activate
922
def test_get_project(self):
1023
responses.add(
@@ -25,6 +38,8 @@ def test_get_project(self):
2538
self.assertEqual(len(proj.releases), 1)
2639
self.assertIsNone(proj.releases["7c4"].component_id)
2740

41+
self.assertEqual(str(proj), "MyProj 11.0 (123)")
42+
2843

2944
if __name__ == "__main__":
3045
unittest.main()

tests/test_sw360obj_release.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import responses
2+
import unittest
3+
from tests.test_sw360obj_base import Sw360ObjTestBase, SW360_BASE_URL
4+
from sw360 import Release
5+
6+
7+
class Sw360ObjTestRelease(Sw360ObjTestBase):
8+
def test_repr(self):
9+
r = Release(release_id="123", name="TestCmp", version="1.4",
10+
component_id="456", downloadurl="http://www")
11+
12+
r = eval(repr(r))
13+
assert r.id == "123"
14+
assert r.name == "TestCmp"
15+
assert r.version == "1.4"
16+
self.assertEqual(str(r), "TestCmp 1.4 (123)")
17+
18+
r = Release()
19+
r = eval(repr(r))
20+
assert r.id is None
21+
assert r.name is None
22+
assert r.version is None
23+
24+
@responses.activate
25+
def test_get_release(self):
26+
responses.add(
27+
responses.GET,
28+
SW360_BASE_URL + "releases/123",
29+
json={
30+
'name': 'acl',
31+
'version': '1.4',
32+
'somekey': 'value',
33+
'_links': {
34+
'sw360:component': {
35+
'href': SW360_BASE_URL + 'components/7b4'}}})
36+
r = Release().get(self.lib, "123")
37+
self.assertEqual(r.name, "acl")
38+
self.assertEqual(r.details["somekey"], "value")
39+
self.assertEqual(len(r.purls), 0)
40+
self.assertEqual(r.component_id, "7b4")
41+
42+
43+
if __name__ == "__main__":
44+
unittest.main()

0 commit comments

Comments
 (0)