Skip to content

Commit d2b9f8b

Browse files
committed
UserDict - no reason was given for reimplementing a core Python data structure. Furthermore, the custom AttrDict doesn't JSON serialize so an object built from JSON cannot be serialized back to JSON.
**BREAKS BACKWARD COMPATIBILITY.** This is now a real Python dictionary and *no longer has attribute access* for the data. This could be added back, but it's un-pythonic and introduces complexity. UserDict retains the ability to access `data`. The `dict` property is gone.
1 parent cc249ef commit d2b9f8b

2 files changed

Lines changed: 34 additions & 99 deletions

File tree

embedly/models.py

Lines changed: 9 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,16 @@
1-
"""
2-
Models
3-
4-
Creates a sudo model class that makes it easy to access attributes
5-
"""
61
from __future__ import unicode_literals
7-
class AttrDict(object):
8-
"""
9-
UserDict is a pain in the ass. Let's just make our own.
10-
"""
11-
def __init__(self, data=None):
12-
if data is None:
13-
data = {}
14-
15-
for key, value in data.items():
16-
if isinstance(value, dict):
17-
data[key] = AttrDict(value)
18-
elif isinstance(value, list):
19-
values = []
20-
for v in value:
21-
if isinstance(v, dict):
22-
values.append(AttrDict(v))
23-
else:
24-
values.append(v)
25-
data[key] = values
26-
27-
self.data = data
28-
29-
def __getattr__(self, name):
30-
if name in ['data', 'method']:
31-
return object.__getattr__(self, name)
32-
try:
33-
return self.data[name]
34-
except KeyError as e:
35-
return None
2+
from UserDict import IterableUserDict
363

37-
def __setattr__(self, name, value):
38-
if name in ['data', 'method']:
39-
object.__setattr__(self, name, value)
40-
else:
41-
self.data[name] = value
424

43-
def __getitem__(self, name): return self.data[name]
44-
def __setitem__(self, name, value): self.data[name] = value
45-
def __delitem__(self, name): del self.data[name]
46-
def __len__(self): return len(self.data)
47-
def get(self, name): return self.data.get(name)
48-
def keys(self): return self.data.keys()
49-
def values(self): return self.data.values()
50-
def items(self): return self.data.items()
51-
52-
@property
53-
def dict(self):
54-
return self.data
55-
56-
57-
class Url(AttrDict):
5+
class Url(IterableUserDict, object):
6+
"""
7+
A dictionary with two additional attributes for the method and url.
8+
UserDict provides a dictionary interface along with the regular
9+
dictionary accsesible via the `data` attribute.
5810
59-
def __init__(self, data=None, method=None, original_url=None):
60-
if data is None:
61-
data = {}
62-
super(Url, self).__init__(data)
11+
"""
12+
def __init__(self, data=None, method=None, original_url=None, **kwargs):
13+
super(Url, self).__init__(data, **kwargs)
6314
self.method = method or 'url'
6415
self.original_url = original_url
6516

embedly/tests.py

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -49,30 +49,14 @@ def test_model(self):
4949
self.assertTrue(len(obj.keys()) is 17)
5050
self.assertTrue(len(obj.items()) is 17)
5151

52+
# check for expected data
5253
self.assertTrue('type' in obj.keys())
5354
self.assertTrue('html' in obj.values())
55+
self.assertEqual(obj['type'], 'html')
56+
self.assertEqual(obj.get('type'), 'html')
57+
self.assertEqual(obj.data['type'], 'html')
58+
self.assertEqual(obj.data.get('type'), 'html')
5459

55-
#Get the object
56-
self.assertTrue(obj.type == 'html')
57-
self.assertTrue(obj['type'] == 'html')
58-
self.assertTrue(obj.get('type') == 'html')
59-
60-
#nope
61-
self.assertTrue(obj.nothing is None)
62-
63-
obj.nothing = 'something'
64-
self.assertTrue(obj.nothing == 'something')
65-
66-
obj['nothing'] = 'maybe'
67-
self.assertTrue(obj['nothing'] == 'maybe')
68-
69-
del obj['nothing']
70-
self.assertTrue(obj.nothing is None)
71-
72-
#Deep Get attrs
73-
self.assertTrue(obj.images[0].width is 275)
74-
self.assertTrue(obj.images[0].nothing is None)
75-
self.assertTrue(obj.object.type is None)
7660
def test_model_data_can_serialize(self):
7761
obj = Url({'a': {'key': 'value'}})
7862
unserialzed = json.loads(json.dumps(obj.data))
@@ -82,62 +66,62 @@ def test_provider(self):
8266
http = Embedly(self.key)
8367

8468
obj = http.oembed('http://www.scribd.com/doc/13994900/Easter')
85-
self.assertTrue(obj.provider_url == 'http://www.scribd.com/')
69+
self.assertEqual(obj['provider_url'], 'http://www.scribd.com/')
8670

