[Pyrex] Early-binding of builtins?

Stefan Behnel behnel_ml at gkec.informatik.tu-darmstadt.de
Sun Jul 23 02:45:18 UTC 2006



Greg Ewing wrote:
> Giovanni Bajo wrote:
> 
>> when I look at the code generated by Pyrex, I see that it totally mimcs
>> Python's semantic for global name lookups,
> 
> Not quite - it determines at compile time whether
> a name is module-level or builtin.
> 
>> and also builtins are not
>> early-bound but instead looked up in the namespace.
> 
> That's true. It would be possible to pre-bind them
> to C variables in the module init code, and I may
> consider doing that some time.

What I frequently do at the beginning of a module is something like this:

cdef object __builtin__
import __builtin__

cdef object type
type = __builtin__.type

cdef object True
True = __builtin__.True

cdef object set
try:
    set = __builtin__.set
except AttributeError:
    from sets import Set as set

etc.

This does the lookup once and then translates to pretty efficient Pyrex code.

I also have a header file defining (currently) these macros:

------------------------------
/* Redefinition of some Python builtins as C functions */
#define isinstance(o,c) PyObject_IsInstance(o,c)
#define issubclass(c,csuper) PyObject_IsSubclass(c,csuper)
#define hasattr(o,a)    PyObject_HasAttr(o,a)
#define getattr(o,a)    PyObject_GetAttr(o,a)
#define callable(o)     PyCallable_Check(o)
#define str(o)          PyObject_Str(o)
#define iter(o)         PyObject_GetIter(o)

#define _cstr(s)        PyString_AS_STRING(s)
#define _isString(obj)  PyObject_TypeCheck(obj, &PyBaseString_Type)
------------------------------

and then I define them as functions in a "python.pyx":

------------------------------
cdef extern from ...:
    cdef int isinstance(object instance, object classes)
    cdef int issubclass(object derived,  object superclasses)
    cdef int hasattr(object obj, object attr)
    cdef object getattr(object obj, object attr)
    cdef int callable(object obj)
    cdef object str(object obj)
    cdef object iter(object obj)

    cdef int _isString(object obj)
    cdef char* _cstr(object s)
------------------------------

and cimport them in the .pyx:

------------------------------
from python cimport isinstance, issubclass, hasattr, callable
from python cimport iter, str, _cstr, _isString
------------------------------

The speedup can be pretty noticeable at times.

Note that there are certain Python C-API functions that do not translate
directly to standard Python builtins (borrowed references, int return values,
etc.). Maybe int-returns are just a matter of Pyrex language definition, however.


> I already have plans to optimise access to some of
> the more frequently-used builtins by calling the
> corresponding C API function directly, which should
> be even better.

Sure. Should look much like the above, just inside the Pyrex compiler.

Stefan



More information about the Pyrex mailing list