1//////////////////// ArgTypeTest.proto ////////////////////
2
3static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4    const char *name, int exact); /*proto*/
5
6//////////////////// ArgTypeTest ////////////////////
7
8static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
9    PyErr_Format(PyExc_TypeError,
10        "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
11        name, type->tp_name, Py_TYPE(obj)->tp_name);
12}
13
14static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
15    const char *name, int exact)
16{
17    if (unlikely(!type)) {
18        PyErr_SetString(PyExc_SystemError, "Missing type object");
19        return 0;
20    }
21    if (none_allowed && obj == Py_None) return 1;
22    else if (exact) {
23        if (likely(Py_TYPE(obj) == type)) return 1;
24        #if PY_MAJOR_VERSION == 2
25        else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
26        #endif
27    }
28    else {
29        if (likely(PyObject_TypeCheck(obj, type))) return 1;
30    }
31    __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
32    return 0;
33}
34
35//////////////////// RaiseArgTupleInvalid.proto ////////////////////
36
37static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
38    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
39
40//////////////////// RaiseArgTupleInvalid ////////////////////
41
42//  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
43//  many or too few positional arguments were found.  This handles
44//  Py_ssize_t formatting correctly.
45
46static void __Pyx_RaiseArgtupleInvalid(
47    const char* func_name,
48    int exact,
49    Py_ssize_t num_min,
50    Py_ssize_t num_max,
51    Py_ssize_t num_found)
52{
53    Py_ssize_t num_expected;
54    const char *more_or_less;
55
56    if (num_found < num_min) {
57        num_expected = num_min;
58        more_or_less = "at least";
59    } else {
60        num_expected = num_max;
61        more_or_less = "at most";
62    }
63    if (exact) {
64        more_or_less = "exactly";
65    }
66    PyErr_Format(PyExc_TypeError,
67                 "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
68                 func_name, more_or_less, num_expected,
69                 (num_expected == 1) ? "" : "s", num_found);
70}
71
72
73//////////////////// RaiseKeywordRequired.proto ////////////////////
74
75static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
76
77//////////////////// RaiseKeywordRequired ////////////////////
78
79static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
80    const char* func_name,
81    PyObject* kw_name)
82{
83    PyErr_Format(PyExc_TypeError,
84        #if PY_MAJOR_VERSION >= 3
85        "%s() needs keyword-only argument %U", func_name, kw_name);
86        #else
87        "%s() needs keyword-only argument %s", func_name,
88        PyString_AS_STRING(kw_name));
89        #endif
90}
91
92
93//////////////////// RaiseDoubleKeywords.proto ////////////////////
94
95static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
96
97//////////////////// RaiseDoubleKeywords ////////////////////
98
99static void __Pyx_RaiseDoubleKeywordsError(
100    const char* func_name,
101    PyObject* kw_name)
102{
103    PyErr_Format(PyExc_TypeError,
104        #if PY_MAJOR_VERSION >= 3
105        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
106        #else
107        "%s() got multiple values for keyword argument '%s'", func_name,
108        PyString_AsString(kw_name));
109        #endif
110}
111
112
113//////////////////// KeywordStringCheck.proto ////////////////////
114
115static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); /*proto*/
116
117//////////////////// KeywordStringCheck ////////////////////
118
119//  __Pyx_CheckKeywordStrings raises an error if non-string keywords
120//  were passed to a function, or if any keywords were passed to a
121//  function that does not accept them.
122
123static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
124    PyObject *kwdict,
125    const char* function_name,
126    int kw_allowed)
127{
128    PyObject* key = 0;
129    Py_ssize_t pos = 0;
130#if CYTHON_COMPILING_IN_PYPY
131    /* PyPy appears to check keywords at call time, not at unpacking time => not much to do here */
132    if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0))
133        goto invalid_keyword;
134    return 1;
135#else
136    while (PyDict_Next(kwdict, &pos, &key, 0)) {
137        #if PY_MAJOR_VERSION < 3
138        if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
139        #endif
140            if (unlikely(!PyUnicode_Check(key)))
141                goto invalid_keyword_type;
142    }
143    if ((!kw_allowed) && unlikely(key))
144        goto invalid_keyword;
145    return 1;
146invalid_keyword_type:
147    PyErr_Format(PyExc_TypeError,
148        "%.200s() keywords must be strings", function_name);
149    return 0;
150#endif
151invalid_keyword:
152    PyErr_Format(PyExc_TypeError,
153    #if PY_MAJOR_VERSION < 3
154        "%.200s() got an unexpected keyword argument '%.200s'",
155        function_name, PyString_AsString(key));
156    #else
157        "%s() got an unexpected keyword argument '%U'",
158        function_name, key);
159    #endif
160    return 0;
161}
162
163
164//////////////////// ParseKeywords.proto ////////////////////
165
166static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
167    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
168    const char* function_name); /*proto*/
169
170//////////////////// ParseKeywords ////////////////////
171//@requires: RaiseDoubleKeywords
172
173//  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
174//  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
175//  keywords will raise an invalid keyword error.
176//
177//  Three kinds of errors are checked: 1) non-string keywords, 2)
178//  unexpected keywords and 3) overlap with positional arguments.
179//
180//  If num_posargs is greater 0, it denotes the number of positional
181//  arguments that were passed and that must therefore not appear
182//  amongst the keywords as well.
183//
184//  This method does not check for required keyword arguments.
185
186static int __Pyx_ParseOptionalKeywords(
187    PyObject *kwds,
188    PyObject **argnames[],
189    PyObject *kwds2,
190    PyObject *values[],
191    Py_ssize_t num_pos_args,
192    const char* function_name)
193{
194    PyObject *key = 0, *value = 0;
195    Py_ssize_t pos = 0;
196    PyObject*** name;
197    PyObject*** first_kw_arg = argnames + num_pos_args;
198
199    while (PyDict_Next(kwds, &pos, &key, &value)) {
200        name = first_kw_arg;
201        while (*name && (**name != key)) name++;
202        if (*name) {
203            values[name-argnames] = value;
204            continue;
205        }
206
207        name = first_kw_arg;
208        #if PY_MAJOR_VERSION < 3
209        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
210            while (*name) {
211                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
212                        && _PyString_Eq(**name, key)) {
213                    values[name-argnames] = value;
214                    break;
215                }
216                name++;
217            }
218            if (*name) continue;
219            else {
220                // not found after positional args, check for duplicate
221                PyObject*** argname = argnames;
222                while (argname != first_kw_arg) {
223                    if ((**argname == key) || (
224                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
225                             && _PyString_Eq(**argname, key))) {
226                        goto arg_passed_twice;
227                    }
228                    argname++;
229                }
230            }
231        } else
232        #endif
233        if (likely(PyUnicode_Check(key))) {
234            while (*name) {
235                int cmp = (**name == key) ? 0 :
236                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
237                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
238                #endif
239                    // need to convert argument name from bytes to unicode for comparison
240                    PyUnicode_Compare(**name, key);
241                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
242                if (cmp == 0) {
243                    values[name-argnames] = value;
244                    break;
245                }
246                name++;
247            }
248            if (*name) continue;
249            else {
250                // not found after positional args, check for duplicate
251                PyObject*** argname = argnames;
252                while (argname != first_kw_arg) {
253                    int cmp = (**argname == key) ? 0 :
254                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
255                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
256                    #endif
257                        // need to convert argument name from bytes to unicode for comparison
258                        PyUnicode_Compare(**argname, key);
259                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
260                    if (cmp == 0) goto arg_passed_twice;
261                    argname++;
262                }
263            }
264        } else
265            goto invalid_keyword_type;
266
267        if (kwds2) {
268            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
269        } else {
270            goto invalid_keyword;
271        }
272    }
273    return 0;
274arg_passed_twice:
275    __Pyx_RaiseDoubleKeywordsError(function_name, key);
276    goto bad;
277invalid_keyword_type:
278    PyErr_Format(PyExc_TypeError,
279        "%.200s() keywords must be strings", function_name);
280    goto bad;
281invalid_keyword:
282    PyErr_Format(PyExc_TypeError,
283    #if PY_MAJOR_VERSION < 3
284        "%.200s() got an unexpected keyword argument '%.200s'",
285        function_name, PyString_AsString(key));
286    #else
287        "%s() got an unexpected keyword argument '%U'",
288        function_name, key);
289    #endif
290bad:
291    return -1;
292}
293