2222extern " C" {
2323#endif
2424
25+ static PyObject* _to_py_value (const union Sass_Value* value);
26+ static union Sass_Value* _to_sass_value (PyObject* value);
27+
28+ static union Sass_Value* _color_to_sass_value (PyObject* value);
29+ static union Sass_Value* _number_to_sass_value (PyObject* value);
30+ static union Sass_Value* _list_to_sass_value (PyObject* value);
31+ static union Sass_Value* _mapping_to_sass_value (PyObject* value);
32+ static union Sass_Value* _unicode_to_sass_value (PyObject* value);
33+ static union Sass_Value* _warning_to_sass_value (PyObject* value);
34+ static union Sass_Value* _error_to_sass_value (PyObject* value);
35+ static union Sass_Value* _unknown_type_to_sass_error (PyObject* value);
36+ static union Sass_Value* _exception_to_sass_error ();
37+
2538struct PySass_Pair {
2639 char *label;
2740 int value;
@@ -129,6 +142,175 @@ static PyObject* _to_py_value(const union Sass_Value* value) {
129142 return retv;
130143}
131144
145+ static union Sass_Value* _color_to_sass_value (PyObject* value) {
146+ union Sass_Value* retv = NULL ;
147+ PyObject* r_value = PyObject_GetAttrString (value, " r" );
148+ PyObject* g_value = PyObject_GetAttrString (value, " g" );
149+ PyObject* b_value = PyObject_GetAttrString (value, " b" );
150+ PyObject* a_value = PyObject_GetAttrString (value, " a" );
151+ retv = sass_make_color (
152+ PyFloat_AsDouble (r_value),
153+ PyFloat_AsDouble (g_value),
154+ PyFloat_AsDouble (b_value),
155+ PyFloat_AsDouble (a_value)
156+ );
157+ Py_DECREF (r_value);
158+ Py_DECREF (g_value);
159+ Py_DECREF (b_value);
160+ Py_DECREF (a_value);
161+ return retv;
162+ }
163+
164+ static union Sass_Value* _list_to_sass_value (PyObject* value) {
165+ PyObject* types_mod = PyImport_ImportModule (" sass" );
166+ PyObject* sass_comma = PyObject_GetAttrString (types_mod, " SASS_SEPARATOR_COMMA" );
167+ PyObject* sass_space = PyObject_GetAttrString (types_mod, " SASS_SEPARATOR_SPACE" );
168+ union Sass_Value* retv = NULL ;
169+ Py_ssize_t i = 0 ;
170+ PyObject* items = PyObject_GetAttrString (value, " items" );
171+ PyObject* separator = PyObject_GetAttrString (value, " separator" );
172+ Sass_Separator sep = SASS_COMMA;
173+ if (separator == sass_comma) {
174+ sep = SASS_COMMA;
175+ } else if (separator == sass_space) {
176+ sep = SASS_SPACE;
177+ } else {
178+ assert (0 );
179+ }
180+ retv = sass_make_list (PyTuple_Size (items), sep);
181+ for (i = 0 ; i < PyTuple_Size (items); i += 1 ) {
182+ sass_list_set_value (
183+ retv, i, _to_sass_value (PyTuple_GET_ITEM (items, i))
184+ );
185+ }
186+ Py_DECREF (types_mod);
187+ Py_DECREF (sass_comma);
188+ Py_DECREF (sass_space);
189+ Py_DECREF (items);
190+ Py_DECREF (separator);
191+ return retv;
192+ }
193+
194+ static union Sass_Value* _mapping_to_sass_value (PyObject* value) {
195+ union Sass_Value* retv = NULL ;
196+ size_t i = 0 ;
197+ Py_ssize_t pos = 0 ;
198+ PyObject* d_key = NULL ;
199+ PyObject* d_value = NULL ;
200+ PyObject* dct = PyDict_New ();
201+ PyDict_Update (dct, value);
202+ retv = sass_make_map (PyDict_Size (dct));
203+ while (PyDict_Next (dct, &pos, &d_key, &d_value)) {
204+ sass_map_set_key (retv, i, _to_sass_value (d_key));
205+ sass_map_set_value (retv, i, _to_sass_value (d_value));
206+ i += 1 ;
207+ }
208+ Py_DECREF (dct);
209+ return retv;
210+ }
211+
212+ static union Sass_Value* _number_to_sass_value (PyObject* value) {
213+ union Sass_Value* retv = NULL ;
214+ PyObject* d_value = PyObject_GetAttrString (value, " value" );
215+ PyObject* unit = PyObject_GetAttrString (value, " unit" );
216+ PyObject* bytes = PyUnicode_AsEncodedString (unit, " UTF-8" , " strict" );
217+ retv = sass_make_number (
218+ PyFloat_AsDouble (d_value), PySass_Bytes_AS_STRING (bytes)
219+ );
220+ Py_DECREF (d_value);
221+ Py_DECREF (unit);
222+ Py_DECREF (bytes);
223+ return retv;
224+ }
225+
226+ static union Sass_Value* _unicode_to_sass_value (PyObject* value) {
227+ union Sass_Value* retv = NULL ;
228+ PyObject* bytes = PyUnicode_AsEncodedString (value, " UTF-8" , " strict" );
229+ retv = sass_make_string (PySass_Bytes_AS_STRING (bytes));
230+ Py_DECREF (bytes);
231+ return retv;
232+ }
233+
234+ static union Sass_Value* _warning_to_sass_value (PyObject* value) {
235+ union Sass_Value* retv = NULL ;
236+ PyObject* msg = PyObject_GetAttrString (value, " msg" );
237+ PyObject* bytes = PyUnicode_AsEncodedString (msg, " UTF-8" , " strict" );
238+ retv = sass_make_warning (PySass_Bytes_AS_STRING (bytes));
239+ Py_DECREF (msg);
240+ Py_DECREF (bytes);
241+ return retv;
242+ }
243+
244+ static union Sass_Value* _error_to_sass_value (PyObject* value) {
245+ union Sass_Value* retv = NULL ;
246+ PyObject* msg = PyObject_GetAttrString (value, " msg" );
247+ PyObject* bytes = PyUnicode_AsEncodedString (msg, " UTF-8" , " strict" );
248+ retv = sass_make_error (PySass_Bytes_AS_STRING (bytes));
249+ Py_DECREF (msg);
250+ Py_DECREF (bytes);
251+ return retv;
252+ }
253+
254+ static union Sass_Value* _unknown_type_to_sass_error (PyObject* value) {
255+ union Sass_Value* retv = NULL ;
256+ PyObject* type = PyObject_Type (value);
257+ PyObject* type_name = PyObject_GetAttrString (type, " __name__" );
258+ PyObject* fmt = PyUnicode_FromString (
259+ " Unexpected type: `{0}`.\n "
260+ " Expected one of:\n "
261+ " - None\n "
262+ " - bool\n "
263+ " - str\n "
264+ " - SassNumber\n "
265+ " - SassColor\n "
266+ " - SassList\n "
267+ " - dict\n "
268+ " - SassMap\n "
269+ " - SassWarning\n "
270+ " - SassError\n "
271+ );
272+ PyObject* format_meth = PyObject_GetAttrString (fmt, " format" );
273+ PyObject* result = PyObject_CallFunctionObjArgs (
274+ format_meth, type_name, NULL
275+ );
276+ PyObject* bytes = PyUnicode_AsEncodedString (result, " UTF-8" , " strict" );
277+ retv = sass_make_error (PySass_Bytes_AS_STRING (bytes));
278+ Py_DECREF (type);
279+ Py_DECREF (type_name);
280+ Py_DECREF (fmt);
281+ Py_DECREF (format_meth);
282+ Py_DECREF (result);
283+ Py_DECREF (bytes);
284+ return retv;
285+ }
286+
287+ static union Sass_Value* _exception_to_sass_error () {
288+ union Sass_Value* retv = NULL ;
289+ PyObject* etype = NULL ;
290+ PyObject* evalue = NULL ;
291+ PyObject* etb = NULL ;
292+ PyErr_Fetch (&etype, &evalue, &etb);
293+ {
294+ PyObject* traceback_mod = PyImport_ImportModule (" traceback" );
295+ PyObject* traceback_parts = PyObject_CallMethod (
296+ traceback_mod, " format_exception" , " OOO" , etype, evalue, etb
297+ );
298+ PyList_Insert (traceback_parts, 0 , PyUnicode_FromString (" \n " ));
299+ PyObject* joinstr = PyUnicode_FromString (" " );
300+ PyObject* result = PyUnicode_Join (joinstr, traceback_parts);
301+ PyObject* bytes = PyUnicode_AsEncodedString (
302+ result, " UTF-8" , " strict"
303+ );
304+ retv = sass_make_error (PySass_Bytes_AS_STRING (bytes));
305+ Py_DECREF (traceback_mod);
306+ Py_DECREF (traceback_parts);
307+ Py_DECREF (joinstr);
308+ Py_DECREF (result);
309+ Py_DECREF (bytes);
310+ }
311+ return retv;
312+ }
313+
132314static union Sass_Value* _to_sass_value (PyObject* value) {
133315 union Sass_Value* retv = NULL ;
134316 PyObject* types_mod = PyImport_ImportModule (" sass" );
@@ -137,8 +319,6 @@ static union Sass_Value* _to_sass_value(PyObject* value) {
137319 PyObject* sass_list_t = PyObject_GetAttrString (types_mod, " SassList" );
138320 PyObject* sass_warning_t = PyObject_GetAttrString (types_mod, " SassWarning" );
139321 PyObject* sass_error_t = PyObject_GetAttrString (types_mod, " SassError" );
140- PyObject* sass_comma = PyObject_GetAttrString (types_mod, " SASS_SEPARATOR_COMMA" );
141- PyObject* sass_space = PyObject_GetAttrString (types_mod, " SASS_SEPARATOR_SPACE" );
142322 PyObject* collections_mod = PyImport_ImportModule (" collections" );
143323 PyObject* mapping_t = PyObject_GetAttrString (collections_mod, " Mapping" );
144324
@@ -147,114 +327,26 @@ static union Sass_Value* _to_sass_value(PyObject* value) {
147327 } else if (PyBool_Check (value)) {
148328 retv = sass_make_boolean (value == Py_True);
149329 } else if (PyUnicode_Check (value)) {
150- PyObject* bytes = PyUnicode_AsEncodedString (value, " UTF-8" , " strict" );
151- retv = sass_make_string (PySass_Bytes_AS_STRING (bytes));
152- Py_DECREF (bytes);
330+ retv = _unicode_to_sass_value (value);
153331 } else if (PySass_Bytes_Check (value)) {
154332 retv = sass_make_string (PySass_Bytes_AS_STRING (value));
155333 /* XXX: PyMapping_Check returns true for lists and tuples in python3 :( */
156334 } else if (PyObject_IsInstance (value, mapping_t )) {
157- size_t i = 0 ;
158- Py_ssize_t pos = 0 ;
159- PyObject* d_key = NULL ;
160- PyObject* d_value = NULL ;
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)) {
165- sass_map_set_key (retv, i, _to_sass_value (d_key));
166- sass_map_set_value (retv, i, _to_sass_value (d_value));
167- i += 1 ;
168- }
169- Py_DECREF (dct);
335+ retv = _mapping_to_sass_value (value);
170336 } else if (PyObject_IsInstance (value, sass_number_t )) {
171- PyObject* d_value = PyObject_GetAttrString (value, " value" );
172- PyObject* unit = PyObject_GetAttrString (value, " unit" );
173- PyObject* bytes = PyUnicode_AsEncodedString (unit, " UTF-8" , " strict" );
174- retv = sass_make_number (
175- PyFloat_AsDouble (d_value), PySass_Bytes_AS_STRING (bytes)
176- );
177- Py_DECREF (d_value);
178- Py_DECREF (unit);
179- Py_DECREF (bytes);
337+ retv = _number_to_sass_value (value);
180338 } else if (PyObject_IsInstance (value, sass_color_t )) {
181- PyObject* r_value = PyObject_GetAttrString (value, " r" );
182- PyObject* g_value = PyObject_GetAttrString (value, " g" );
183- PyObject* b_value = PyObject_GetAttrString (value, " b" );
184- PyObject* a_value = PyObject_GetAttrString (value, " a" );
185- retv = sass_make_color (
186- PyFloat_AsDouble (r_value),
187- PyFloat_AsDouble (g_value),
188- PyFloat_AsDouble (b_value),
189- PyFloat_AsDouble (a_value)
190- );
191- Py_DECREF (r_value);
192- Py_DECREF (g_value);
193- Py_DECREF (b_value);
194- Py_DECREF (a_value);
339+ retv = _color_to_sass_value (value);
195340 } else if (PyObject_IsInstance (value, sass_list_t )) {
196- Py_ssize_t i = 0 ;
197- PyObject* items = PyObject_GetAttrString (value, " items" );
198- PyObject* separator = PyObject_GetAttrString (value, " separator" );
199- Sass_Separator sep = SASS_COMMA;
200- if (separator == sass_comma) {
201- sep = SASS_COMMA;
202- } else if (separator == sass_space) {
203- sep = SASS_SPACE;
204- } else {
205- assert (0 );
206- }
207- retv = sass_make_list (PyTuple_Size (items), sep);
208- for (i = 0 ; i < PyTuple_Size (items); i += 1 ) {
209- sass_list_set_value (
210- retv, i, _to_sass_value (PyTuple_GET_ITEM (items, i))
211- );
212- }
213- Py_DECREF (items);
214- Py_DECREF (separator);
341+ retv = _list_to_sass_value (value);
215342 } else if (PyObject_IsInstance (value, sass_warning_t )) {
216- PyObject* msg = PyObject_GetAttrString (value, " msg" );
217- PyObject* bytes = PyUnicode_AsEncodedString (msg, " UTF-8" , " strict" );
218- retv = sass_make_warning (PySass_Bytes_AS_STRING (bytes));
219- Py_DECREF (msg);
220- Py_DECREF (bytes);
343+ retv = _warning_to_sass_value (value);
221344 } else if (PyObject_IsInstance (value, sass_error_t )) {
222- PyObject* msg = PyObject_GetAttrString (value, " msg" );
223- PyObject* bytes = PyUnicode_AsEncodedString (msg, " UTF-8" , " strict" );
224- retv = sass_make_error (PySass_Bytes_AS_STRING (bytes));
225- Py_DECREF (msg);
226- Py_DECREF (bytes);
345+ retv = _error_to_sass_value (value);
227346 }
228347
229348 if (retv == NULL ) {
230- PyObject* type = PyObject_Type (value);
231- PyObject* type_name = PyObject_GetAttrString (type, " __name__" );
232- PyObject* fmt = PyUnicode_FromString (
233- " Unexpected type: `{0}`.\n "
234- " Expected one of:\n "
235- " - None\n "
236- " - bool\n "
237- " - str\n "
238- " - SassNumber\n "
239- " - SassColor\n "
240- " - SassList\n "
241- " - dict\n "
242- " - SassMap\n "
243- " - SassWarning\n "
244- " - SassError\n "
245- );
246- PyObject* format_meth = PyObject_GetAttrString (fmt, " format" );
247- PyObject* result = PyObject_CallFunctionObjArgs (
248- format_meth, type_name, NULL
249- );
250- PyObject* bytes = PyUnicode_AsEncodedString (result, " UTF-8" , " strict" );
251- retv = sass_make_error (PySass_Bytes_AS_STRING (bytes));
252- Py_DECREF (type);
253- Py_DECREF (type_name);
254- Py_DECREF (fmt);
255- Py_DECREF (format_meth);
256- Py_DECREF (result);
257- Py_DECREF (bytes);
349+ retv = _unknown_type_to_sass_error (value);
258350 }
259351
260352 Py_DECREF (types_mod);
@@ -263,8 +355,6 @@ static union Sass_Value* _to_sass_value(PyObject* value) {
263355 Py_DECREF (sass_list_t );
264356 Py_DECREF (sass_warning_t );
265357 Py_DECREF (sass_error_t );
266- Py_DECREF (sass_comma);
267- Py_DECREF (sass_space);
268358 Py_DECREF (collections_mod);
269359 Py_DECREF (mapping_t );
270360 return retv;
@@ -280,7 +370,7 @@ static union Sass_Value* _call_py_f(
280370 union Sass_Value* sass_result = NULL ;
281371
282372 for (i = 0 ; i < sass_list_get_length (sass_args); i += 1 ) {
283- union Sass_Value* sass_arg = sass_list_get_value (sass_args, i);
373+ const union Sass_Value* sass_arg = sass_list_get_value (sass_args, i);
284374 PyObject* py_arg = NULL ;
285375 if (!(py_arg = _to_py_value (sass_arg))) goto done;
286376 PyTuple_SetItem (py_args, i, py_arg);
@@ -291,28 +381,7 @@ static union Sass_Value* _call_py_f(
291381
292382done:
293383 if (sass_result == NULL ) {
294- PyObject* etype = NULL ;
295- PyObject* evalue = NULL ;
296- PyObject* etb = NULL ;
297- {
298- PyErr_Fetch (&etype, &evalue, &etb);
299- PyObject* traceback_mod = PyImport_ImportModule (" traceback" );
300- PyObject* traceback_parts = PyObject_CallMethod (
301- traceback_mod, " format_exception" , " OOO" , etype, evalue, etb
302- );
303- PyList_Insert (traceback_parts, 0 , PyUnicode_FromString (" \n " ));
304- PyObject* joinstr = PyUnicode_FromString (" " );
305- PyObject* result = PyUnicode_Join (joinstr, traceback_parts);
306- PyObject* bytes = PyUnicode_AsEncodedString (
307- result, " UTF-8" , " strict"
308- );
309- sass_result = sass_make_error (PySass_Bytes_AS_STRING (bytes));
310- Py_DECREF (traceback_mod);
311- Py_DECREF (traceback_parts);
312- Py_DECREF (joinstr);
313- Py_DECREF (result);
314- Py_DECREF (bytes);
315- }
384+ sass_result = _exception_to_sass_error ();
316385 }
317386 Py_XDECREF (py_args);
318387 Py_XDECREF (py_result);
0 commit comments