def PyErr_SetExcInfo(space, py_type, py_value, py_traceback): """---Cython extension--- Set the exception info, as known from ``sys.exc_info()``. This refers to an exception that was already caught, not to an exception that was freshly raised. This function steals the references of the arguments. To clear the exception state, pass *NULL* for all three arguments. For general rules about the three arguments, see :c:func:`PyErr_Restore`. .. note:: This function is not normally used by code that wants to handle exceptions. Rather, it can be used when code needs to save and restore the exception state temporarily. Use :c:func:`PyErr_GetExcInfo` to read the exception state. """ w_type = get_w_obj_and_decref(space, py_type) w_value = get_w_obj_and_decref(space, py_value) w_traceback = get_w_obj_and_decref(space, py_traceback) if w_value is None or space.is_w(w_value, space.w_None): operror = None else: tb = None if w_traceback is not None: try: tb = pytraceback.check_traceback(space, w_traceback, '?') except OperationError: # catch and ignore bogus objects pass operror = OperationError(w_type, w_value, tb) # ec = space.getexecutioncontext() ec.set_sys_exc_info(operror)
def test_getitem(self, space, api): thelist = [8, 7, 6, 5, 4, 3, 2, 1] w_l = space.wrap(thelist) py_result = api.PySequence_GetItem(w_l, 4) result = get_w_obj_and_decref(space, py_result) assert space.is_true(space.eq(result, space.wrap(4))) py_result = api.PySequence_ITEM(w_l, 4) result = get_w_obj_and_decref(space, py_result) assert space.is_true(space.eq(result, space.wrap(4))) with raises_w(space, IndexError): PySequence_GetItem(space, w_l, 9000)
def test_setitemstring(self, space, api): w_d = space.newdict() key = rffi.str2charp("key") api.PyMapping_SetItemString(w_d, key, space.wrap(42)) assert 42 == space.unwrap( get_w_obj_and_decref(space, api.PyMapping_GetItemString(w_d, key))) rffi.free_charp(key)
def test_getitem(self, space, api): w_t = space.wrap((1, 2, 3, 4, 5)) assert space.unwrap(get_w_obj_and_decref(space, api.PyObject_GetItem(w_t, space.wrap(3)))) == 4 w_d = space.newdict() space.setitem(w_d, space.wrap("a key!"), space.wrap(72)) assert space.unwrap(get_w_obj_and_decref(space, api.PyObject_GetItem(w_d, space.wrap("a key!")))) == 72 assert api.PyObject_SetItem(w_d, space.wrap("key"), space.w_None) == 0 assert space.getitem(w_d, space.wrap("key")) is space.w_None assert api.PyObject_DelItem(w_d, space.wrap("key")) == 0 with raises_w(space, KeyError): PyObject_GetItem(space, w_d, space.wrap("key"))
def test_intobject(self, space): state = space.fromcache(State) assert PyInt_Check(space, space.wrap(3)) assert PyInt_Check(space, space.w_True) assert not PyInt_Check(space, space.wrap((1, 2, 3))) for i in [3, -5, -1, -sys.maxint, sys.maxint - 1]: x = PyInt_AsLong(space, space.wrap(i)) y = PyInt_AS_LONG(space, space.wrap(i)) assert x == i assert y == i py_x = state.C.PyInt_FromLong(x + 1) w_x = get_w_obj_and_decref(space, py_x) assert space.type(w_x) is space.w_int assert space.eq_w(w_x, space.wrap(i + 1)) with raises_w(space, TypeError): PyInt_AsLong(space, space.w_None) with raises_w(space, TypeError): PyInt_AsLong(space, None) assert PyInt_AsUnsignedLong(space, space.wrap(sys.maxint)) == sys.maxint with raises_w(space, ValueError): PyInt_AsUnsignedLong(space, space.wrap(-5)) assert (PyInt_AsUnsignedLongMask(space, space.wrap(sys.maxint)) == sys.maxint) assert (PyInt_AsUnsignedLongMask(space, space.wrap(10**30)) == 10**30 % ((sys.maxint + 1) * 2)) assert (PyInt_AsUnsignedLongLongMask(space, space.wrap( sys.maxint)) == sys.maxint) assert (PyInt_AsUnsignedLongLongMask(space, space.wrap( 10**30)) == 10**30 % (2**64))
def test_getattr(self, space): charp1 = rffi.str2charp("__len__") charp2 = rffi.str2charp("not_real") assert get_w_obj_and_decref(space, PyObject_GetAttrString(space, space.wrap(""), charp1)) with raises_w(space, AttributeError): PyObject_GetAttrString(space, space.wrap(""), charp2) with raises_w(space, AttributeError): PyObject_DelAttrString(space, space.wrap(""), charp1) rffi.free_charp(charp1) rffi.free_charp(charp2) assert get_w_obj_and_decref(space, PyObject_GetAttr(space, space.wrap(""), space.wrap("__len__"))) with raises_w(space, AttributeError): PyObject_DelAttr(space, space.wrap(""), space.wrap("__len__"))
def PyErr_SetExcInfo(space, py_type, py_value, py_traceback): """ Set the exception info, as known from ``sys.exc_info()``. This refers to an exception that was already caught, not to an exception that was freshly raised. This function steals the references of the arguments. To clear the exception state, pass *NULL* for all three arguments. For general rules about the three arguments, see :c:func:`PyErr_Restore`. .. note:: This function is not normally used by code that wants to handle exceptions. Rather, it can be used when code needs to save and restore the exception state temporarily. Use :c:func:`PyErr_GetExcInfo` to read the exception state. """ w_type = get_w_obj_and_decref(space, py_type) w_value = get_w_obj_and_decref(space, py_value) w_traceback = get_w_obj_and_decref(space, py_traceback) # ec = space.getexecutioncontext() ec.set_sys_exc_info3(w_type, w_value, w_traceback)
def test_lookup(self, space): w_instance = space.appexec([], """(): class C: def __init__(self): self.x = None def f(self): pass return C() """) assert PyInstance_Check(space, w_instance) py_obj = PyObject_GetAttr(space, w_instance, space.wrap('x')) assert get_w_obj_and_decref(space, py_obj) is space.w_None assert _PyInstance_Lookup(space, w_instance, space.wrap('x')) is space.w_None assert _PyInstance_Lookup(space, w_instance, space.wrap('y')) is None # getattr returns a bound method py_obj = PyObject_GetAttr(space, w_instance, space.wrap('f')) assert not isinstance(get_w_obj_and_decref(space, py_obj), Function) # _PyInstance_Lookup returns the raw descriptor assert isinstance( _PyInstance_Lookup(space, w_instance, space.wrap('f')), Function)
def PyErr_Restore(space, py_type, py_value, py_traceback): """Set the error indicator from the three objects. If the error indicator is already set, it is cleared first. If the objects are NULL, the error indicator is cleared. Do not pass a NULL type and non-NULL value or traceback. The exception type should be a class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems later.) This call takes away a reference to each object: you must own a reference to each object before the call and after the call you no longer own these references. (If you don't understand this, don't use this function. I warned you.) This function is normally only used by code that needs to save and restore the error indicator temporarily; use PyErr_Fetch() to save the current exception state.""" state = space.fromcache(State) w_type = get_w_obj_and_decref(space, py_type) w_value = get_w_obj_and_decref(space, py_value) w_traceback = get_w_obj_and_decref(space, py_traceback) # XXX do something with w_traceback if w_type is None: state.clear_exception() return state.set_exception(OperationError(w_type, w_value))
def PyBytes_Concat(space, ref, w_newpart): """Create a new string object in *string containing the contents of newpart appended to string; the caller will own the new reference. The reference to the old value of string will be stolen. If the new string cannot be created, the old reference to string will still be discarded and the value of *string will be set to NULL; the appropriate exception will be set.""" old = ref[0] if not old: return ref[0] = lltype.nullptr(PyObject.TO) w_str = get_w_obj_and_decref(space, old) if w_newpart is not None and PyBytes_Check(space, old): # XXX: should use buffer protocol w_newstr = space.add(w_str, w_newpart) ref[0] = make_ref(space, w_newstr)
def test_run_string(self, space): def run(code, start, w_globals, w_locals): buf = rffi.str2charp(code) try: return PyRun_String(space, buf, start, w_globals, w_locals) finally: rffi.free_charp(buf) w_globals = space.newdict() assert 42 * 43 == space.unwrap( run("42 * 43", Py_eval_input, w_globals, w_globals)) assert PyObject_Size(space, w_globals) == 0 assert run("a = 42 * 43", Py_single_input, w_globals, w_globals) == space.w_None py_obj = PyObject_GetItem(space, w_globals, space.wrap("a")) assert 42 * 43 == space.unwrap(get_w_obj_and_decref(space, py_obj))
def PyString_Concat(space, ref, w_newpart): """Create a new string object in *string containing the contents of newpart appended to string; the caller will own the new reference. The reference to the old value of string will be stolen. If the new string cannot be created, the old reference to string will still be discarded and the value of *string will be set to NULL; the appropriate exception will be set.""" old = ref[0] if not old: return ref[0] = lltype.nullptr(PyObject.TO) w_str = get_w_obj_and_decref(space, old) if w_newpart is not None and PyString_Check(space, old): # xxx if w_newpart is not a string or unicode or bytearray, # this might call __radd__() on it, whereas CPython raises # a TypeError in this case. w_newstr = space.add(w_str, w_newpart) ref[0] = make_ref(space, w_newstr)
def PyString_Concat(space, ref, w_newpart): """Create a new string object in *string containing the contents of newpart appended to string; the caller will own the new reference. The reference to the old value of string will be stolen. If the new string cannot be created, the old reference to string will still be discarded and the value of *string will be set to NULL; the appropriate exception will be set.""" old = ref[0] if not old: return ref[0] = lltype.nullptr(PyObject.TO) w_str = get_w_obj_and_decref(space, old) if w_newpart is not None and PyString_Check(space, old): # xxx if w_newpart is not a string or unicode or bytearray, # this might call __radd__() on it, whereas CPython raises # a TypeError in this case. w_newstr = space.add(w_str, w_newpart) ref[0] = make_ref(space, w_newstr)