from pypy.module.cpyext.typeobjectdefs import ( PyTypeObjectPtr, PyTypeObject, PyGetSetDef, PyMemberDef, newfunc, PyNumberMethods, PyMappingMethods, PySequenceMethods, PyBufferProcs) from pypy.module.cpyext.slotdefs import ( slotdefs_for_tp_slots, slotdefs_for_wrappers, get_slot_tp_function) from pypy.interpreter.buffer import Buffer from pypy.interpreter.error import OperationError from pypy.rlib.rstring import rsplit from pypy.rlib.objectmodel import specialize from pypy.module.__builtin__.abstractinst import abstract_issubclass_w from pypy.module.__builtin__.interp_classobj import W_ClassObject from pypy.rlib import jit WARN_ABOUT_MISSING_SLOT_FUNCTIONS = False PyType_Check, PyType_CheckExact = build_type_checkers("Type", "w_type") PyHeapTypeObjectStruct = lltype.ForwardReference() PyHeapTypeObject = lltype.Ptr(PyHeapTypeObjectStruct) PyHeapTypeObjectFields = ( ("ht_type", PyTypeObject), ("ht_name", PyObject), ("as_number", PyNumberMethods), ("as_mapping", PyMappingMethods), ("as_sequence", PySequenceMethods), ("as_buffer", PyBufferProcs), ) cpython_struct("PyHeapTypeObject", PyHeapTypeObjectFields, PyHeapTypeObjectStruct, level=2) class W_GetSetPropertyEx(GetSetProperty):
from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( cpython_api, CANNOT_FAIL, build_type_checkers, Py_ssize_t, Py_ssize_tP, CONST_STRING) from pypy.module.cpyext.pyobject import PyObject, PyObjectP, as_pyobj from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.interpreter.error import OperationError from rpython.rlib.objectmodel import specialize @cpython_api([], PyObject) def PyDict_New(space): return space.newdict() PyDict_Check, PyDict_CheckExact = build_type_checkers("Dict") @cpython_api([PyObject, PyObject], PyObject, error=CANNOT_FAIL, result_borrowed=True) def PyDict_GetItem(space, w_dict, w_key): try: w_res = space.getitem(w_dict, w_key) except: return None # NOTE: this works so far because all our dict strategies store # *values* as full objects, which stay alive as long as the dict is # alive and not modified. So we can return a borrowed ref. # XXX this is wrong with IntMutableCell. Hope it works... return w_res @cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1) def PyDict_SetItem(space, w_dict, w_key, w_obj): if PyDict_Check(space, w_dict):
PyTupleObject = lltype.Ptr(PyTupleObjectStruct) ObjectItems = rffi.CArray(PyObject) PyTupleObjectFields = PyVarObjectFields + \ (("ob_item", ObjectItems),) cpython_struct("PyTupleObject", PyTupleObjectFields, PyTupleObjectStruct) @bootstrap_function def init_stringobject(space): "Type description of PyTupleObject" make_typedescr(space.w_tuple.layout.typedef, basestruct=PyTupleObject.TO, attach=tuple_attach, dealloc=tuple_dealloc, realize=tuple_realize) PyTuple_Check, PyTuple_CheckExact = build_type_checkers("Tuple") def tuple_check_ref(space, ref): w_type = from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) return (w_type is space.w_tuple or space.issubtype_w(w_type, space.w_tuple)) def new_empty_tuple(space, length): """ Allocate a PyTupleObject and its array of PyObject *, but without a corresponding interpreter object. The array may be mutated, until tuple_realize() is called. Refcount of the result is 1. """ typedescr = get_typedescr(space.w_tuple.layout.typedef) py_obj = typedescr.allocate(space, space.w_tuple, length) py_tup = rffi.cast(PyTupleObject, py_obj)
@slot_function([PyObject], lltype.Void) def dict_dealloc(space, py_obj): py_dict = rffi.cast(PyDictObject, py_obj) decref(space, py_dict.c__tmpkeys) py_dict.c__tmpkeys = lltype.nullptr(PyObject.TO) _dealloc(space, py_obj) @cpython_api([], PyObject) def PyDict_New(space): return space.newdict() PyDict_Check, PyDict_CheckExact = build_type_checkers("Dict") @cpython_api([PyObject, PyObject], PyObject, error=CANNOT_FAIL, result_borrowed=True) def PyDict_GetItem(space, w_dict, w_key): try: w_res = space.getitem(w_dict, w_key) except: return None # NOTE: this works so far because all our dict strategies store # *values* as full objects, which stay alive as long as the dict is # alive and not modified. So we can return a borrowed ref. # XXX this is wrong with IntMutableCell. Hope it works...
PyTupleObject = lltype.Ptr(PyTupleObjectStruct) ObjectItems = rffi.CArray(PyObject) PyTupleObjectFields = PyVarObjectFields + \ (("ob_item", ObjectItems),) cpython_struct("PyTupleObject", PyTupleObjectFields, PyTupleObjectStruct) @bootstrap_function def init_stringobject(space): "Type description of PyTupleObject" make_typedescr(space.w_tuple.layout.typedef, basestruct=PyTupleObject.TO, attach=tuple_attach, dealloc=tuple_dealloc, realize=tuple_realize) PyTuple_Check, PyTuple_CheckExact = build_type_checkers("Tuple") def tuple_check_ref(space, ref): w_type = from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) return (w_type is space.w_tuple or space.issubtype_w(w_type, space.w_tuple)) def new_empty_tuple(space, length): """ Allocate a PyTupleObject and its array of PyObject *, but without a corresponding interpreter object. The array may be mutated, until tuple_realize() is called. Refcount of the result is 1. """ typedescr = get_typedescr(space.w_tuple.layout.typedef) py_obj = typedescr.allocate(space, space.w_tuple, length) py_tup = rffi.cast(PyTupleObject, py_obj)
PyBytesObjectStruct = lltype.ForwardReference() PyBytesObject = lltype.Ptr(PyBytesObjectStruct) PyBytesObjectFields = PyObjectFields + \ (("buffer", rffi.CCHARP), ("size", Py_ssize_t)) cpython_struct("PyBytesObject", PyBytesObjectFields, PyBytesObjectStruct) @bootstrap_function def init_bytesobject(space): "Type description of PyBytesObject" make_typedescr(space.w_str.instancetypedef, basestruct=PyBytesObject.TO, attach=bytes_attach, dealloc=bytes_dealloc, realize=bytes_realize) PyBytes_Check, PyBytes_CheckExact = build_type_checkers("Bytes", "w_bytes") def new_empty_str(space, length): """ Allocates a PyBytesObject and its buffer, but without a corresponding interpreter object. The buffer may be mutated, until bytes_realize() is called. """ typedescr = get_typedescr(space.w_bytes.instancetypedef) py_obj = typedescr.allocate(space, space.w_bytes) py_str = rffi.cast(PyBytesObject, py_obj) buflen = length + 1 py_str.c_size = length py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw', zero=True)
from pypy.objspace.std.dictproxyobject import W_DictProxyObject from pypy.module.cpyext.api import cpython_api, build_type_checkers from pypy.module.cpyext.pyobject import PyObject PyDictProxy_Check, PyDictProxy_CheckExact = build_type_checkers( "DictProxy", W_DictProxyObject) @cpython_api([PyObject], PyObject) def PyDictProxy_New(space, w_dict): return W_DictProxyObject(w_dict)
from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.cpyext.api import ( cpython_api, PyObject, build_type_checkers, Py_ssize_t, CONST_STRING, ADDR, CANNOT_FAIL) from pypy.objspace.std.longobject import W_LongObject from pypy.interpreter.error import OperationError from pypy.module.cpyext.intobject import PyInt_AsUnsignedLongMask from pypy.rlib.rbigint import rbigint from pypy.rlib.rarithmetic import intmask PyLong_Check, PyLong_CheckExact = build_type_checkers("Long") @cpython_api([lltype.Signed], PyObject) def PyLong_FromLong(space, val): """Return a new PyLongObject object from v, or NULL on failure.""" return space.newlong(val) @cpython_api([Py_ssize_t], PyObject) def PyLong_FromSsize_t(space, val): """Return a new PyLongObject object from a C Py_ssize_t, or NULL on failure. """ return space.newlong(val) @cpython_api([rffi.LONGLONG], PyObject) def PyLong_FromLongLong(space, val): """Return a new PyLongObject object from a C long long, or NULL on failure.""" return space.wrap(val)
from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import (cpython_api, PyObject, CANNOT_FAIL, build_type_checkers) # Inheriting from bool isn't actually possible. PyBool_Check = build_type_checkers("Bool")[1] @cpython_api([rffi.LONG], PyObject) def PyBool_FromLong(space, value): if value != 0: return space.w_True return space.w_False
from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( CANNOT_FAIL, cpython_api, PyObject, build_type_checkers, CONST_STRING) from pypy.interpreter.error import OperationError from pypy.rlib.rstruct import runpack PyFloat_Check, PyFloat_CheckExact = build_type_checkers("Float") @cpython_api([lltype.Float], PyObject) def PyFloat_FromDouble(space, value): return space.wrap(value) @cpython_api([PyObject], lltype.Float, error=-1) def PyFloat_AsDouble(space, w_obj): return space.float_w(space.float(w_obj)) @cpython_api([PyObject], lltype.Float, error=CANNOT_FAIL) def PyFloat_AS_DOUBLE(space, w_float): """Return a C double representation of the contents of w_float, but without error checking.""" return space.float_w(w_float) @cpython_api([PyObject], PyObject) def PyNumber_Float(space, w_obj): """ Returns the o converted to a float object on success, or NULL on failure. This is the equivalent of the Python expression float(o).""" return space.call_function(space.w_float, w_obj) @cpython_api([PyObject, rffi.CCHARPP], PyObject) def PyFloat_FromString(space, w_obj, _):
from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( PyObjectFields, CANNOT_FAIL, cpython_api, bootstrap_function, cpython_struct, build_type_checkers) from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref, Py_DecRef, make_typedescr from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.module.__builtin__.interp_classobj import W_ClassObject, W_InstanceObject PyClass_Check, PyClass_CheckExact = build_type_checkers("Class", W_ClassObject) PyInstance_Check, PyInstance_CheckExact = build_type_checkers("Instance", W_InstanceObject) @cpython_api([PyObject, PyObject], PyObject) def PyInstance_NewRaw(space, w_class, w_dict): """Create a new instance of a specific class without calling its constructor. class is the class of new object. The dict parameter will be used as the object's __dict__; if NULL, a new dictionary will be created for the instance.""" if not isinstance(w_class, W_ClassObject): return PyErr_BadInternalCall(space) w_result = w_class.instantiate(space) if w_dict is not None: w_result.setdict(space, w_dict) return w_result @cpython_api([PyObject, PyObject, PyObject], PyObject) def PyInstance_New(space, w_cls, w_arg, w_kw): """Create a new instance of a specific class. The parameters arg and kw are used as the positional and keyword parameters to the object's constructor.""" return space.call(w_cls, w_arg, w_kw) @cpython_api([PyObject, PyObject], PyObject, error=CANNOT_FAIL)
PyBytesObjectFields = PyObjectFields + \ (("buffer", rffi.CCHARP), ("size", Py_ssize_t)) cpython_struct("PyBytesObject", PyBytesObjectFields, PyBytesObjectStruct) @bootstrap_function def init_bytesobject(space): "Type description of PyBytesObject" make_typedescr(space.w_str.instancetypedef, basestruct=PyBytesObject.TO, attach=bytes_attach, dealloc=bytes_dealloc, realize=bytes_realize) PyBytes_Check, PyBytes_CheckExact = build_type_checkers("Bytes", "w_bytes") def new_empty_str(space, length): """ Allocates a PyBytesObject and its buffer, but without a corresponding interpreter object. The buffer may be mutated, until bytes_realize() is called. """ typedescr = get_typedescr(space.w_bytes.instancetypedef) py_obj = typedescr.allocate(space, space.w_bytes) py_str = rffi.cast(PyBytesObject, py_obj) buflen = length + 1 py_str.c_size = length py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO,
from pypy.module.cpyext.api import (cpython_api, Py_buffer, CANNOT_FAIL, Py_MAX_FMT, Py_MAX_NDIMS, build_type_checkers, Py_ssize_tP) from pypy.module.cpyext.pyobject import PyObject, make_ref, incref, from_ref from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rarithmetic import widen from pypy.objspace.std.memoryobject import W_MemoryView from pypy.module.cpyext.import_ import PyImport_Import PyMemoryView_Check, PyMemoryView_CheckExact = build_type_checkers("MemoryView", "w_memoryview") @cpython_api([PyObject, lltype.Ptr(Py_buffer), rffi.INT_real], rffi.INT_real, error=-1) def PyObject_GetBuffer(space, w_obj, view, flags): """Export obj into a Py_buffer, view. These arguments must never be NULL. The flags argument is a bit field indicating what kind of buffer the caller is prepared to deal with and therefore what kind of buffer the exporter is allowed to return. The buffer interface allows for complicated memory sharing possibilities, but some caller may not be able to handle all the complexity but may want to see if the exporter will let them take a simpler view to its memory. Some exporters may not be able to share memory in every possible way and may need to raise errors to signal to some consumers that something is just not possible. These errors should be a BufferError unless there is another error that is actually causing the problem. The exporter can use flags information to simplify how much of the Py_buffer structure is filled in with non-default values and/or raise an error if the object can't support a simpler view of its memory. 0 is returned on success and -1 on error.""" flags = widen(flags)
value must not be modified. """ py_int = rffi.cast(PyIntObject, py_obj) py_int.c_ob_ival = space.int_w(w_obj) def int_realize(space, obj): intval = rffi.cast(lltype.Signed, rffi.cast(PyIntObject, obj).c_ob_ival) w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type)) w_obj = space.allocate_instance(W_IntObject, w_type) w_obj.__init__(intval) track_reference(space, obj, w_obj) return w_obj PyInt_Check, PyInt_CheckExact = build_type_checkers("Int") @cpython_api([], lltype.Signed, error=CANNOT_FAIL) def PyInt_GetMax(space): """Return the system's idea of the largest integer it can handle (LONG_MAX, as defined in the system header files).""" return sys.maxint @cpython_api([lltype.Signed], PyObject) def PyInt_FromLong(space, ival): """Create a new integer object with a value of ival. """ return space.wrap(ival)
from pypy.rpython.lltypesystem import lltype, rffi from pypy.module.cpyext.api import (cpython_api, cpython_struct, PyObject, build_type_checkers) from pypy.module.cpyext.floatobject import PyFloat_AsDouble from pypy.objspace.std.complexobject import W_ComplexObject from pypy.interpreter.error import OperationError PyComplex_Check, PyComplex_CheckExact = build_type_checkers("Complex") Py_complex_t = lltype.ForwardReference() Py_complex_ptr = lltype.Ptr(Py_complex_t) Py_complex_fields = (("real", rffi.DOUBLE), ("imag", rffi.DOUBLE)) cpython_struct("Py_complex", Py_complex_fields, Py_complex_t) @cpython_api([lltype.Float, lltype.Float], PyObject) def PyComplex_FromDoubles(space, real, imag): return space.newcomplex(real, imag) @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_RealAsDouble(space, w_obj): if space.is_true(space.isinstance(w_obj, space.w_complex)): assert isinstance(w_obj, W_ComplexObject) return w_obj.realval else: return space.float_w(w_obj) @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_ImagAsDouble(space, w_obj):
from rpython.rtyper.lltypesystem import lltype, rffi from pypy.module.cpyext.api import (cpython_api, PyObject, build_type_checkers, Py_ssize_t, CONST_STRING, ADDR, CANNOT_FAIL) from pypy.objspace.std.longobject import W_LongObject from pypy.interpreter.error import OperationError from pypy.module.cpyext.intobject import PyInt_AsUnsignedLongMask from rpython.rlib.rbigint import rbigint from rpython.rlib.rarithmetic import intmask PyLong_Check, PyLong_CheckExact = build_type_checkers("Long") @cpython_api([lltype.Signed], PyObject) def PyLong_FromLong(space, val): """Return a new PyLongObject object from v, or NULL on failure.""" return space.newlong(val) @cpython_api([Py_ssize_t], PyObject) def PyLong_FromSsize_t(space, val): """Return a new PyLongObject object from a C Py_ssize_t, or NULL on failure. """ return space.newlong(val) @cpython_api([rffi.SIZE_T], PyObject) def PyLong_FromSize_t(space, val): """Return a new PyLongObject object from a C size_t, or NULL on failure.
# The only way to go between bytes and str/unicode is via encoding # and decoding. # For the convenience of C programmers, the bytes type is considered # to contain a char pointer, not an unsigned char pointer. # Expose data as a rw cchar* only through PyByteArray_AsString # Under this strategy the pointer could loose its synchronization with # the underlying space.w_bytearray if PyByteArray_Resize is called, so # hopefully the use of the pointer is short-lived PyByteArrayObjectStruct = lltype.ForwardReference() PyByteArrayObject = lltype.Ptr(PyByteArrayObjectStruct) PyByteArrayObjectFields = PyVarObjectFields cpython_struct("PyByteArrayObject", PyByteArrayObjectFields, PyByteArrayObjectStruct) PyByteArray_Check, PyByteArray_CheckExact = build_type_checkers("ByteArray", "w_bytearray") #_______________________________________________________________________ @cpython_api([PyObject], PyObject, result_is_ll=True) def PyByteArray_FromObject(space, w_obj): """Return a new bytearray object from any object, o, that implements the buffer protocol. XXX expand about the buffer protocol, at least somewhere""" w_buffer = space.call_function(space.w_bytearray, w_obj) return make_ref(space, w_buffer) @cpython_api([CONST_STRING, Py_ssize_t], PyObject, result_is_ll=True) def PyByteArray_FromStringAndSize(space, char_p, length): """Create a new bytearray object from string and its length, len. On
def init_unicodeobject(space): make_typedescr(space.w_unicode.instancetypedef, basestruct=PyUnicodeObject.TO, attach=unicode_attach, dealloc=unicode_dealloc, realize=unicode_realize) # Buffer for the default encoding (used by PyUnicde_GetDefaultEncoding) DEFAULT_ENCODING_SIZE = 100 default_encoding = lltype.malloc(rffi.CCHARP.TO, DEFAULT_ENCODING_SIZE, flavor='raw', zero=True) PyUnicode_Check, PyUnicode_CheckExact = build_type_checkers( "Unicode", "w_unicode") Py_UNICODE = lltype.UniChar def new_empty_unicode(space, length): """ Allocatse a PyUnicodeObject and its buffer, but without a corresponding interpreter object. The buffer may be mutated, until unicode_realize() is called. """ typedescr = get_typedescr(space.w_unicode.instancetypedef) py_obj = typedescr.allocate(space, space.w_unicode) py_uni = rffi.cast(PyUnicodeObject, py_obj) buflen = length + 1
from pypy.interpreter.generator import GeneratorIterator from pypy.module.cpyext.api import build_type_checkers PyGen_Check, PyGen_CheckExact = build_type_checkers("Gen", GeneratorIterator)
cpython_struct("PyCodeObject", PyCodeObjectFields, PyCodeObjectStruct) @bootstrap_function def init_functionobject(space): make_typedescr(Function.typedef, basestruct=PyFunctionObject.TO, attach=function_attach, dealloc=function_dealloc) make_typedescr(PyCode.typedef, basestruct=PyCodeObject.TO, attach=code_attach, dealloc=code_dealloc) PyFunction_Check, PyFunction_CheckExact = build_type_checkers( "Function", Function) PyMethod_Check, PyMethod_CheckExact = build_type_checkers("Method", Method) PyCode_Check, PyCode_CheckExact = build_type_checkers("Code", PyCode) def function_attach(space, py_obj, w_obj): py_func = rffi.cast(PyFunctionObject, py_obj) assert isinstance(w_obj, Function) py_func.c_func_name = make_ref(space, space.wrap(w_obj.name)) @cpython_api([PyObject], lltype.Void, header=None) def function_dealloc(space, py_obj): py_func = rffi.cast(PyFunctionObject, py_obj) Py_DecRef(space, py_func.c_func_name) from pypy.module.cpyext.object import PyObject_dealloc
from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL, build_type_checkers) from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, Py_DecRef, borrow_from, make_ref, from_ref) from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.setobject import W_SetObject, newset from pypy.objspace.std.smalltupleobject import W_SmallTupleObject PySet_Check, PySet_CheckExact = build_type_checkers("Set") @cpython_api([PyObject], PyObject) def PySet_New(space, w_iterable): """Return a new set containing objects returned by the iterable. The iterable may be NULL to create a new empty set. Return the new set on success or NULL on failure. Raise TypeError if iterable is not actually iterable. The constructor is also useful for copying a set (c=set(s)).""" if w_iterable is None: return space.call_function(space.w_set) else: return space.call_function(space.w_set, w_iterable) @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) def PySet_Add(space, w_s, w_obj): """Add key to a set instance. Does not apply to frozenset instances. Return 0 on success or -1 on failure. Raise a TypeError if the key is unhashable. Raise a MemoryError if there is no room to grow.
# XXX: needs a stricter test if not space.isinstance_w(w_instance, self.w_objclass): w_objclass = self.w_objclass assert isinstance(w_objclass, W_TypeObject) raise oefmt( space.w_TypeError, "descriptor '%s' requires a '%s' object but received a '%T'", self.name, w_objclass.name, w_instance) # # CCC: we can surely do better than this __args__ = __args__.replace_arguments(__args__.arguments_w[1:]) return self.call(space, w_instance, __args__) # PyPy addition, for Cython _, _ = build_type_checkers("MethodDescr", W_PyCMethodObject) @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyCFunction_Check(space, w_obj): from pypy.interpreter.function import BuiltinFunction if w_obj is None: return False if isinstance(w_obj, W_PyCFunctionObject): return True return isinstance(w_obj, BuiltinFunction) class W_PyCClassMethodObject(W_PyCFunctionObject): def __init__(self, space, ml, w_type): W_PyCFunctionObject.__init__(self, space, ml, w_self=None)
from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, build_type_checkers) from pypy.module.cpyext.pyobject import PyObject, borrow_from from pypy.module.cpyext.object import Py_PRINT_RAW from pypy.interpreter.error import OperationError from pypy.module._file.interp_file import W_File PyFile_Check, PyFile_CheckExact = build_type_checkers("File", W_File) @cpython_api([PyObject, rffi.INT_real], PyObject) def PyFile_GetLine(space, w_obj, n): """ Equivalent to p.readline([n]), this function reads one line from the object p. p may be a file object or any object with a readline() method. If n is 0, exactly one line is read, regardless of the length of the line. If n is greater than 0, no more than n bytes will be read from the file; a partial line can be returned. In both cases, an empty string is returned if the end of the file is reached immediately. If n is less than 0, however, one line is read regardless of length, but EOFError is raised if the end of the file is reached immediately.""" try: w_readline = space.getattr(w_obj, space.wrap('readline')) except OperationError: raise OperationError( space.w_TypeError, space.wrap( "argument must be a file, or have a readline() method.")) n = rffi.cast(lltype.Signed, n) if space.is_true(space.gt(space.wrap(n), space.wrap(0))): return space.call_function(w_readline, space.wrap(n))
from pypy.interpreter.error import OperationError from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL, build_type_checkers from pypy.module.cpyext.pyobject import PyObject, PyObjectP, Py_DecRef, borrow_from, make_ref, from_ref from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.setobject import W_SetObject, newset PySet_Check, PySet_CheckExact = build_type_checkers("Set") @cpython_api([PyObject], PyObject) def PySet_New(space, w_iterable): """Return a new set containing objects returned by the iterable. The iterable may be NULL to create a new empty set. Return the new set on success or NULL on failure. Raise TypeError if iterable is not actually iterable. The constructor is also useful for copying a set (c=set(s)).""" if w_iterable is None: return space.call_function(space.w_set) else: return space.call_function(space.w_set, w_iterable) @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) def PySet_Add(space, w_s, w_obj): """Add key to a set instance. Does not apply to frozenset instances. Return 0 on success or -1 on failure. Raise a TypeError if the key is unhashable. Raise a MemoryError if there is no room to grow. Raise a SystemError if set is an not an instance of set or its subtype.
bootstrap_function, Py_bufferP, slot_function) from pypy.module.cpyext.pyobject import (PyObject, make_ref, decref, from_ref, make_typedescr, get_typedescr, track_reference) from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rarithmetic import widen from pypy.objspace.std.memoryobject import W_MemoryView from pypy.module.cpyext.object import _dealloc from pypy.module.cpyext.import_ import PyImport_Import from pypy.module.cpyext.buffer import CPyBuffer, fq cts.parse_header(parse_dir / 'cpyext_memoryobject.h') PyMemoryViewObject = cts.gettype('PyMemoryViewObject*') PyMemoryView_Check, PyMemoryView_CheckExact = build_type_checkers("MemoryView") @bootstrap_function def init_memoryobject(space): "Type description of PyDictObject" make_typedescr( W_MemoryView.typedef, basestruct=PyMemoryViewObject.TO, attach=memory_attach, dealloc=memory_dealloc, realize=memory_realize, ) def memory_attach(space, py_obj, w_obj, w_userdata=None):
cpython_struct("PyUnicodeObject", PyUnicodeObjectFields, PyUnicodeObjectStruct) @bootstrap_function def init_unicodeobject(space): make_typedescr(space.w_unicode.layout.typedef, basestruct=PyUnicodeObject.TO, attach=unicode_attach, dealloc=unicode_dealloc, realize=unicode_realize) # Buffer for the default encoding (used by PyUnicde_GetDefaultEncoding) DEFAULT_ENCODING_SIZE = 100 default_encoding = lltype.malloc(rffi.CCHARP.TO, DEFAULT_ENCODING_SIZE, flavor='raw', zero=True) PyUnicode_Check, PyUnicode_CheckExact = build_type_checkers("Unicode", "w_unicode") Py_UNICODE = lltype.UniChar def new_empty_unicode(space, length): """ Allocate a PyUnicodeObject and its buffer, but without a corresponding interpreter object. The buffer may be mutated, until unicode_realize() is called. Refcount of the result is 1. """ typedescr = get_typedescr(space.w_unicode.layout.typedef) py_obj = typedescr.allocate(space, space.w_unicode) py_uni = rffi.cast(PyUnicodeObject, py_obj) buflen = length + 1 py_uni.c_length = length
from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import (cpython_api, CONST_STRING, FILEP, build_type_checkers) from pypy.module.cpyext.pyobject import PyObject, borrow_from from pypy.interpreter.error import OperationError from pypy.module._file.interp_file import W_File PyFile_Check, PyFile_CheckExact = build_type_checkers("File", W_File) @cpython_api([PyObject, rffi.INT_real], PyObject) def PyFile_GetLine(space, w_obj, n): """ Equivalent to p.readline([n]), this function reads one line from the object p. p may be a file object or any object with a readline() method. If n is 0, exactly one line is read, regardless of the length of the line. If n is greater than 0, no more than n bytes will be read from the file; a partial line can be returned. In both cases, an empty string is returned if the end of the file is reached immediately. If n is less than 0, however, one line is read regardless of length, but EOFError is raised if the end of the file is reached immediately.""" try: w_readline = space.getattr(w_obj, space.wrap('readline')) except OperationError: raise OperationError( space.w_TypeError, space.wrap( "argument must be a file, or have a readline() method.")) n = rffi.cast(lltype.Signed, n) if space.is_true(space.gt(space.wrap(n), space.wrap(0))):
w_self = None def __init__(self, space, ml, w_type): self.space = space self.ml = ml self.name = rffi.charp2str(ml.c_ml_name) self.w_objclass = w_type def __repr__(self): return self.space.unwrap(self.descr_method_repr()) def descr_method_repr(self): return self.getrepr(self.space, "built-in method '%s' of '%s' object" % (self.name, self.w_objclass.getname(self.space))) PyCFunction_Check, PyCFunction_CheckExact = build_type_checkers( "CFunction", W_PyCFunctionObject) class W_PyCClassMethodObject(W_PyCFunctionObject): w_self = None def __init__(self, space, ml, w_type): self.space = space self.ml = ml self.name = rffi.charp2str(ml.c_ml_name) self.w_objclass = w_type def __repr__(self): return self.space.unwrap(self.descr_method_repr()) def descr_method_repr(self): return self.getrepr(self.space, "built-in method '%s' of '%s' object" %
value must not be modified. """ py_int = rffi.cast(PyIntObject, py_obj) py_int.c_ob_ival = space.int_w(w_obj) def int_realize(space, obj): intval = rffi.cast(lltype.Signed, rffi.cast(PyIntObject, obj).c_ob_ival) w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type)) w_obj = space.allocate_instance(W_IntObject, w_type) w_obj.__init__(intval) track_reference(space, obj, w_obj) state = space.fromcache(RefcountState) state.set_lifeline(w_obj, obj) return w_obj PyInt_Check, PyInt_CheckExact = build_type_checkers("Int") @cpython_api([], lltype.Signed, error=CANNOT_FAIL) def PyInt_GetMax(space): """Return the system's idea of the largest integer it can handle (LONG_MAX, as defined in the system header files).""" return sys.maxint @cpython_api([lltype.Signed], PyObject) def PyInt_FromLong(space, ival): """Create a new integer object with a value of ival. """ return space.wrap(ival) @cpython_api([PyObject], lltype.Signed, error=-1)
def __init__(self, space, ml, w_type): self.space = space self.ml = ml self.name = rffi.charp2str(ml.c_ml_name) self.w_objclass = w_type def __repr__(self): return self.space.unwrap(self.descr_method_repr()) def descr_method_repr(self): return self.getrepr( self.space, "built-in method '%s' of '%s' object" % (self.name, self.w_objclass.getname(self.space))) PyCFunction_Check, PyCFunction_CheckExact = build_type_checkers( "CFunction", W_PyCFunctionObject) class W_PyCClassMethodObject(W_PyCFunctionObject): w_self = None def __init__(self, space, ml, w_type): self.space = space self.ml = ml self.name = rffi.charp2str(ml.c_ml_name) self.w_objclass = w_type def __repr__(self): return self.space.unwrap(self.descr_method_repr()) def descr_method_repr(self):
from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import (cpython_api, CANNOT_FAIL, Py_ssize_t, build_type_checkers) from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.module.cpyext.pyobject import Py_DecRef, PyObject, borrow_from from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError PyList_Check, PyList_CheckExact = build_type_checkers("List") @cpython_api([Py_ssize_t], PyObject) def PyList_New(space, len): """Return a new list of length len on success, or NULL on failure. If length is greater than zero, the returned list object's items are set to NULL. Thus you cannot use abstract API functions such as PySequence_SetItem() or expose the object to Python code before setting all items to a real object with PyList_SetItem(). """ return space.newlist([None] * len) @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1) def PyList_SetItem(space, w_list, index, w_item): """Set the item at index index in list to item. Return 0 on success or -1 on failure. This function "steals" a reference to item and discards a reference to an item already in the list at the affected position. """
from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import (cpython_api, CANNOT_FAIL, Py_ssize_t, build_type_checkers) from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.module.cpyext.pyobject import Py_DecRef, PyObject, borrow_from from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError PyList_Check, PyList_CheckExact = build_type_checkers("List") @cpython_api([Py_ssize_t], PyObject) def PyList_New(space, len): """Return a new list of length len on success, or NULL on failure. If length is greater than zero, the returned list object's items are set to NULL. Thus you cannot use abstract API functions such as PySequence_SetItem() or expose the object to Python code before setting all items to a real object with PyList_SetItem(). """ return space.newlist([None] * len) @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1) def PyList_SetItem(space, w_list, index, w_item): """Set the item at index index in list to item. Return 0 on success or -1 on failure. This function "steals" a reference to item and discards a reference to an item already in the list at the affected position. """
from pypy.interpreter.error import OperationError, oefmt from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL, build_type_checkers) from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, make_ref, from_ref) from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject, newset PySet_Check, PySet_CheckExact = build_type_checkers("Set") PyFrozenSet_Check, PyFrozenSet_CheckExact = build_type_checkers("FrozenSet") @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyAnySet_Check(space, w_obj): """Return true if obj is a set object, a frozenset object, or an instance of a subtype.""" return (space.isinstance_w(w_obj, space.gettypefor(W_SetObject)) or space.isinstance_w(w_obj, space.gettypefor(W_FrozensetObject))) @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyAnySet_CheckExact(space, w_obj): """Return true if obj is a set object or a frozenset object but not an instance of a subtype.""" w_obj_type = space.type(w_obj) return (space.is_w(w_obj_type, space.gettypefor(W_SetObject)) or space.is_w(w_obj_type, space.gettypefor(W_FrozensetObject))) @cpython_api([PyObject], PyObject) def PySet_New(space, w_iterable): """Return a new set containing objects returned by the iterable. The
from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( PyObjectFields, CANNOT_FAIL, cpython_api, bootstrap_function, build_type_checkers) from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref, Py_DecRef, make_typedescr from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.module.__builtin__.interp_classobj import W_ClassObject, W_InstanceObject PyClass_Check, PyClass_CheckExact = build_type_checkers("Class", W_ClassObject) PyInstance_Check, PyInstance_CheckExact = build_type_checkers("Instance", W_InstanceObject) @cpython_api([PyObject, PyObject], PyObject) def PyInstance_NewRaw(space, w_class, w_dict): """Create a new instance of a specific class without calling its constructor. class is the class of new object. The dict parameter will be used as the object's __dict__; if NULL, a new dictionary will be created for the instance.""" if not isinstance(w_class, W_ClassObject): return PyErr_BadInternalCall(space) w_result = w_class.instantiate(space) if w_dict is not None: w_result.setdict(space, w_dict) return w_result @cpython_api([PyObject, PyObject, PyObject], PyObject) def PyInstance_New(space, w_cls, w_arg, w_kw): """Create a new instance of a specific class. The parameters arg and kw are used as the positional and keyword parameters to the object's constructor.""" return space.call(w_cls, w_arg, w_kw) @cpython_api([PyObject, PyObject], PyObject, error=CANNOT_FAIL)
# and decoding. # For the convenience of C programmers, the bytes type is considered # to contain a char pointer, not an unsigned char pointer. # Expose data as a rw cchar* only through PyByteArray_AsString # Under this strategy the pointer could loose its synchronization with # the underlying space.w_bytearray if PyByteArray_Resize is called, so # hopefully the use of the pointer is short-lived PyByteArrayObjectStruct = lltype.ForwardReference() PyByteArrayObject = lltype.Ptr(PyByteArrayObjectStruct) PyByteArrayObjectFields = PyVarObjectFields cpython_struct("PyByteArrayObject", PyByteArrayObjectFields, PyByteArrayObjectStruct) PyByteArray_Check, PyByteArray_CheckExact = build_type_checkers( "ByteArray", "w_bytearray") #_______________________________________________________________________ @cpython_api([PyObject], PyObject, result_is_ll=True) def PyByteArray_FromObject(space, w_obj): """Return a new bytearray object from any object, o, that implements the buffer protocol. XXX expand about the buffer protocol, at least somewhere""" w_buffer = space.call_function(space.w_bytearray, w_obj) return make_ref(space, w_buffer) @cpython_api([CONST_STRING, Py_ssize_t], PyObject, result_is_ll=True)
bootstrap_function, slot_function) from pypy.module.cpyext.pyobject import PyObject, make_typedescr, as_pyobj from pypy.module.cpyext.object import _dealloc cts.parse_header(parse_dir / 'cpyext_genobject.h') @bootstrap_function def init_genobject(space): make_typedescr(GeneratorIterator.typedef, basestruct=cts.gettype('PyGenObject'), attach=gi_attach, dealloc=gi_dealloc) PyGen_Check, PyGen_CheckExact = build_type_checkers("Gen", GeneratorIterator) _, PyCoro_CheckExact = build_type_checkers("Coro", Coroutine) def gi_attach(space, py_obj, w_obj, w_userdata=None): assert isinstance(w_obj, GeneratorIterator) cts.cast('PyGenObject*', py_obj).c_gi_code = as_pyobj(space, w_obj.pycode) def gi_realize(space, py_obj): raise NotImplementedError( "PyPy doesn't support creation of generators from the C-API.") @slot_function([PyObject], lltype.Void)
py_slice.c_start = make_ref(space, w_obj.w_start) py_slice.c_stop = make_ref(space, w_obj.w_stop) py_slice.c_step = make_ref(space, w_obj.w_step) @cpython_api([PyObject], lltype.Void, header=None) def slice_dealloc(space, py_obj): """Frees allocated PyStringObject resources. """ py_slice = rffi.cast(PySliceObject, py_obj) Py_DecRef(space, py_slice.c_start) Py_DecRef(space, py_slice.c_stop) Py_DecRef(space, py_slice.c_step) from pypy.module.cpyext.object import PyObject_dealloc PyObject_dealloc(space, py_obj) PySlice_Check, PySlice_CheckExact = build_type_checkers("Slice") @cpython_api([PyObject, PyObject, PyObject], PyObject) def PySlice_New(space, w_start, w_stop, w_step): """Return a new slice object with the given values. The start, stop, and step parameters are used as the values of the slice object attributes of the same names. Any of the values may be NULL, in which case the None will be used for the corresponding attribute. Return NULL if the new object could not be allocated.""" if w_start is None: w_start = space.w_None if w_stop is None: w_stop = space.w_None if w_step is None: w_step = space.w_None return W_SliceObject(w_start, w_stop, w_step)
from rpython.rtyper.lltypesystem import lltype, rffi from pypy.module.cpyext.api import ( cpython_api, cpython_struct, PyObject, build_type_checkers) from pypy.module.cpyext.floatobject import PyFloat_AsDouble from pypy.objspace.std.complexobject import W_ComplexObject from pypy.interpreter.error import OperationError PyComplex_Check, PyComplex_CheckExact = build_type_checkers("Complex") Py_complex_t = lltype.ForwardReference() Py_complex_ptr = lltype.Ptr(Py_complex_t) Py_complex_fields = (("real", rffi.DOUBLE), ("imag", rffi.DOUBLE)) cpython_struct("Py_complex", Py_complex_fields, Py_complex_t) @cpython_api([lltype.Float, lltype.Float], PyObject) def PyComplex_FromDoubles(space, real, imag): return space.newcomplex(real, imag) @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_RealAsDouble(space, w_obj): if space.isinstance_w(w_obj, space.w_complex): assert isinstance(w_obj, W_ComplexObject) return w_obj.realval else: return space.float_w(w_obj) @cpython_api([PyObject], lltype.Float, error=-1) def PyComplex_ImagAsDouble(space, w_obj):
PyStringObjectStruct = lltype.ForwardReference() PyStringObject = lltype.Ptr(PyStringObjectStruct) PyStringObjectFields = PyObjectFields + \ (("buffer", rffi.CCHARP), ("size", Py_ssize_t)) cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct) @bootstrap_function def init_stringobject(space): "Type description of PyStringObject" make_typedescr(space.w_str.instancetypedef, basestruct=PyStringObject.TO, attach=string_attach, dealloc=string_dealloc, realize=string_realize) PyString_Check, PyString_CheckExact = build_type_checkers("String", "w_str") def new_empty_str(space, length): """ Allocatse a PyStringObject and its buffer, but without a corresponding interpreter object. The buffer may be mutated, until string_realize() is called. """ typedescr = get_typedescr(space.w_str.instancetypedef) py_obj = typedescr.allocate(space, space.w_str) py_str = rffi.cast(PyStringObject, py_obj) buflen = length + 1 py_str.c_size = length py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw', zero=True)
py_slice.c_start = make_ref(space, w_obj.w_start) py_slice.c_stop = make_ref(space, w_obj.w_stop) py_slice.c_step = make_ref(space, w_obj.w_step) @cpython_api([PyObject], lltype.Void, external=False) def slice_dealloc(space, py_obj): """Frees allocated PySliceObject resources. """ py_slice = rffi.cast(PySliceObject, py_obj) Py_DecRef(space, py_slice.c_start) Py_DecRef(space, py_slice.c_stop) Py_DecRef(space, py_slice.c_step) from pypy.module.cpyext.object import PyObject_dealloc PyObject_dealloc(space, py_obj) PySlice_Check, PySlice_CheckExact = build_type_checkers("Slice") @cpython_api([PyObject, PyObject, PyObject], PyObject) def PySlice_New(space, w_start, w_stop, w_step): """Return a new slice object with the given values. The start, stop, and step parameters are used as the values of the slice object attributes of the same names. Any of the values may be NULL, in which case the None will be used for the corresponding attribute. Return NULL if the new object could not be allocated.""" if w_start is None: w_start = space.w_None if w_stop is None: w_stop = space.w_None if w_step is None: w_step = space.w_None return W_SliceObject(w_start, w_stop, w_step)
("co_argcount", rffi.INT), ) cpython_struct("PyCodeObject", PyCodeObjectFields, PyCodeObjectStruct) @bootstrap_function def init_functionobject(space): make_typedescr(Function.typedef, basestruct=PyFunctionObject.TO, attach=function_attach, dealloc=function_dealloc) make_typedescr(PyCode.typedef, basestruct=PyCodeObject.TO, attach=code_attach, dealloc=code_dealloc) PyFunction_Check, PyFunction_CheckExact = build_type_checkers("Function", Function) PyMethod_Check, PyMethod_CheckExact = build_type_checkers("Method", Method) def function_attach(space, py_obj, w_obj): py_func = rffi.cast(PyFunctionObject, py_obj) assert isinstance(w_obj, Function) py_func.c_func_name = make_ref(space, space.wrap(w_obj.name)) @cpython_api([PyObject], lltype.Void, external=False) def function_dealloc(space, py_obj): py_func = rffi.cast(PyFunctionObject, py_obj) Py_DecRef(space, py_func.c_func_name) from pypy.module.cpyext.object import PyObject_dealloc PyObject_dealloc(space, py_obj) def code_attach(space, py_obj, w_obj):
from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import (CANNOT_FAIL, cpython_api, PyObject, build_type_checkers, CONST_STRING) from pypy.interpreter.error import OperationError from rpython.rlib.rstruct import runpack PyFloat_Check, PyFloat_CheckExact = build_type_checkers("Float") @cpython_api([lltype.Float], PyObject) def PyFloat_FromDouble(space, value): return space.wrap(value) @cpython_api([PyObject], lltype.Float, error=-1) def PyFloat_AsDouble(space, w_obj): return space.float_w(space.float(w_obj)) @cpython_api([PyObject], lltype.Float, error=CANNOT_FAIL) def PyFloat_AS_DOUBLE(space, w_float): """Return a C double representation of the contents of w_float, but without error checking.""" return space.float_w(w_float) @cpython_api([PyObject], PyObject) def PyNumber_Float(space, w_obj): """ Returns the o converted to a float object on success, or NULL on failure. This is the equivalent of the Python expression float(o)."""
from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, cpython_struct, \ METH_STATIC, METH_CLASS, METH_COEXIST, CANNOT_FAIL, CONST_STRING, \ METH_NOARGS, METH_O, METH_VARARGS, build_type_checkers from pypy.module.cpyext.pyobject import PyObject, as_pyobj from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import (W_PyCFunctionObject, PyCFunction_NewEx, PyDescr_NewMethod, PyMethodDef, PyDescr_NewClassMethod, PyStaticMethod_New) from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.module.cpyext.state import State from pypy.interpreter.error import oefmt PyModule_Check, PyModule_CheckExact = build_type_checkers("Module", Module) @cpython_api([CONST_STRING], PyObject) def PyModule_New(space, name): """ Return a new module object with the __name__ attribute set to name. Only the module's __doc__ and __name__ attributes are filled in; the caller is responsible for providing a __file__ attribute.""" return Module(space, space.newtext(rffi.charp2str(name))) #@cpython_api([rffi.CCHARP], PyObject) def PyImport_AddModule(space, name): """Return the module object corresponding to a module name. The name argument may be of the form package.module. First check the modules dictionary if