8771
obj = http.oembed('http://www.scribd.com/doc/28452730/Easter-Cards')
88-
self.assertTrue(obj.provider_url == 'http://www.scribd.com/')
72+
self.assertEqual(obj['provider_url'], 'http://www.scribd.com/')
8973

9074
obj = http.oembed('http://www.youtube.com/watch?v=Zk7dDekYej0')
91-
self.assertTrue(obj.provider_url == 'http://www.youtube.com/')
75+
self.assertEqual(obj['provider_url'], 'http://www.youtube.com/')
9276

9377
obj = http.oembed('http://yfrog.com/h22eu4j')
94-
self.assertTrue(obj.provider_url == 'http://yfrog.com')
78+
self.assertEqual(obj['provider_url'], 'http://yfrog.com')
9579

9680
def test_providers(self):
9781
http = Embedly(self.key)
9882

9983
objs = list(http.oembed(['http://www.scribd.com/doc/13994900/Easter',
10084
'http://www.scribd.com/doc/28452730/Easter-Cards']))
101-
self.assertTrue(objs[0].provider_url == 'http://www.scribd.com/')
102-
self.assertTrue(objs[1].provider_url == 'http://www.scribd.com/')
85+
self.assertEqual(objs[0]['provider_url'], 'http://www.scribd.com/')
86+
self.assertEqual(objs[1]['provider_url'], 'http://www.scribd.com/')
10387

10488
objs = list(http.oembed(['http://www.youtube.com/watch?v=Zk7dDekYej0',
10589
'http://yfrog.com/h22eu4']))
106-
self.assertTrue(objs[0].provider_url == 'http://www.youtube.com/')
107-
self.assertTrue(objs[1].provider_url == 'http://yfrog.com')
90+
self.assertEqual(objs[0]['provider_url'], 'http://www.youtube.com/')
91+
self.assertEqual(objs[1]['provider_url'], 'http://yfrog.com')
10892

10993
def test_error(self):
11094
http = Embedly(self.key)
11195

11296
obj = http.oembed('http://www.embedly.com/this/is/a/bad/url')
113-
self.assertTrue(obj.error is True, obj.dict)
97+
self.assertTrue(obj['error'])
11498
obj = http.oembed('http://blog.embed.ly/lsbsdlfldsf/asdfkljlas/klajsdlfkasdf')
115-
self.assertTrue(obj.error is True, obj.dict)
99+
self.assertTrue(obj['error'])
116100
obj = http.oembed('http://twitpic/nothing/to/see/here')
117-
self.assertTrue(obj.error is True, obj.dict)
101+
self.assertTrue(obj['error'])
118102

119103
def test_multi_errors(self):
120104
http = Embedly(self.key)
121105

122106
objs = list(http.oembed(['http://www.embedly.com/this/is/a/bad/url',
123107
'http://blog.embed.ly/alsd/slsdlf/asdlfj']))
124-
self.assertTrue(objs[0].type == 'error', objs[0].dict)
125-
self.assertTrue(objs[1].type == 'error', objs[1].dict)
108+
self.assertEqual(objs[0]['type'], 'error')
109+
self.assertEqual(objs[1]['type'], 'error')
126110

127111
objs = list(http.oembed(['http://blog.embed.ly/lsbsdlfldsf/asdf/kl',
128112
'http://twitpic.com/nothing/to/see/here']))
129-
self.assertTrue(objs[0].type == 'error',objs[0].dict)
130-
self.assertTrue(objs[1].type == 'error',objs[1].dict)
113+
self.assertEqual(objs[0]['type'], 'error')
114+
self.assertEqual(objs[1]['type'], 'error')
131115

132116
objs = list(http.oembed(['http://blog.embed.ly/lsbsdlfldsf/asdf/kl',
133117
'http://yfrog.com/h22eu4j']))
134-
self.assertTrue(objs[0].type == 'error',objs[0].dict)
135-
self.assertTrue(objs[1].type == 'photo',objs[1].dict)
118+
self.assertEqual(objs[0]['type'], 'error')
119+
self.assertEqual(objs[1]['type'], 'photo')
136120

137121
objs = list(http.oembed(['http://yfrog.com/h22eu4j',
138122
'http://www.scribd.com/asdf/asdf/asdfasdf']))
139-
self.assertTrue(objs[0].type == 'photo',objs[0].dict)
140-
self.assertTrue(objs[1].type == 'error',objs[1].dict)
123+
self.assertEqual(objs[0]['type'], 'photo')
124+
self.assertEqual(objs[1]['type'], 'error')
141125

142126
def test_too_many_urls(self):
143127
http = Embedly(self.key)
@@ -151,4 +135,4 @@ def test_too_many_urls(self):
151135

152136

153137
if __name__ == '__main__':
154-
unittest.main()
138+
unittest.main()

0 commit comments

Comments
 (0)