Skip to content

Commit 9702c17

Browse files
committed
Use Mapping interface
1 parent 66f99cd commit 9702c17

File tree

2 files changed

+30
-11
lines changed

2 files changed

+30
-11
lines changed

pysass.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ static union Sass_Value* _to_sass_value(PyObject* value) {
139139
PyObject* sass_error_t = PyObject_GetAttrString(types_mod, "SassError");
140140
PyObject* sass_comma = PyObject_GetAttrString(types_mod, "SASS_SEPARATOR_COMMA");
141141
PyObject* sass_space = PyObject_GetAttrString(types_mod, "SASS_SEPARATOR_SPACE");
142+
PyObject* collections_mod = PyImport_ImportModule("collections");
143+
PyObject* mapping_t = PyObject_GetAttrString(collections_mod, "Mapping");
142144

143145
if (value == Py_None) {
144146
retv = sass_make_null();
@@ -150,17 +152,21 @@ static union Sass_Value* _to_sass_value(PyObject* value) {
150152
Py_DECREF(bytes);
151153
} else if (PySass_Bytes_Check(value)) {
152154
retv = sass_make_string(PySass_Bytes_AS_STRING(value));
153-
} else if (PyDict_Check(value)) {
155+
/* XXX: PyMapping_Check returns true for lists and tuples in python3 :( */
156+
} else if (PyObject_IsInstance(value, mapping_t)) {
154157
size_t i = 0;
155158
Py_ssize_t pos = 0;
156159
PyObject* d_key = NULL;
157160
PyObject* d_value = NULL;
158-
retv = sass_make_map(PyDict_Size(value));
159-
while (PyDict_Next(value, &pos, &d_key, &d_value)) {
161+
PyObject* dct = PyDict_New();
162+
PyDict_Update(dct, value);
163+
retv = sass_make_map(PyDict_Size(dct));
164+
while (PyDict_Next(dct, &pos, &d_key, &d_value)) {
160165
sass_map_set_key(retv, i, _to_sass_value(d_key));
161166
sass_map_set_value(retv, i, _to_sass_value(d_value));
162167
i += 1;
163168
}
169+
Py_DECREF(dct);
164170
} else if (PyObject_IsInstance(value, sass_number_t)) {
165171
PyObject* d_value = PyObject_GetAttrString(value, "value");
166172
PyObject* unit = PyObject_GetAttrString(value, "unit");
@@ -190,7 +196,6 @@ static union Sass_Value* _to_sass_value(PyObject* value) {
190196
Py_ssize_t i = 0;
191197
PyObject* items = PyObject_GetAttrString(value, "items");
192198
PyObject* separator = PyObject_GetAttrString(value, "separator");
193-
/* TODO: I don't really like this, maybe move types to C */
194199
Sass_Separator sep = SASS_COMMA;
195200
if (separator == sass_comma) {
196201
sep = SASS_COMMA;
@@ -260,6 +265,8 @@ static union Sass_Value* _to_sass_value(PyObject* value) {
260265
Py_DECREF(sass_error_t);
261266
Py_DECREF(sass_comma);
262267
Py_DECREF(sass_space);
268+
Py_DECREF(collections_mod);
269+
Py_DECREF(mapping_t);
263270
return retv;
264271
}
265272

sass.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -457,17 +457,29 @@ def __new__(cls, msg):
457457
return super(SassWarning, cls).__new__(cls, msg)
458458

459459

460-
class SassMap(dict):
460+
class SassMap(collections.Mapping):
461461
"""Because sass maps can have mapping types as keys, we need an immutable
462462
hashable mapping type.
463463
"""
464-
__slots__ = ('_hash',)
464+
__slots__ = ('_dict', '_hash',)
465465

466-
def __new__(cls, *args, **kwargs):
467-
value = super(SassMap, cls).__new__(cls, *args, **kwargs)
466+
def __init__(self, *args, **kwargs):
467+
self._dict = dict(*args, **kwargs)
468468
# An assertion that all things are hashable
469-
value._hash = hash(frozenset(value.items()))
470-
return value
469+
self._hash = hash(frozenset(self._dict.items()))
470+
471+
# Mapping interface
472+
473+
def __getitem__(self, key):
474+
return self._dict[key]
475+
476+
def __iter__(self):
477+
return iter(self._dict)
478+
479+
def __len__(self):
480+
return len(self._dict)
481+
482+
# Our interface
471483

472484
def __repr__(self):
473485
return '{0}({1})'.format(type(self).__name__, frozenset(self.items()))
@@ -476,6 +488,6 @@ def __hash__(self):
476488
return self._hash
477489

478490
def _immutable(self, *_):
479-
raise AssertionError('SassMaps are immutable')
491+
raise TypeError('SassMaps are immutable.')
480492

481493
__setitem__ = __delitem__ = _immutable

0 commit comments

Comments
 (0)