/* XXX(nnorwitz): should we error check if the user passes any empty ranges? range(-10) range(0, -5) range(0, 5, -1) */ static PyObject * range_new(PyTypeObject *type, PyObject *args, PyObject *kw) { rangeobject *obj; PyObject *start = NULL, *stop = NULL, *step = NULL; if (!_PyArg_NoKeywords("range()", kw)) return NULL; if (PyTuple_Size(args) <= 1) { if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop)) return NULL; stop = PyNumber_Index(stop); if (!stop) return NULL; start = PyLong_FromLong(0); if (!start) { Py_DECREF(stop); return NULL; } step = PyLong_FromLong(1); if (!step) { Py_DECREF(stop); Py_DECREF(start); return NULL; } } else { if (!PyArg_UnpackTuple(args, "range", 2, 3, &start, &stop, &step)) return NULL; /* Convert borrowed refs to owned refs */ start = PyNumber_Index(start); if (!start) return NULL; stop = PyNumber_Index(stop); if (!stop) { Py_DECREF(start); return NULL; } step = validate_step(step); /* Caution, this can clear exceptions */ if (!step) { Py_DECREF(start); Py_DECREF(stop); return NULL; } } obj = make_range_object(type, start, stop, step); if (obj != NULL) return (PyObject *) obj; /* Failed to create object, release attributes */ Py_XDECREF(start); Py_XDECREF(stop); Py_XDECREF(step); return NULL; }
static PyObject * math_log(PyObject *self, PyObject *args) { PyObject *arg; PyObject *base = NULL; PyObject *num, *den; PyObject *ans; if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base)) return NULL; num = loghelper(arg, log, "log"); if (num == NULL || base == NULL) return num; den = loghelper(base, log, "log"); if (den == NULL) { Py_DECREF(num); return NULL; } ans = PyNumber_TrueDivide(num, den); Py_DECREF(num); Py_DECREF(den); return ans; }
static PyObject * math_2(PyObject *args, double (*func) (double, double), char *funcname) { PyObject *ox, *oy; double x, y, r; if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy)) return NULL; x = PyFloat_AsDouble(ox); y = PyFloat_AsDouble(oy); if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) return NULL; errno = 0; PyFPE_START_PROTECT("in math_2", return 0); r = (*func)(x, y); PyFPE_END_PROTECT(r); if (Py_IS_NAN(r)) { if (!Py_IS_NAN(x) && !Py_IS_NAN(y)) errno = EDOM; else errno = 0; } else if (Py_IS_INFINITY(r)) { if (Py_IS_FINITE(x) && Py_IS_FINITE(y)) errno = ERANGE; else errno = 0; } if (errno && is_error(r)) return NULL; else return PyFloat_FromDouble(r); }
static PyObject * sophia_db_get(SophiaDB *db, PyObject *args) { char *key; PyObject *pkey, *pvalue = NULL; void *value; Py_ssize_t ksize; size_t vsize; ensure_is_opened(db, NULL); if (!PyArg_UnpackTuple(args, "get", 1, 2, &pkey, &pvalue) || PyBytes_AsStringAndSize(pkey, &key, &ksize) == -1) return NULL; int rv = sp_get(db->db, key, (size_t)ksize, &value, &vsize); switch (rv) { case 1: pvalue = PyBytes_FromStringAndSize(value, (Py_ssize_t)vsize); free(value); return pvalue; case 0: if (pvalue) return pvalue; Py_RETURN_NONE; default: PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } }
static PyObject * _cffi_f_cvCreateMat(PyObject *self, PyObject *args) { int x0; int x1; int x2; CvMat * result; PyObject *arg0; PyObject *arg1; PyObject *arg2; if (!PyArg_UnpackTuple(args, "cvCreateMat", 3, 3, &arg0, &arg1, &arg2)) return NULL; x0 = _cffi_to_c_int(arg0, int); if (x0 == (int)-1 && PyErr_Occurred()) return NULL; x1 = _cffi_to_c_int(arg1, int); if (x1 == (int)-1 && PyErr_Occurred()) return NULL; x2 = _cffi_to_c_int(arg2, int); if (x2 == (int)-1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS _cffi_restore_errno(); { result = cvCreateMat(x0, x1, x2); } _cffi_save_errno(); Py_END_ALLOW_THREADS (void)self; /* unused */ return _cffi_from_c_pointer((char *)result, _cffi_type(12)); }
static PyObject * hashsplit_read_chunk(PyObject *self, PyObject *args) { PyObject *source_file = NULL; //gcc complains if these aren't initialized PyObject *max_chunk_size = NULL; long MAX_CHUNK_SIZE; PyObject *result = NULL; Chunk *chunk; FILE *source; if (!PyArg_UnpackTuple(args, "read_chunk", 1, 2, &source_file, &max_chunk_size)) return NULL; if (!(source = PyFile_AsFile(source_file))) { PyErr_SetString(PyExc_TypeError, "Expected file or file descriptor"); return NULL; } if (!max_chunk_size || max_chunk_size == Py_None) { MAX_CHUNK_SIZE = DEFAULT_MAX_CHUNK_SIZE; } else if ((MAX_CHUNK_SIZE = PyInt_AsLong(max_chunk_size))==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "max_chunk_size should be an integer"); return NULL; } if (MAX_CHUNK_SIZE < MIN_CHUNK_SIZE) { PyErr_SetString(PyExc_ValueError, "max_chunk_size must be larger than MIN_CHUNK_SIZE"); return NULL; } if (!(chunk = chunk_new(MAX_CHUNK_SIZE))) return PyErr_NoMemory(); if (!read_chunk(source, chunk, MAX_CHUNK_SIZE)) { PyErr_SetString(PyExc_EOFError, ""); } else { result = PyString_FromStringAndSize((char*)chunk->data, chunk->length); } chunk_delete(chunk); return result; }
static PyObject * math_fmod(PyObject *self, PyObject *args) { PyObject *ox, *oy; double r, x, y; if (! PyArg_UnpackTuple(args, "fmod", 2, 2, &ox, &oy)) return NULL; x = PyFloat_AsDouble(ox); y = PyFloat_AsDouble(oy); if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) return NULL; /* fmod(x, +/-Inf) returns x for finite x. */ if (Py_IS_INFINITY(y) && Py_IS_FINITE(x)) return PyFloat_FromDouble(x); errno = 0; PyFPE_START_PROTECT("in math_fmod", return 0); r = fmod(x, y); PyFPE_END_PROTECT(r); if (Py_IS_NAN(r)) { if (!Py_IS_NAN(x) && !Py_IS_NAN(y)) errno = EDOM; else errno = 0; } if (errno && is_error(r)) return NULL; else return PyFloat_FromDouble(r); }
/* Updating LDAPEntry. Pretty much same as PyDict_Update function's codebase. */ static PyObject * LDAPEntry_Update(LDAPEntry *self, PyObject *args, PyObject *kwds) { int rc = 0; PyObject *arg = NULL; if (!PyArg_UnpackTuple(args, "update", 0, 1, &arg)) { rc = -1; } else if (arg != NULL) { if (PyObject_HasAttrString(arg, "keys") || PyDict_Check(arg)) { /* If argument is a dict, use own function to update. */ rc = LDAPEntry_UpdateFromDict(self, arg); } else { /* If argument is a sequence type, use own function to update. */ rc = LDAPEntry_UpdateFromSeq2(self, arg); } } if (rc == 0 && kwds != NULL) { if (PyArg_ValidateKeywordArguments(kwds)) { /* If arguments are keywords, use own function to update. */ rc = LDAPEntry_UpdateFromDict(self, kwds); } else { rc = -1; } } if (rc != -1) { Py_INCREF(Py_None); //Why? return Py_None; } return NULL; }
static PyObject* _tnetstring_dumps(PyObject* self, PyObject *args, PyObject *kwds) { PyObject *object, *string; char *output, *odata, *sdata; size_t len=0; if(!PyArg_UnpackTuple(args, "dumps", 1, 1, &object)) { return NULL; } Py_INCREF(object); output = tns_render_reversed(object, &len); Py_DECREF(object); if(output == NULL) { return NULL; } string = PyString_FromStringAndSize(NULL,len); if(string == NULL) { return NULL; } sdata = PyString_AS_STRING(string); odata = output + len - 1; while(odata >= output) { *sdata = *odata; odata--; sdata++; } free(output); return string; }
static PyObject * csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *name_obj, *dialect_obj = NULL; PyObject *dialect; if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj)) return NULL; if (!PyUnicode_Check(name_obj)) { PyErr_SetString(PyExc_TypeError, "dialect name must be a string"); return NULL; } if (PyUnicode_READY(name_obj) == -1) return NULL; dialect = _call_dialect(dialect_obj, kwargs); if (dialect == NULL) return NULL; if (PyDict_SetItem(_csvstate_global->dialects, name_obj, dialect) < 0) { Py_DECREF(dialect); return NULL; } Py_DECREF(dialect); Py_RETURN_NONE; }
static int parse_weakref_init_args(char *funcname, PyObject *args, PyObject *kwargs, PyObject **obp, PyObject **callbackp) { /* XXX Should check that kwargs == NULL or is empty. */ return PyArg_UnpackTuple(args, funcname, 1, 2, obp, callbackp); }
static PyObject * time_ctime(PyObject *self, PyObject *args) { PyObject *ot = NULL; time_t tt; struct tm *timeptr; if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot)) return NULL; if (ot == NULL || ot == Py_None) tt = time(NULL); else { double dt = PyFloat_AsDouble(ot); if (PyErr_Occurred()) return NULL; tt = _PyTime_DoubleToTimet(dt); if (tt == (time_t)-1 && PyErr_Occurred()) return NULL; } timeptr = localtime(&tt); if (timeptr == NULL) { PyErr_SetString(PyExc_ValueError, "unconvertible time"); return NULL; } return _asctime(timeptr); }
static int wrap_init(PyObject *self, PyObject *args, PyObject *kwds) { int result = -1; PyObject *object; if (PyArg_UnpackTuple(args, "__init__", 1, 1, &object)) { ProxyObject *wrapper = (ProxyObject *)self; if (kwds != NULL && PyDict_Size(kwds) != 0) { PyErr_SetString(PyExc_TypeError, "proxy.__init__ does not accept keyword args"); return -1; } /* If the object in this proxy is not the one we * received in args, replace it with the new one. */ if (wrapper->proxy_object != object) { PyObject *temp = wrapper->proxy_object; Py_INCREF(object); wrapper->proxy_object = object; Py_DECREF(temp); } result = 0; } return result; }
static PyObject * cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *it; PyObject *iterable; PyObject *saved; cycleobject *lz; if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable)) return NULL; /* Get iterator. */ it = PyObject_GetIter(iterable); if (it == NULL) return NULL; saved = PyList_New(0); if (saved == NULL) { Py_DECREF(it); return NULL; } /* create cycleobject structure */ lz = (cycleobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(it); Py_DECREF(saved); return NULL; } lz->it = it; lz->saved = saved; lz->firstpass = 0; return (PyObject *)lz; }
static PyObject * starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *func, *seq; PyObject *it; starmapobject *lz; if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq)) return NULL; /* Get iterator. */ it = PyObject_GetIter(seq); if (it == NULL) return NULL; /* create starmapobject structure */ lz = (starmapobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(it); return NULL; } Py_INCREF(func); lz->func = func; lz->it = it; return (PyObject *)lz; }
static PyObject * reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { Py_ssize_t n; PyObject *seq; reversedobject *ro; if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) ) return NULL; if (PyObject_HasAttrString(seq, "__reversed__")) return PyObject_CallMethod(seq, "__reversed__", NULL); if (!PySequence_Check(seq)) { PyErr_SetString(PyExc_TypeError, "argument to reversed() must be a sequence"); return NULL; } n = PySequence_Size(seq); if (n == -1) return NULL; ro = (reversedobject *)type->tp_alloc(type, 0); if (ro == NULL) return NULL; ro->index = n-1; Py_INCREF(seq); ro->seq = seq; return (PyObject *)ro; }
static PyObject * dict_setdefault(PyObject *_self, PyObject *args) { attr_dir_object *self = (attr_dir_object*)_self; PyObject *key, *failobj; PyObject *val = NULL; kdump_ctx *ctx; kdump_attr_ref_t ref; kdump_attr_t attr; kdump_status status; failobj = Py_None; if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj)) return NULL; if (get_attribute(self, key, &ref) <= 0) return NULL; ctx = self->kdumpfile->ctx; status = kdump_attr_ref_get(ctx, &ref, &attr); if (status == kdump_ok) val = attr_new(self->kdumpfile, &ref, &attr); else if (status == kdump_nodata) val = (set_attribute(self, &ref, failobj) == 0) ? failobj : NULL; else { PyErr_SetString(exception_map(status), kdump_err_str(ctx)); val = NULL; } kdump_attr_unref(ctx, &ref); Py_XINCREF(val); return val; }
static PyObject* sllist_insertbefore(SLListObject* self, PyObject* arg) { PyObject* value = NULL; PyObject* after = NULL; PyObject* list_ref; SLListNodeObject* new_node; SLListNodeObject* prev; if (!PyArg_UnpackTuple(arg, "insertbefore", 2, 2, &value, &after)) return NULL; if (!PyObject_TypeCheck(after, &SLListNodeType)) { PyErr_SetString(PyExc_TypeError, "Argument is not an sllistnode"); return NULL; } if (PyObject_TypeCheck(value, &SLListNodeType)) value = ((SLListNodeObject*)value)->value; if (after == Py_None) { PyErr_SetString(PyExc_ValueError, "sllistnode does not belong to a list"); return NULL; } list_ref = PyWeakref_GetObject( ((SLListNodeObject*)after)->list_weakref); if (list_ref != (PyObject*)self) { PyErr_SetString(PyExc_ValueError, "sllistnode belongs to another list"); return NULL; } new_node = sllistnode_create(Py_None, value, (PyObject*)self); /* getting prev node for this from arg*/ prev = sllist_get_prev(self, (SLListNodeObject*)after); /* putting new node in created gap, not first and exists */ if((PyObject*)prev != Py_None && prev != NULL) { ((SLListNodeObject*)prev)->next = (PyObject*)new_node; new_node->next = after; } else { new_node->next = after; self->first = (PyObject*)new_node; } /* new_node->next = ((SLListNodeObject*)after)->next; */ /* ((SLListNodeObject*)before)->next = (PyObject*)new_node; */ ++self->size; Py_INCREF((PyObject*)new_node); return (PyObject*)new_node; }
static PyObject* sllistiterator_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { SLListIteratorObject* self; PyObject* owner_list = NULL; if (!PyArg_UnpackTuple(args, "__new__", 1, 1, &owner_list)) return NULL; if (!PyObject_TypeCheck(owner_list, &SLListType)) { PyErr_SetString(PyExc_TypeError, "sllist argument expected"); return NULL; } self = (SLListIteratorObject*)type->tp_alloc(type, 0); if (self == NULL) return NULL; self->list = (SLListObject*)owner_list; self->current_node = self->list->first; Py_INCREF(self->list); Py_INCREF(self->current_node); return (PyObject*)self; }
static int BaseRowProxy_init(BaseRowProxy *self, PyObject *args, PyObject *kwds) { PyObject *parent, *row, *processors, *keymap; if (!PyArg_UnpackTuple(args, "BaseRowProxy", 4, 4, &parent, &row, &processors, &keymap)) return -1; Py_INCREF(parent); self->parent = parent; if (!PySequence_Check(row)) { PyErr_SetString(PyExc_TypeError, "row must be a sequence"); return -1; } Py_INCREF(row); self->row = row; if (!PyList_CheckExact(processors)) { PyErr_SetString(PyExc_TypeError, "processors must be a list"); return -1; } Py_INCREF(processors); self->processors = processors; if (!PyDict_CheckExact(keymap)) { PyErr_SetString(PyExc_TypeError, "keymap must be a dict"); return -1; } Py_INCREF(keymap); self->keymap = keymap; return 0; }
static PyObject * time_ctime(PyObject *self, PyObject *args) { PyObject *ot = NULL; time_t tt; char *p; if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot)) return NULL; if (ot == NULL || ot == Py_None) tt = time(NULL); else { double dt = PyFloat_AsDouble(ot); if (PyErr_Occurred()) return NULL; tt = _PyTime_DoubleToTimet(dt); if (tt == (time_t)-1 && PyErr_Occurred()) return NULL; } p = ctime(&tt); if (p == NULL) { PyErr_SetString(PyExc_ValueError, "unconvertible time"); return NULL; } if (p[24] == '\n') p[24] = '\0'; return PyString_FromString(p); }
static PyObject * heapreplace_internal(PyObject *args, int siftup_func(PyListObject *, Py_ssize_t)) { PyObject *heap, *item, *returnitem; if (!PyArg_UnpackTuple(args, "heapreplace", 2, 2, &heap, &item)) return NULL; if (!PyList_Check(heap)) { PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); return NULL; } if (PyList_GET_SIZE(heap) < 1) { PyErr_SetString(PyExc_IndexError, "index out of range"); return NULL; } returnitem = PyList_GET_ITEM(heap, 0); Py_INCREF(item); PyList_SET_ITEM(heap, 0, item); if (siftup_func((PyListObject *)heap, 0) == -1) { Py_DECREF(returnitem); return NULL; } return returnitem; }
static PyObject * attr_dir_get(PyObject *_self, PyObject *args) { attr_dir_object *self = (attr_dir_object*)_self; PyObject *key, *failobj; kdump_ctx *ctx; kdump_attr_ref_t ref; kdump_attr_t attr; kdump_status status; int res; failobj = Py_None; if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj)) return NULL; res = lookup_attribute(self, key, &ref); if (res < 0) return NULL; else if (res == 0) goto notfound; ctx = self->kdumpfile->ctx; status = kdump_attr_ref_get(ctx, &ref, &attr); if (status == kdump_ok) return attr_new(self->kdumpfile, &ref, &attr); if (status != kdump_nodata) { PyErr_SetString(exception_map(status), kdump_err_str(ctx)); return NULL; } notfound: Py_INCREF(failobj); return failobj; }
static PyObject* _tnetstring_pop(PyObject* self, PyObject *args) { PyObject *string, *val, *rest; char *data, *remain; size_t len; if(!PyArg_UnpackTuple(args, "pop", 1, 1, &string)) { return NULL; } if(!PyString_Check(string)) { PyErr_SetString(PyExc_TypeError, "arg must be a string"); return NULL; } Py_INCREF(string); data = PyString_AS_STRING(string); len = PyString_GET_SIZE(string); val = tns_parse(data, len, &remain); Py_DECREF(string); if(val == NULL) { return NULL; } rest = PyString_FromStringAndSize(remain, len-(remain-data)); return PyTuple_Pack(2, val, rest); }
static PyObject* _tnetstring_loads(PyObject* self, PyObject *args) { PyObject *string, *val; char *data; size_t len; if(!PyArg_UnpackTuple(args, "loads", 1, 1, &string)) { return NULL; } if(!PyString_Check(string)) { PyErr_SetString(PyExc_TypeError, "arg must be a string"); return NULL; } Py_INCREF(string); data = PyString_AS_STRING(string); len = PyString_GET_SIZE(string); val = tns_parse(data, len, NULL); Py_DECREF(string); if(val == NULL) { return NULL; } return val; }
// filter_function checks if the value should be filtered. If it is a // SanitizedPlaceholder or the placeholder_function has a skip_filter // annotation, there is no need to filter. Otherwise, call // self._filter_function. static PyObject * filter_function(PyObject *self, PyObject *args) { PyObject *value; PyObject *fn = Py_None; if (!PyArg_UnpackTuple(args, "filter_function", 1, 2, &value, &fn)) { return NULL; } if (Py_TYPE(value) == baked_SanitizedPlaceholder) { Py_INCREF(value); return value; } if (fn != Py_None) { PyObject *is_skip_filter = PyObject_GetAttr(fn, Skip_Filter_PyString); if (is_skip_filter == NULL) { PyErr_Clear(); } else if (PyObject_IsTrue(is_skip_filter)) { Py_DECREF(is_skip_filter); Py_INCREF(value); return value; } else { Py_DECREF(is_skip_filter); } } // TODO: Manually get the function and call it to avoid tuple // creation in PyObject_CallMethodObjArgs. return PyObject_CallMethodObjArgs(self, filter_function_name, value, NULL); }
static PyObject* sys_excepthook(PyObject* self, PyObject* args) noexcept { PyObject* exc, *value, *tb; if (!PyArg_UnpackTuple(args, "excepthook", 3, 3, &exc, &value, &tb)) return NULL; PyErr_Display(exc, value, tb); Py_INCREF(Py_None); return Py_None; }
PyObject * getattribute(PyObject *self, PyObject *args) { PyObject *target, *name; if (!PyArg_UnpackTuple(args, "", 2, 2, &target, &name)) return NULL; return PyObject_GenericGetAttr(target, name); }
static PyObject * py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { SHA3object *self = NULL; Py_buffer buf = {NULL, NULL}; HashReturn res; PyObject *data = NULL; if (!_PyArg_NoKeywords(_PyType_Name(type), kwargs)) { return NULL; } if (!PyArg_UnpackTuple(args, _PyType_Name(type), 0, 1, &data)) { return NULL; } self = newSHA3object(type); if (self == NULL) { goto error; } if (type == &SHA3_224type) { res = Keccak_HashInitialize_SHA3_224(&self->hash_state); } else if (type == &SHA3_256type) { res = Keccak_HashInitialize_SHA3_256(&self->hash_state); } else if (type == &SHA3_384type) { res = Keccak_HashInitialize_SHA3_384(&self->hash_state); } else if (type == &SHA3_512type) { res = Keccak_HashInitialize_SHA3_512(&self->hash_state); #ifdef PY_WITH_KECCAK } else if (type == &Keccak_224type) { res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); } else if (type == &Keccak_256type) { res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); } else if (type == &Keccak_384type) { res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); } else if (type == &Keccak_512type) { res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); #endif } else if (type == &SHAKE128type) { res = Keccak_HashInitialize_SHAKE128(&self->hash_state); } else if (type == &SHAKE256type) { res = Keccak_HashInitialize_SHAKE256(&self->hash_state); } else { PyErr_BadInternalCall(); goto error; } if (data) { GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); if (buf.len >= HASHLIB_GIL_MINSIZE) { /* invariant: New objects can't be accessed by other code yet, * thus it's safe to release the GIL without locking the object. */ Py_BEGIN_ALLOW_THREADS res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); Py_END_ALLOW_THREADS } else {
static PyObject * proxy_get(proxyobject *pp, PyObject *args) { PyObject *key, *def = Py_None; if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) return NULL; return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def); }