Skip to content

Commit 4eda8bc

Browse files
committed
Fix multidict coverage
1 parent 3846bb7 commit 4eda8bc

File tree

4 files changed

+69
-84
lines changed

4 files changed

+69
-84
lines changed

.coveragerc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ omit = site-packages
66
[report]
77
exclude_lines =
88
@abc.
9+
pragma: no cover
910

1011
[html]
1112
directory = coverage

aiohttp/_multidict.pyx

Lines changed: 24 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ class upstr(str):
1515
val = str(val, encoding, errors)
1616
elif isinstance(val, str):
1717
pass
18-
elif hasattr(val, '__str__'):
19-
val = val.__str__()
2018
else:
21-
val = repr(val)
19+
val = str(val)
2220
val = val.upper()
2321
return str.__new__(cls, val)
2422

@@ -109,53 +107,30 @@ cdef class _Base:
109107
body = ', '.join("'{}': {!r}".format(k, v) for k, v in self.items())
110108
return '<{} {{{}}}>'.format(self.__class__.__name__, body)
111109

112-
113-
114-
115-
116-
cdef class MultiDictProxy(_Base):
117-
118-
def __init__(self, arg):
119-
cdef MultiDict mdict
120-
if not isinstance(arg, MultiDict):
121-
raise TypeError(
122-
'MultiDictProxy requires MultiDict instance, not {}'.format(
123-
type(arg)))
124-
125-
mdict = arg
126-
self._items = mdict._items
127-
128-
def copy(self):
129-
return MultiDict(self._items)
130-
131110
def __richcmp__(self, other, op):
132-
cdef MultiDictProxy typed_self = self
133-
cdef MultiDictProxy typed_other
111+
cdef _Base typed_self
112+
cdef _Base typed_other
134113
cdef tuple item
135114
if op == 2:
136-
if isinstance(other, MultiDictProxy):
137-
typed_other = other
138-
return typed_self._items == typed_other._items
139-
elif isinstance(other, MultiDict):
115+
if isinstance(self, _Base) and isinstance(other, _Base):
116+
typed_self = self
140117
typed_other = other
141118
return typed_self._items == typed_other._items
142119
elif not isinstance(other, abc.Mapping):
143120
return NotImplemented
144-
for item in typed_self._items:
121+
for item in self.items():
145122
nv = other.get(item[0], _marker)
146123
if item[1] != nv:
147124
return False
148125
return True
149126
elif op != 2:
150-
if isinstance(other, MultiDictProxy):
127+
if isinstance(self, _Base) and isinstance(other, _Base):
128+
typed_self = self
151129
typed_other = other
152130
return typed_self._items != typed_other._items
153-
elif isinstance(other, MultiDict):
154-
typed_other = other
155-
return typed_self._items == typed_other._items
156131
elif not isinstance(other, abc.Mapping):
157132
return NotImplemented
158-
for item in typed_self._items:
133+
for item in self.items():
159134
nv = other.get(item[0], _marker)
160135
if item[1] == nv:
161136
return True
@@ -164,6 +139,21 @@ cdef class MultiDictProxy(_Base):
164139
return NotImplemented
165140

166141

142+
cdef class MultiDictProxy(_Base):
143+
144+
def __init__(self, arg):
145+
cdef MultiDict mdict
146+
if not isinstance(arg, MultiDict):
147+
raise TypeError(
148+
'MultiDictProxy requires MultiDict instance, not {}'.format(
149+
type(arg)))
150+
151+
mdict = arg
152+
self._items = mdict._items
153+
154+
def copy(self):
155+
return MultiDict(self._items)
156+
167157
abc.Mapping.register(MultiDictProxy)
168158

169159

@@ -322,36 +312,6 @@ cdef class MultiDict(_Base):
322312
def update(self, *args, **kwargs):
323313
self._extend(args, kwargs, "update", 0)
324314

325-
def __richcmp__(self, other, op):
326-
cdef MultiDict typed_self = self
327-
cdef MultiDict typed_other
328-
cdef tuple item
329-
if op == 2:
330-
if isinstance(other, MultiDict):
331-
typed_other = other
332-
return typed_self._items == typed_other._items
333-
elif not isinstance(other, abc.Mapping):
334-
return NotImplemented
335-
for item in typed_self._items:
336-
nv = other.get(item[0], _marker)
337-
if item[1] != nv:
338-
return False
339-
return True
340-
elif op != 2:
341-
if isinstance(other, MultiDict):
342-
typed_other = other
343-
return typed_self._items == typed_other._items
344-
elif not isinstance(other, abc.Mapping):
345-
return NotImplemented
346-
for item in typed_self._items:
347-
nv = other.get(item[0], _marker)
348-
if item[1] == nv:
349-
return True
350-
return False
351-
else:
352-
return NotImplemented
353-
354-
355315

356316
abc.MutableMapping.register(MultiDict)
357317

