from .object cimport PyObject from .pyport cimport uint64_t cdef extern from *: # On Python 2, PyDict_GetItemWithError is called _PyDict_GetItemWithError # Also backport PyDict_GetItemStringRef and PyDict_SetDefaultRef """ #if PY_MAJOR_VERSION <= 2 #define PyDict_GetItemWithError _PyDict_GetItemWithError #endif #if __PYX_LIMITED_VERSION_HEX < 0x030d0000 static CYTHON_INLINE int __Pyx_CAPI_PyDict_GetItemStringRef(PyObject *mp, const char *key, PyObject **result) { int res; PyObject *key_obj = PyUnicode_FromString(key); if (key_obj == NULL) { *result = NULL; return -1; } res = __Pyx_PyDict_GetItemRef(mp, key_obj, result); Py_DECREF(key_obj); return res; } #else #define __Pyx_CAPI_PyDict_GetItemStringRef PyDict_GetItemStringRef #endif #if PY_VERSION_HEX < 0x030d0000 || (CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030F0000) static CYTHON_INLINE int __Pyx_CAPI_PyDict_SetDefaultRef(PyObject *d, PyObject *key, PyObject *default_value, PyObject **result) { PyObject *value; if (__Pyx_PyDict_GetItemRef(d, key, &value) < 0) { // get error if (result) { *result = NULL; } return -1; } if (value != NULL) { // present if (result) { *result = value; } else { Py_DECREF(value); } return 1; } // missing: set the item if (PyDict_SetItem(d, key, default_value) < 0) { // set error if (result) { *result = NULL; } return -1; } if (result) { Py_INCREF(default_value); *result = default_value; } return 0; } #else #define __Pyx_CAPI_PyDict_SetDefaultRef PyDict_SetDefaultRef #endif """ int PyDict_GetItemRef "__Pyx_PyDict_GetItemRef" (object p, object key, PyObject* *result) except -1 # Return a new strong reference to the object from dictionary p # which has a key key: # - If the key is present, set *result to a new strong reference to # the value and return 1. # - If the key is missing, set *result to NULL and return 0. # - On error, raise an exception and return -1. int PyDict_GetItemStringRef "__Pyx_CAPI_PyDict_GetItemStringRef" (object p, const char *key, PyObject* *result) except -1 # Similar to PyDict_GetItemRef(), but key is specified as a const char* # UTF-8 encoded bytes string, rather than a PyObject*. int PyDict_SetDefaultRef "__Pyx_CAPI_PyDict_SetDefaultRef" (object p, object key, object default_value, PyObject* *result) except -1 # Inserts default_value into the dictionary p with a key of key if the # key is not already present in the dictionary. If result is not NULL, # then *result is set to a strong reference to either default_value, # if the key was not present, or the existing value, if key was already # present in the dictionary. Returns 1 if the key was present and # default_value was not inserted, or 0 if the key was not present and # default_value was inserted. On failure, returns -1, sets an exception, # and sets *result to NULL. # For clarity: if you have a strong reference to default_value before # calling this function, then after it returns, you hold a strong # reference to both default_value and *result (if it’s not NULL). These # may refer to the same object: in that case you hold two separate # references to it. cdef extern from "Python.h": ############################################################################ # 7.4.1 Dictionary Objects ############################################################################ # PyDictObject # # This subtype of PyObject represents a Python dictionary object # (i.e. the 'dict' type). # PyTypeObject PyDict_Type # # This instance of PyTypeObject represents the Python dictionary # type. This is exposed to Python programs as dict and # types.DictType. bint PyDict_Check(object p) # Return true if p is a dict object or an instance of a subtype of # the dict type. bint PyDict_CheckExact(object p) # Return true if p is a dict object, but not an instance of a # subtype of the dict type. dict PyDict_New() # Return value: New reference. # Return a new empty dictionary, or NULL on failure. object PyDictProxy_New(object dict) # Return value: New reference. # Return a proxy object for a mapping which enforces read-only # behavior. This is normally used to create a proxy to prevent # modification of the dictionary for non-dynamic class types. void PyDict_Clear(object p) # Empty an existing dictionary of all key-value pairs. int PyDict_Contains(object p, object key) except -1 # Determine if dictionary p contains key. If an item in p is # matches key, return 1, otherwise return 0. On error, return # -1. This is equivalent to the Python expression "key in p". dict PyDict_Copy(object p) # Return value: New reference. # Return a new dictionary that contains the same key-value pairs as p. int PyDict_SetItem(object p, object key, object val) except -1 # Insert value into the dictionary p with a key of key. key must # be hashable; if it isn't, TypeError will be raised. Return 0 on # success or -1 on failure. int PyDict_SetItemString(object p, const char *key, object val) except -1 # Insert value into the dictionary p using key as a key. key # should be a char*. The key object is created using # PyString_FromString(key). Return 0 on success or -1 on failure. int PyDict_DelItem(object p, object key) except -1 # Remove the entry in dictionary p with key key. key must be # hashable; if it isn't, TypeError is raised. Return 0 on success # or -1 on failure. int PyDict_DelItemString(object p, const char *key) except -1 # Remove the entry in dictionary p which has a key specified by # the string key. Return 0 on success or -1 on failure. PyObject* PyDict_GetItem(object p, object key) # Return value: Borrowed reference. # Return the object from dictionary p which has a key key. Return # NULL if the key key is not present, but without setting an # exception. PyObject* PyDict_GetItemWithError(object p, object key) except? NULL # Return value: Borrowed reference. # Variant of PyDict_GetItem() that does not suppress exceptions. Return # NULL with an exception set if an exception occurred. Return NULL # without an exception set if the key wasn’t present. PyObject* PyDict_GetItemString(object p, const char *key) # Return value: Borrowed reference. # This is the same as PyDict_GetItem(), but key is specified as a # char*, rather than a PyObject*. PyObject* PyDict_SetDefault(object p, object key, object default) except NULL # Return value: Borrowed reference. # This is the same as the Python-level dict.setdefault(). If present, it # returns the value corresponding to key from the dictionary p. If the key # is not in the dict, it is inserted with value defaultobj and defaultobj # is returned. This function evaluates the hash function of key only once, # instead of evaluating it independently for the lookup and the insertion. list PyDict_Items(object p) # Return value: New reference. # Return a PyListObject containing all the items from the # dictionary, as in the dictionary method items() (see the Python # Library Reference). list PyDict_Keys(object p) # Return value: New reference. # Return a PyListObject containing all the keys from the # dictionary, as in the dictionary method keys() (see the Python # Library Reference). list PyDict_Values(object p) # Return value: New reference. # Return a PyListObject containing all the values from the # dictionary p, as in the dictionary method values() (see the # Python Library Reference). Py_ssize_t PyDict_Size(object p) except -1 # Return the number of items in the dictionary. This is equivalent # to "len(p)" on a dictionary. int PyDict_Next(object p, Py_ssize_t *ppos, PyObject* *pkey, PyObject* *pvalue) # Iterate over all key-value pairs in the dictionary p. The int # referred to by ppos must be initialized to 0 prior to the first # call to this function to start the iteration; the function # returns true for each pair in the dictionary, and false once all # pairs have been reported. The parameters pkey and pvalue should # either point to PyObject* variables that will be filled in with # each key and value, respectively, or may be NULL. Any references # returned through them are borrowed. ppos should not be altered # during iteration. Its value represents offsets within the # internal dictionary structure, and since the structure is # sparse, the offsets are not consecutive. # For example: # #object key, *value; #int pos = 0; # #while (PyDict_Next(self->dict, &pos, &key, &value)) { # /* do something interesting with the values... */ # ... #} # The dictionary p should not be mutated during iteration. It is # safe (since Python 2.1) to modify the values of the keys as you # iterate over the dictionary, but only so long as the set of keys # does not change. For example: # object key, *value; # int pos = 0; # while (PyDict_Next(self->dict, &pos, &key, &value)) { # int i = PyInt_AS_LONG(value) + 1; # object o = PyInt_FromLong(i); # if (o == NULL) # return -1; # if (PyDict_SetItem(self->dict, key, o) < 0) { # Py_DECREF(o); # return -1; # } # Py_DECREF(o); # } int PyDict_Merge(object a, object b, int override) except -1 # Iterate over mapping object b adding key-value pairs to # dictionary a. b may be a dictionary, or any object supporting # PyMapping_Keys() and PyObject_GetItem(). If override is true, # existing pairs in a will be replaced if a matching key is found # in b, otherwise pairs will only be added if there is not a # matching key in a. Return 0 on success or -1 if an exception was # raised. int PyDict_Update(object a, object b) except -1 # This is the same as PyDict_Merge(a, b, 1) in C, or a.update(b) # in Python. Return 0 on success or -1 if an exception was raised. int PyDict_MergeFromSeq2(object a, object seq2, int override) except -1 # Update or merge into dictionary a, from the key-value pairs in # seq2. seq2 must be an iterable object producing iterable objects # of length 2, viewed as key-value pairs. In case of duplicate # keys, the last wins if override is true, else the first # wins. Return 0 on success or -1 if an exception was # raised. Equivalent Python (except for the return value): # #def PyDict_MergeFromSeq2(a, seq2, override): # for key, value in seq2: # if override or key not in a: # a[key] = value