aiohttp/multidict.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ def __new__(cls, val='',
1616
val = str(val, encoding, errors)
1717
elif isinstance(val, str):
1818
pass
19-
elif hasattr(val, '__str__'):
20-
val = val.__str__()
2119
else:
22-
val = repr(val)
20+
val = str(val)
2321
val = val.upper()
2422
return str.__new__(cls, val)
2523

@@ -79,9 +77,7 @@ def values(self):
7977
def __eq__(self, other):
8078
if not isinstance(other, abc.Mapping):
8179
return NotImplemented
82-
if isinstance(other, _MultiDictProxy):
83-
return self._items == other._items
84-
elif isinstance(other, _MultiDict):
80+
if isinstance(other, _Base):
8581
return self._items == other._items
8682
for k, v in self.items():
8783
nv = other.get(k, _marker)
@@ -200,11 +196,7 @@ def clear(self):
200196
# Mapping interface #
201197

202198
def __setitem__(self, key, value):
203-
try:
204-
del self[key]
205-
except KeyError:
206-
pass
207-
self._items.append((key, value))
199+
self._replace(key, value)
208200

209201
def __delitem__(self, key):
210202
items = self._items
@@ -327,7 +319,7 @@ def __iter__(self):
327319
MultiDict,
328320
CIMultiDict,
329321
upstr)
330-
except ImportError:
322+
except ImportError: # pragma: no cover
331323
MultiDictProxy = _MultiDictProxy
332324
CIMultiDictProxy = _CIMultiDictProxy
333325
MultiDict = _MultiDict

tests/test_multidict.py

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,15 @@ def test_extend(self):
395395
with self.assertRaises(TypeError):
396396
d.extend('foo', 'bar')
397397

398+
def test_extend_from_proxy(self):
399+
d = self.make_dict([('a', 'a'), ('b', 'b')])
400+
proxy = self.proxy_cls(d)
401+
402+
d2 = self.make_dict()
403+
d2.extend(proxy)
404+
405+
self.assertEqual([('a', 'a'), ('b', 'b')], list(d2.items()))
406+
398407
def test_clear(self):
399408
d = self.make_dict([('key', 'one')], key='two', foo='bar')
400409

@@ -564,6 +573,15 @@ def test_extend(self):
564573
with self.assertRaises(TypeError):
565574
d.extend('foo', 'bar')
566575

576+
def test_extend_from_proxy(self):
577+
d = self.make_dict([('a', 'a'), ('b', 'b')])
578+
proxy = self.proxy_cls(d)
579+
580+
d2 = self.make_dict()
581+
d2.extend(proxy)
582+
583+
self.assertEqual([('A', 'a'), ('B', 'b')], list(d2.items()))
584+
567585
def test_clear(self):
568586
d = self.make_dict([('KEY', 'one')], key='two', foo='bar')
569587

@@ -650,11 +668,13 @@ class TestPyCIMultiDictProxy(_TestCIProxy, unittest.TestCase):
650668
class PyMutableMultiDictTests(_BaseMutableMultiDictTests, unittest.TestCase):
651669

652670
cls = _MultiDict
671+
proxy_cls = _MultiDictProxy
653672

654673

655674
class PyCIMutableMultiDictTests(_CIMutableMultiDictTests, unittest.TestCase):
656675

657676
cls = _CIMultiDict
677+
proxy_cls = _CIMultiDictProxy
658678

659679

660680
class TestMultiDictProxy(_TestProxy, unittest.TestCase):
@@ -672,11 +692,13 @@ class TestCIMultiDictProxt(_TestCIProxy, unittest.TestCase):
672692
class MutableMultiDictTests(_BaseMutableMultiDictTests, unittest.TestCase):
673693

674694
cls = MultiDict
695+
proxy_cls = MultiDictProxy
675696

676697

677698
class CIMutableMultiDictTests(_CIMutableMultiDictTests, unittest.TestCase):
678699

679700
cls = CIMultiDict
701+
proxy_cls = CIMultiDictProxy
680702

681703

682704
class _UpStrMixin:
@@ -707,14 +729,6 @@ def test_upper(self):
707729
s = self.cls('a')
708730
self.assertIs(s, s.upper())
709731

710-
def test_upstr_is_not_str(self):
711-
712-
class A:
713-
def __repr__(self):
714-
return '<A repr>'
715-
716-
self.assertEqual('<A REPR>', self.cls(A()))
717-
718732

719733
class TestPyUpStr(_UpStrMixin, unittest.TestCase):
720734

@@ -742,6 +756,24 @@ def test_proxy_not_inherited_from_dict(self):
742756
def test_dict_not_inherited_from_proxy(self):
743757
self.assertFalse(issubclass(self.mdict, self.proxy))
744758

759+
def test_create_multidict_proxy_from_nonmultidict(self):
760+
with self.assertRaises(TypeError):
761+
self.proxy({})
762+
763+
def test_create_multidict_proxy_from_cimultidict(self):
764+
d = self.cimdict(key='val')
765+
p = self.proxy(d)
766+
self.assertEqual(p, d)
767+
768+
def test_create_cimultidict_proxy_from_nonmultidict(self):
769+
with self.assertRaises(TypeError):
770+
self.ciproxy({})
771+
772+
def test_create_ci_multidict_proxy_from_multidict(self):
773+
d = self.mdict(key='val')
774+
with self.assertRaises(TypeError):
775+
self.ciproxy(d)
776+
745777

746778
class TestPyTypes(TypesMixin, unittest.TestCase):
747779

0 commit comments

Comments
 (0)