Commit 6d6c1a35 authored by Tim Peters's avatar Tim Peters

Merge of descr-branch back into trunk.

parent 52d55a39
......@@ -89,6 +89,7 @@
#include "sliceobject.h"
#include "cellobject.h"
#include "iterobject.h"
#include "descrobject.h"
#include "codecs.h"
#include "pyerrors.h"
......
......@@ -294,6 +294,17 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
*/
DL_IMPORT(PyObject *) PyObject_Call(PyObject *callable_object,
PyObject *args, PyObject *kw);
/*
Call a callable Python object, callable_object, with
arguments and keywords arguments. The 'args' argument can not be
NULL, but the 'kw' argument can be NULL.
*/
DL_IMPORT(PyObject *) PyObject_CallObject(PyObject *callable_object,
PyObject *args);
......
......@@ -45,6 +45,9 @@ DL_IMPORT(int) Py_MakePendingCalls(void);
DL_IMPORT(void) Py_SetRecursionLimit(int);
DL_IMPORT(int) Py_GetRecursionLimit(void);
DL_IMPORT(char *) PyEval_GetFuncName(PyObject *);
DL_IMPORT(char *) PyEval_GetFuncDesc(PyObject *);
/* Interface for threads.
A module that plans to do a blocking system call (or something else
......
......@@ -47,10 +47,6 @@ extern DL_IMPORT(PyObject *) PyInstance_New(PyObject *, PyObject *,
extern DL_IMPORT(PyObject *) PyInstance_NewRaw(PyObject *, PyObject *);
extern DL_IMPORT(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *);
extern DL_IMPORT(PyObject *) PyMethod_Function(PyObject *);
extern DL_IMPORT(PyObject *) PyMethod_Self(PyObject *);
extern DL_IMPORT(PyObject *) PyMethod_Class(PyObject *);
/* Macros for direct access to these values. Type checks are *not*
done, so use with care. */
#define PyMethod_GET_FUNCTION(meth) \
......
/* XXX getter, setter, getsetlist and wrapperbase need 'Py'-prefixed names */
typedef PyObject *(*getter)(PyObject *, void *);
typedef int (*setter)(PyObject *, PyObject *, void *);
struct getsetlist {
char *name;
getter get;
setter set;
void *closure;
};
typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
void *wrapped);
struct wrapperbase {
char *name;
wrapperfunc wrapper;
char *doc;
};
extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *);
extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *,
struct memberlist *);
extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
struct getsetlist *);
extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
struct wrapperbase *, void *);
extern DL_IMPORT(int) PyDescr_IsData(PyObject *);
extern DL_IMPORT(PyObject *) PyDictProxy_New(PyObject *);
extern DL_IMPORT(PyObject *) PyWrapper_New(PyObject *, PyObject *);
......@@ -7,9 +7,83 @@ extern "C" {
/* Dictionary object type -- mapping from hashable object to object */
/*
There are three kinds of slots in the table:
1. Unused. me_key == me_value == NULL
Does not hold an active (key, value) pair now and never did. Unused can
transition to Active upon key insertion. This is the only case in which
me_key is NULL, and is each slot's initial state.
2. Active. me_key != NULL and me_key != dummy and me_value != NULL
Holds an active (key, value) pair. Active can transition to Dummy upon
key deletion. This is the only case in which me_value != NULL.
3. Dummy. me_key == dummy and me_value == NULL
Previously held an active (key, value) pair, but that was deleted and an
active pair has not yet overwritten the slot. Dummy can transition to
Active upon key insertion. Dummy slots cannot be made Unused again
(cannot have me_key set to NULL), else the probe sequence in case of
collision would have no way to know they were once active.
Note: .popitem() abuses the me_hash field of an Unused or Dummy slot to
hold a search finger. The me_hash field of Unused or Dummy slots has no
meaning otherwise.
*/
/* PyDict_MINSIZE is the minimum size of a dictionary. This many slots are
* allocated directly in the dict object (in the ma_smalltable member).
* It must be a power of 2, and at least 4. 8 allows dicts with no more
* than 5 active entries to live in ma_smalltable (and so avoid an
* additional malloc); instrumentation suggested this suffices for the
* majority of dicts (consisting mostly of usually-small instance dicts and
* usually-small dicts created to pass keyword arguments).
*/
#define PyDict_MINSIZE 8
typedef struct {
long me_hash; /* cached hash code of me_key */
PyObject *me_key;
PyObject *me_value;
#ifdef USE_CACHE_ALIGNED
long aligner;
#endif
} PyDictEntry;
/*
To ensure the lookup algorithm terminates, there must be at least one Unused
slot (NULL key) in the table.
The value ma_fill is the number of non-NULL keys (sum of Active and Dummy);
ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL
values == the number of Active items).
To avoid slowing down lookups on a near-full table, we resize the table when
it's two-thirds full.
*/
typedef struct _dictobject PyDictObject;
struct _dictobject {
PyObject_HEAD
int ma_fill; /* # Active + # Dummy */
int ma_used; /* # Active */
/* The table contains ma_mask + 1 slots, and that's a power of 2.
* We store the mask instead of the size because the mask is more
* frequently needed.
*/
int ma_mask;
/* ma_table points to ma_smalltable for small tables, else to
* additional malloc'ed memory. ma_table is never NULL! This rule
* saves repeated runtime null-tests in the workhorse getitem and
* setitem calls.
*/
PyDictEntry *ma_table;
PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
PyDictEntry ma_smalltable[PyDict_MINSIZE];
};
extern DL_IMPORT(PyTypeObject) PyDict_Type;
#define PyDict_Check(op) ((op)->ob_type == &PyDict_Type)
#define PyDict_Check(op) PyObject_TypeCheck(op, &PyDict_Type)
extern DL_IMPORT(PyObject *) PyDict_New(void);
extern DL_IMPORT(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
......@@ -23,6 +97,7 @@ extern DL_IMPORT(PyObject *) PyDict_Values(PyObject *mp);
extern DL_IMPORT(PyObject *) PyDict_Items(PyObject *mp);
extern DL_IMPORT(int) PyDict_Size(PyObject *mp);
extern DL_IMPORT(PyObject *) PyDict_Copy(PyObject *mp);
extern DL_IMPORT(int) PyDict_Update(PyObject *mp, PyObject *other);
extern DL_IMPORT(PyObject *) PyDict_GetItemString(PyObject *dp, char *key);
......
......@@ -9,6 +9,14 @@ extern "C" {
DL_IMPORT(PyObject *) PyEval_EvalCode(PyCodeObject *, PyObject *, PyObject *);
DL_IMPORT(PyObject *) PyEval_EvalCodeEx(PyCodeObject *co,
PyObject *globals,
PyObject *locals,
PyObject **args, int argc,
PyObject **kwds, int kwdc,
PyObject **defs, int defc,
PyObject *closure);
#ifdef __cplusplus
}
#endif
......
......@@ -42,6 +42,13 @@ extern DL_IMPORT(int) PyFunction_SetClosure(PyObject *, PyObject *);
#define PyFunction_GET_CLOSURE(func) \
(((PyFunctionObject *)func) -> func_closure)
/* The classmethod and staticmethod types lives here, too */
extern DL_IMPORT(PyTypeObject) PyClassMethod_Type;
extern DL_IMPORT(PyTypeObject) PyStaticMethod_Type;
extern DL_IMPORT(PyObject *) PyClassMethod_New(PyObject *);
extern DL_IMPORT(PyObject *) PyStaticMethod_New(PyObject *);
#ifdef __cplusplus
}
#endif
......
......@@ -26,7 +26,7 @@ typedef struct {
extern DL_IMPORT(PyTypeObject) PyList_Type;
#define PyList_Check(op) ((op)->ob_type == &PyList_Type)
#define PyList_Check(op) PyObject_TypeCheck(op, &PyList_Type)
extern DL_IMPORT(PyObject *) PyList_New(int size);
extern DL_IMPORT(int) PyList_Size(PyObject *);
......
......@@ -22,8 +22,8 @@ extern DL_IMPORT(int) PyModule_AddObject(PyObject *, char *, PyObject *);
extern DL_IMPORT(int) PyModule_AddIntConstant(PyObject *, char *, long);
extern DL_IMPORT(int) PyModule_AddStringConstant(PyObject *, char *, char *);
#define PYTHON_API_VERSION 1010
#define PYTHON_API_STRING "1010"
#define PYTHON_API_VERSION 1011
#define PYTHON_API_STRING "1011"
/* The API version is maintained (independently from the Python version)
so we can detect mismatches between the interpreter and dynamically
loaded modules. These are diagnosed by an error message but
......@@ -37,6 +37,8 @@ extern DL_IMPORT(int) PyModule_AddStringConstant(PyObject *, char *, char *);
Please add a line or two to the top of this log for each API
version change:
17-Jul-2001 GvR 1011 Descr-branch, just to be on the safe side
25-Jan-2001 FLD 1010 Parameters added to PyCode_New() and
PyFrame_New(); Python 2.1a2
......
......@@ -202,6 +202,11 @@ typedef long (*hashfunc)(PyObject *);
typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
typedef PyObject *(*getiterfunc) (PyObject *);
typedef PyObject *(*iternextfunc) (PyObject *);
typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *);
typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *);
typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
typedef PyObject *(*allocfunc)(struct _typeobject *, int);
typedef struct _typeobject {
PyObject_VAR_HEAD
......@@ -255,18 +260,48 @@ typedef struct _typeobject {
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
struct memberlist *tp_members;
struct getsetlist *tp_getset;
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
long tp_dictoffset;
initproc tp_init;
allocfunc tp_alloc;
newfunc tp_new;
destructor tp_free; /* Low-level free-memory routine */
PyObject *tp_bases;
PyObject *tp_mro; /* method resolution order */
PyObject *tp_defined;
#ifdef COUNT_ALLOCS
/* these must be last and never explicitly initialized */
int tp_alloc;
int tp_free;
int tp_allocs;
int tp_frees;
int tp_maxalloc;
struct _typeobject *tp_next;
#endif
} PyTypeObject;
extern DL_IMPORT(PyTypeObject) PyType_Type; /* The type of type objects */
#define PyType_Check(op) ((op)->ob_type == &PyType_Type)
/* Generic type check */
extern DL_IMPORT(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *);
#define PyObject_TypeCheck(ob, tp) \
((ob)->ob_type == (tp) || PyType_IsSubtype((ob)->ob_type, (tp)))
extern DL_IMPORT(PyTypeObject) PyType_Type; /* Metatype */
extern DL_IMPORT(PyTypeObject) PyBaseObject_Type; /* Most base object type */
#define PyType_Check(op) PyObject_TypeCheck(op, &PyType_Type)
extern DL_IMPORT(int) PyType_InitDict(PyTypeObject *);
extern DL_IMPORT(PyObject *) PyType_GenericAlloc(PyTypeObject *, int);
extern DL_IMPORT(PyObject *) PyType_GenericNew(PyTypeObject *,
PyObject *, PyObject *);
extern DL_IMPORT(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
/* Generic operations on objects */
extern DL_IMPORT(int) PyObject_Print(PyObject *, FILE *, int);
......@@ -283,6 +318,10 @@ extern DL_IMPORT(int) PyObject_HasAttrString(PyObject *, char *);
extern DL_IMPORT(PyObject *) PyObject_GetAttr(PyObject *, PyObject *);
extern DL_IMPORT(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *);
extern DL_IMPORT(int) PyObject_HasAttr(PyObject *, PyObject *);
extern DL_IMPORT(PyObject **) _PyObject_GetDictPtr(PyObject *);
extern DL_IMPORT(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *);
extern DL_IMPORT(int) PyObject_GenericSetAttr(PyObject *,
PyObject *, PyObject *);
extern DL_IMPORT(long) PyObject_Hash(PyObject *);
extern DL_IMPORT(int) PyObject_IsTrue(PyObject *);
extern DL_IMPORT(int) PyObject_Not(PyObject *);
......@@ -357,6 +396,18 @@ given type object has a specified feature.
/* tp_iter is defined */
#define Py_TPFLAGS_HAVE_ITER (1L<<7)
/* Experimental stuff for healing the type/class split */
#define Py_TPFLAGS_HAVE_CLASS (1L<<8)
/* Set if the type object is dynamically allocated */
#define Py_TPFLAGS_HEAPTYPE (1L<<9)
/* Set if the type allows subclassing */
#define Py_TPFLAGS_BASETYPE (1L<<10)
/* Set if the type's __dict__ may change */
#define Py_TPFLAGS_DYNAMICTYPE (1L<<11)
#define Py_TPFLAGS_DEFAULT ( \
Py_TPFLAGS_HAVE_GETCHARBUFFER | \
Py_TPFLAGS_HAVE_SEQUENCE_IN | \
......@@ -364,6 +415,7 @@ given type object has a specified feature.
Py_TPFLAGS_HAVE_RICHCOMPARE | \
Py_TPFLAGS_HAVE_WEAKREFS | \
Py_TPFLAGS_HAVE_ITER | \
Py_TPFLAGS_HAVE_CLASS | \
0)
#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0)
......@@ -412,8 +464,8 @@ extern DL_IMPORT(void) _Py_ResetReferences(void);
#ifndef Py_TRACE_REFS
#ifdef COUNT_ALLOCS
#define _Py_Dealloc(op) ((op)->ob_type->tp_free++, (*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
#define _Py_ForgetReference(op) ((op)->ob_type->tp_free++)
#define _Py_Dealloc(op) ((op)->ob_type->tp_frees++, (*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
#define _Py_ForgetReference(op) ((op)->ob_type->tp_frees++)
#else /* !COUNT_ALLOCS */
#define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op))
#define _Py_ForgetReference(op) /*empty*/
......
......@@ -236,7 +236,13 @@ extern DL_IMPORT(void) _PyObject_Del(PyObject *);
#define PyObject_GC_Fini(op)
#define PyObject_AS_GC(op) (op)
#define PyObject_FROM_GC(op) (op)
#define PyType_IS_GC(t) 0
#define PyObject_IS_GC(o) 0
#define PyObject_AS_GC(o) (o)
#define PyObject_FROM_GC(o) (o)
#define PyType_BASICSIZE(t) ((t)->tp_basicsize)
#define PyType_SET_BASICSIZE(t, s) ((t)->tp_basicsize = (s))
#else
/* Add the object into the container set */
......@@ -269,6 +275,13 @@ typedef struct _gc_head {
/* Get the object given the PyGC_Head */
#define PyObject_FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1))
/* Calculate tp_basicsize excluding PyGC_HEAD_SIZE if applicable */
#define PyType_BASICSIZE(t) (!PyType_IS_GC(t) ? (t)->tp_basicsize : \
(t)->tp_basicsize - PyGC_HEAD_SIZE)
#define PyType_SET_BASICSIZE(t, s) (!PyType_IS_GC(t) ? \
((t)->tp_basicsize = (s)) : \
((t)->tp_basicsize = (s) + PyGC_HEAD_SIZE))
extern DL_IMPORT(void) _PyGC_Dump(PyGC_Head *);
#endif /* WITH_CYCLE_GC */
......
......@@ -23,13 +23,13 @@
#define PY_MINOR_VERSION 2
#define PY_MICRO_VERSION 0
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA
#define PY_RELEASE_SERIAL 0
#define PY_RELEASE_SERIAL 1
/* Version as a string */
#define PY_VERSION "2.2a0"
#define PY_VERSION "2.2a1"
/* Historic */
#define PATCHLEVEL "2.2a0"
#define PATCHLEVEL "2.2a1"
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */
......
......@@ -92,10 +92,10 @@ DL_IMPORT(const char *) Py_GetBuildInfo(void);
DL_IMPORT(PyObject *) _PyBuiltin_Init(void);
DL_IMPORT(PyObject *) _PySys_Init(void);
DL_IMPORT(void) _PyImport_Init(void);
DL_IMPORT(void) init_exceptions(void);
DL_IMPORT(void) _PyExc_Init(void);
/* Various internal finalizers */
DL_IMPORT(void) fini_exceptions(void);
DL_IMPORT(void) _PyExc_Fini(void);
DL_IMPORT(void) _PyImport_Fini(void);
DL_IMPORT(void) PyMethod_Fini(void);
DL_IMPORT(void) PyFrame_Fini(void);
......
......@@ -504,6 +504,7 @@ class Pickler:
dispatch[ClassType] = save_global
dispatch[FunctionType] = save_global
dispatch[BuiltinFunctionType] = save_global
dispatch[TypeType] = save_global
def _keep_alive(x, memo):
......
......@@ -62,7 +62,7 @@ class Repr:
s = s + ': ' + self.repr1(x[key], level-1)
if n > self.maxdict: s = s + ', ...'
return '{' + s + '}'
def repr_string(self, x, level):
def repr_str(self, x, level):
s = `x[:self.maxstring]`
if len(s) > self.maxstring:
i = max(0, (self.maxstring-3)/2)
......@@ -70,7 +70,7 @@ class Repr:
s = `x[:i] + x[len(x)-j:]`
s = s[:i] + '...' + s[len(s)-j:]
return s
def repr_long_int(self, x, level):
def repr_long(self, x, level):
s = `x` # XXX Hope this isn't too slow...
if len(s) > self.maxlong:
i = max(0, (self.maxlong-3)/2)
......
This diff is collapsed.
......@@ -380,10 +380,16 @@ From the Iterators list, about the types of these things.
>>> i = g()
>>> type(i)
<type 'generator'>
XXX dir(object) *generally* doesn't return useful stuff in descr-branch.
>>> dir(i)
[]
Was hoping to see this instead:
['gi_frame', 'gi_running', 'next']
>>> print i.next.__doc__
next() -- get the next value, or raise StopIteration
x.next() -> the next value, or raise StopIteration
>>> iter(i) is i
1
>>> import types
......@@ -399,7 +405,7 @@ And more, added later.
>>> i.gi_running = 42
Traceback (most recent call last):
...
TypeError: object has read-only attributes
TypeError: 'generator' object has only read-only attributes (assign to .gi_running)
>>> def g():
... yield me.gi_running
>>> me = g()
......
......@@ -7,7 +7,8 @@ from __future__ import generators
import sys
NoneType = type(None)
TypeType = type(NoneType)
TypeType = type
ObjectType = object
IntType = type(0)
LongType = type(0L)
......@@ -22,8 +23,8 @@ UnicodeType = type(u'')
BufferType = type(buffer(''))
TupleType = type(())
ListType = type([])
DictType = DictionaryType = type({})
ListType = list
DictType = DictionaryType = dictionary
def _f(): pass
FunctionType = type(_f)
......@@ -71,4 +72,9 @@ except TypeError:
SliceType = type(slice(0))
EllipsisType = type(Ellipsis)
DictIterType = type(iter({}))
SequenceIterType = type(iter([]))
FunctionIterType = type(iter(lambda: 0, 0))
DictProxyType = type(TypeType.__dict__)
del sys, _f, _C, _x # Not for export
......@@ -237,6 +237,7 @@ OBJECT_OBJS= \
Objects/classobject.o \
Objects/cobject.o \
Objects/complexobject.o \
Objects/descrobject.o \
Objects/fileobject.o \
Objects/floatobject.o \
Objects/frameobject.o \
......@@ -438,6 +439,7 @@ PYTHON_HEADERS= \
Include/tupleobject.h \
Include/listobject.h \
Include/iterobject.h \
Include/descrobject.h \
Include/dictobject.h \
Include/methodobject.h \
Include/moduleobject.h \
......
......@@ -44,6 +44,17 @@ What's New in Python 2.2a1?
Core
- TENTATIVELY, a large amount of code implementing much of what's
described in PEP 252 (Making Types Look More Like Classes) and PEP
253 (Subtyping Built-in Types) was added. This will be released
with Python 2.2a1. Documentation will be provided separately
through http://www.python.org/2.2/. The purpose of releasing this
with Python 2.2a1 is to test backwards compatibility. It is
possible, though not likely, that a decision is made not to release
this code as part of 2.2 final, if any serious backwards
incompapatibilities are found during alpha testing that cannot be
repaired.
- Generators were added; this is a new way to create an iterator (see
below) using what looks like a simple function containing one or
more 'yield' statements. See PEP 255. Since this adds a new
......
......@@ -464,3 +464,5 @@ GLHACK=-Dclear=__GLclear
# Example -- included for reference only:
# xx xxmodule.c
# Another example -- the 'xxsubtype' module shows C-level subtyping in action
xxsubtype xxsubtype.c
......@@ -1869,6 +1869,10 @@ save(Picklerobject *self, PyObject *args, int pers_save) {
res = save_tuple(self, args);
goto finally;
}
if (type == &PyType_Type) {
res = save_global(self, args, NULL);
goto finally;
}
break;
case 'l':
......
......@@ -37,7 +37,7 @@ struct _inittab _PyImport_Inittab[] = {
{"__main__", NULL},
{"__builtin__", NULL},
{"sys", NULL},
{"exceptions", init_exceptions},
{"exceptions", NULL},
/* Sentinel */
{0, 0}
......
#include "Python.h"
/* Examples showing how to subtype the builtin list and dict types from C. */
/* spamlist -- a list subtype */
typedef struct {
PyListObject list;
int state;
} spamlistobject;
static PyObject *
spamlist_getstate(spamlistobject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":getstate"))
return NULL;
return PyInt_FromLong(self->state);
}
static PyObject *
spamlist_setstate(spamlistobject *self, PyObject *args)
{
int state;
if (!PyArg_ParseTuple(args, "i:setstate", &state))
return NULL;
self->state = state;
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef spamlist_methods[] = {
{"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
"getstate() -> state"},
{"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
"setstate(state)"},
{NULL, NULL},
};
staticforward PyTypeObject spamlist_type;
static int
spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
{
if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
return -1;
self->state = 0;
return 0;
}
static PyTypeObject spamlist_type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"spamlist",
sizeof(spamlistobject),
0,
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
spamlist_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PyList_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)spamlist_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
/* spamdict -- a dict subtype */
typedef struct {
PyDictObject dict;
int state;
} spamdictobject;
static PyObject *
spamdict_getstate(spamdictobject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":getstate"))
return NULL;
return PyInt_FromLong(self->state);
}
static PyObject *
spamdict_setstate(spamdictobject *self, PyObject *args)
{
int state;
if (!PyArg_ParseTuple(args, "i:setstate", &state))
return NULL;
self->state = state;
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef spamdict_methods[] = {
{"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
"getstate() -> state"},
{"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
"setstate(state)"},
{NULL, NULL},
};
staticforward PyTypeObject spamdict_type;
static int
spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
{
if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
return -1;
self->state = 0;
return 0;
}
static PyTypeObject spamdict_type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"spamdict",
sizeof(spamdictobject),
0,
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
spamdict_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PyDict_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)spamdict_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
PyObject *
spam_bench(PyObject *self, PyObject *args)
{
PyObject *obj, *name, *res;
int n = 1000;
time_t t0, t1;
if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n))
return NULL;
t0 = clock();
while (--n >= 0) {
res = PyObject_GetAttr(obj, name);
if (res == NULL)
return NULL;
Py_DECREF(res);
}
t1 = clock();
return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC);
}
static PyMethodDef xxsubtype_functions[] = {
{"bench", spam_bench, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
DL_EXPORT(void)
initxxsubtype(void)
{
PyObject *m, *d;
m = Py_InitModule("xxsubtype", xxsubtype_functions);
if (m == NULL)
return;
if (PyType_InitDict(&spamlist_type) < 0)
return;
if (PyType_InitDict(&spamdict_type) < 0)
return;
d = PyModule_GetDict(m);
if (d == NULL)
return;
Py_INCREF(&spamlist_type);
if (PyDict_SetItemString(d, "spamlist",
(PyObject *) &spamlist_type) < 0)
return;
Py_INCREF(&spamdict_type);
if (PyDict_SetItemString(d, "spamdict",
(PyObject *) &spamdict_type) < 0)
return;
}
......@@ -1588,6 +1588,24 @@ PyObject_CallObject(PyObject *o, PyObject *a)
return r;
}
PyObject *
PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
{
ternaryfunc call;
if ((call = func->ob_type->tp_call) != NULL) {
PyObject *result = (*call)(func, arg, kw);
if (result == NULL && !PyErr_Occurred())
PyErr_SetString(
PyExc_SystemError,
"NULL result without error in PyObject_Call");
return result;
}
PyErr_Format(PyExc_TypeError, "object is not callable: %s",
PyString_AS_STRING(PyObject_Repr(func)));
return NULL;
}
PyObject *
PyObject_CallFunction(PyObject *callable, char *format, ...)
{
......@@ -1746,7 +1764,7 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
}
}
else if (PyType_Check(cls)) {
retval = ((PyObject *)(inst->ob_type) == cls);
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
}
else if (!PyInstance_Check(inst)) {
if (__class__ == NULL) {
......
......@@ -537,21 +537,21 @@ PyTypeObject PyBuffer_Type = {
"buffer",
sizeof(PyBufferObject),
0,
(destructor)buffer_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
(cmpfunc)buffer_compare, /*tp_compare*/
(reprfunc)buffer_repr, /*tp_repr*/
0, /*tp_as_number*/
&buffer_as_sequence, /*tp_as_sequence*/
0, /*tp_as_mapping*/
(hashfunc)buffer_hash, /*tp_hash*/
0, /*tp_call*/
(reprfunc)buffer_str, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
&buffer_as_buffer, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
(destructor)buffer_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc)buffer_compare, /* tp_compare */
(reprfunc)buffer_repr, /* tp_repr */
0, /* tp_as_number */
&buffer_as_sequence, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)buffer_hash, /* tp_hash */
0, /* tp_call */
(reprfunc)buffer_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&buffer_as_buffer, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
};
......@@ -106,7 +106,7 @@ PyTypeObject PyCell_Type = {
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
......
This diff is collapsed.
......@@ -8,6 +8,7 @@
#ifndef WITHOUT_COMPLEX
#include "Python.h"
#include "structmember.h"
/* Precisions used by repr() and str(), respectively.
......@@ -182,6 +183,17 @@ c_powi(Py_complex x, long n)
}
static PyObject *
complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
{
PyObject *op;
op = PyType_GenericAlloc(type, 0);
if (op != NULL)
((PyComplexObject *)op)->cval = cval;
return op;
}
PyObject *
PyComplex_FromCComplex(Py_complex cval)
{
......@@ -196,6 +208,15 @@ PyComplex_FromCComplex(Py_complex cval)
return (PyObject *) op;
}
static PyObject *
complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
{
Py_complex c;
c.real = real;
c.imag = imag;
return complex_subtype_from_c_complex(type, c);
}
PyObject *
PyComplex_FromDoubles(double real, double imag)
{
......@@ -559,19 +580,261 @@ static PyMethodDef complex_methods[] = {
{NULL, NULL} /* sentinel */
};
static struct memberlist complex_members[] = {
{"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0},
{"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0},
{0},
};
static PyObject *
complex_getattr(PyComplexObject *self, char *name)
{
if (strcmp(name, "real") == 0)
return (PyObject *)PyFloat_FromDouble(self->cval.real);
else if (strcmp(name, "imag") == 0)
return (PyObject *)PyFloat_FromDouble(self->cval.imag);
else if (strcmp(name, "__members__") == 0)
return Py_BuildValue("[ss]", "imag", "real");
return Py_FindMethod(complex_methods, (PyObject *)self, name);
complex_subtype_from_string(PyTypeObject *type, PyObject *v)
{
extern double strtod(const char *, char **);
const char *s, *start;
char *end;
double x=0.0, y=0.0, z;
int got_re=0, got_im=0, done=0;
int digit_or_dot;
int sw_error=0;
int sign;
char buffer[256]; /* For errors */
char s_buffer[256];
int len;
if (PyString_Check(v)) {
s = PyString_AS_STRING(v);
len = PyString_GET_SIZE(v);
}
else if (PyUnicode_Check(v)) {
if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) {
PyErr_SetString(PyExc_ValueError,
"complex() literal too large to convert");
return NULL;
}
if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
PyUnicode_GET_SIZE(v),
s_buffer,
NULL))
return NULL;
s = s_buffer;
len = (int)strlen(s);
}
else if (PyObject_AsCharBuffer(v, &s, &len)) {
PyErr_SetString(PyExc_TypeError,
"complex() arg is not a string");
return NULL;
}
/* position on first nonblank */
start = s;
while (*s && isspace(Py_CHARMASK(*s)))
s++;
if (s[0] == '\0') {
PyErr_SetString(PyExc_ValueError,
"complex() arg is an empty string");
return NULL;
}
z = -1.0;
sign = 1;
do {
switch (*s) {
case '\0':
if (s-start != len) {
PyErr_SetString(
PyExc_ValueError,
"complex() arg contains a null byte");
return NULL;
}
if(!done) sw_error=1;
break;
case '-':
sign = -1;
/* Fallthrough */
case '+':
if (done) sw_error=1;
s++;
if ( *s=='\0'||*s=='+'||*s=='-' ||
isspace(Py_CHARMASK(*s)) ) sw_error=1;
break;
case 'J':
case 'j':
if (got_im || done) {
sw_error = 1;
break;
}
if (z<0.0) {
y=sign;
}
else{
y=sign*z;
}
got_im=1;
s++;
if (*s!='+' && *s!='-' )
done=1;
break;
default:
if (isspace(Py_CHARMASK(*s))) {
while (*s && isspace(Py_CHARMASK(*s)))
s++;
if (s[0] != '\0')
sw_error=1;
else
done = 1;
break;
}
digit_or_dot =
(*s=='.' || isdigit(Py_CHARMASK(*s)));
if (done||!digit_or_dot) {
sw_error=1;
break;
}
errno = 0;
PyFPE_START_PROTECT("strtod", return 0)
z = strtod(s, &end) ;
PyFPE_END_PROTECT(z)
if (errno != 0) {
sprintf(buffer,
"float() out of range: %.150s", s);
PyErr_SetString(
PyExc_ValueError,
buffer);
return NULL;
}
s=end;
if (*s=='J' || *s=='j') {
break;
}
if (got_re) {
sw_error=1;
break;
}
/* accept a real part */
x=sign*z;
got_re=1;
if (got_im) done=1;
z = -1.0;
sign = 1;
break;
} /* end of switch */
} while (*s!='\0' && !sw_error);
if (sw_error) {
PyErr_SetString(PyExc_ValueError,
"complex() arg is a malformed string");
return NULL;
}
return complex_subtype_from_doubles(type, x, y);
}
static PyObject *
complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *r, *i, *tmp;
PyNumberMethods *nbr, *nbi = NULL;
Py_complex cr, ci;
int own_r = 0;
static char *kwlist[] = {"real", "imag", 0};
r = Py_False;
i = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
&r, &i))
return NULL;
if (PyString_Check(r) || PyUnicode_Check(r))
return complex_subtype_from_string(type, r);
if ((nbr = r->ob_type->tp_as_number) == NULL ||
nbr->nb_float == NULL ||
(i != NULL &&
((nbi = i->ob_type->tp_as_number) == NULL ||
nbi->nb_float == NULL))) {
PyErr_SetString(PyExc_TypeError,
"complex() arg can't be converted to complex");
return NULL;
}
/* XXX Hack to support classes with __complex__ method */
if (PyInstance_Check(r)) {
static PyObject *complexstr;
PyObject *f;
if (complexstr == NULL) {
complexstr = PyString_InternFromString("__complex__");
if (complexstr == NULL)
return NULL;
}
f = PyObject_GetAttr(r, complexstr);
if (f == NULL)
PyErr_Clear();
else {
PyObject *args = Py_BuildValue("()");
if (args == NULL)
return NULL;
r = PyEval_CallObject(f, args);
Py_DECREF(args);
Py_DECREF(f);
if (r == NULL)
return NULL;
own_r = 1;
}
}
if (PyComplex_Check(r)) {
cr = ((PyComplexObject*)r)->cval;
if (own_r) {
Py_DECREF(r);
}
}
else {
tmp = PyNumber_Float(r);
if (own_r) {
Py_DECREF(r);
}
if (tmp == NULL)
return NULL;
if (!PyFloat_Check(tmp)) {
PyErr_SetString(PyExc_TypeError,
"float(r) didn't return a float");
Py_DECREF(tmp);
return NULL;
}
cr.real = PyFloat_AsDouble(tmp);
Py_DECREF(tmp);
cr.imag = 0.0;
}
if (i == NULL) {
ci.real = 0.0;
ci.imag = 0.0;
}
else if (PyComplex_Check(i))
ci = ((PyComplexObject*)i)->cval;
else {
tmp = (*nbi->nb_float)(i);
if (tmp == NULL)
return NULL;
ci.real = PyFloat_AsDouble(tmp);
Py_DECREF(tmp);
ci.imag = 0.;
}
cr.real -= ci.imag;
cr.imag += ci.real;
return complex_subtype_from_c_complex(type, cr);
}
static char complex_doc[] =
"complex(real[, imag]) -> complex number\n\
\n\
Create a complex number from a real part and an optional imaginary part.\n\
This is equivalent to (real + imag*1j) where imag defaults to 0.";
static PyNumberMethods complex_as_number = {
(binaryfunc)complex_add, /* nb_add */
(binaryfunc)complex_sub, /* nb_subtract */
......@@ -606,7 +869,7 @@ PyTypeObject PyComplex_Type = {
0,
(destructor)complex_dealloc, /* tp_dealloc */
(printfunc)complex_print, /* tp_print */
(getattrfunc)complex_getattr, /* tp_getattr */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)complex_repr, /* tp_repr */
......@@ -616,14 +879,28 @@ PyTypeObject PyComplex_Type = {
(hashfunc)complex_hash, /* tp_hash */
0, /* tp_call */
(reprfunc)complex_str, /* tp_str */
0, /* tp_getattro */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
complex_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
complex_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
complex_methods, /* tp_methods */
complex_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
complex_new, /* tp_new */
};
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -1273,29 +1273,15 @@ static struct memberlist file_memberlist[] = {
};
static PyObject *
file_getattr(PyFileObject *f, char *name)
get_closed(PyFileObject *f, void *closure)
{
PyObject *res;
res = Py_FindMethod(file_methods, (PyObject *)f, name);
if (res != NULL)
return res;
PyErr_Clear();
if (strcmp(name, "closed") == 0)
return PyInt_FromLong((long)(f->f_fp == 0));
return PyMember_Get((char *)f, file_memberlist, name);
return PyInt_FromLong((long)(f->f_fp == 0));
}
static int
file_setattr(PyFileObject *f, char *name, PyObject *v)
{
if (v == NULL) {
PyErr_SetString(PyExc_AttributeError,
"can't delete file attributes");
return -1;
}
return PyMember_Set((char *)f, file_memberlist, name, v);
}
static struct getsetlist file_getsetlist[] = {
{"closed", (getter)get_closed, NULL, NULL},
{0},
};
static PyObject *
file_getiter(PyObject *f)
......@@ -1311,27 +1297,32 @@ PyTypeObject PyFile_Type = {
0,
(destructor)file_dealloc, /* tp_dealloc */
0, /* tp_print */
(getattrfunc)file_getattr, /* tp_getattr */
(setattrfunc)file_setattr, /* tp_setattr */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)file_repr, /* tp_repr */
(reprfunc)file_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
file_getiter, /* tp_iter */
0, /* tp_iternext */
file_methods, /* tp_methods */
file_memberlist, /* tp_members */
file_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
};
/* Interface for the 'soft space' between print items. */
......
......@@ -636,6 +636,26 @@ float_float(PyObject *v)
}
static PyObject *
float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *x = Py_False; /* Integer zero */
static char *kwlist[] = {"x", 0};
assert(type == &PyFloat_Type);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
return NULL;
if (PyString_Check(x))
return PyFloat_FromString(x, NULL);
return PyNumber_Float(x);
}
static char float_doc[] =
"float(x) -> floating point number\n\
\n\
Convert a string or number to a floating point number, if possible.";
static PyNumberMethods float_as_number = {
(binaryfunc)float_add, /*nb_add*/
(binaryfunc)float_sub, /*nb_subtract*/
......@@ -679,22 +699,40 @@ PyTypeObject PyFloat_Type = {
"float",
sizeof(PyFloatObject),
0,
(destructor)float_dealloc, /*tp_dealloc*/
(printfunc)float_print, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
(cmpfunc)float_compare, /*tp_compare*/
(reprfunc)float_repr, /*tp_repr*/
&float_as_number, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
(hashfunc)float_hash, /*tp_hash*/
0, /*tp_call*/
(reprfunc)float_str, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_CHECKTYPES /*tp_flags*/
(destructor)float_dealloc, /* tp_dealloc */
(printfunc)float_print, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc)float_compare, /* tp_compare */
(reprfunc)float_repr, /* tp_repr */
&float_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)float_hash, /* tp_hash */
0, /* tp_call */
(reprfunc)float_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
float_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
float_new, /* tp_new */
};
void
......
......@@ -15,7 +15,6 @@ static struct memberlist frame_memberlist[] = {
{"f_code", T_OBJECT, OFF(f_code), RO},
{"f_builtins", T_OBJECT, OFF(f_builtins),RO},
{"f_globals", T_OBJECT, OFF(f_globals), RO},
{"f_locals", T_OBJECT, OFF(f_locals), RO},
{"f_lasti", T_INT, OFF(f_lasti), RO},
{"f_lineno", T_INT, OFF(f_lineno), RO},
{"f_restricted",T_INT, OFF(f_restricted),RO},
......@@ -27,18 +26,17 @@ static struct memberlist frame_memberlist[] = {
};
static PyObject *
frame_getattr(PyFrameObject *f, char *name)
frame_getlocals(PyFrameObject *f, void *closure)
{
if (strcmp(name, "f_locals") == 0)
PyFrame_FastToLocals(f);
return PyMember_Get((char *)f, frame_memberlist, name);
PyFrame_FastToLocals(f);
Py_INCREF(f->f_locals);
return f->f_locals;
}
static int
frame_setattr(PyFrameObject *f, char *name, PyObject *value)
{
return PyMember_Set((char *)f, frame_memberlist, name, value);
}
static struct getsetlist frame_getsetlist[] = {
{"f_locals", (getter)frame_getlocals, NULL, NULL},
{0}
};
/* Stack frames are allocated and deallocated at a considerable rate.
In an attempt to improve the speed of function calls, we maintain a
......@@ -177,8 +175,8 @@ PyTypeObject PyFrame_Type = {
0,
(destructor)frame_dealloc, /* tp_dealloc */
0, /* tp_print */
(getattrfunc)frame_getattr, /* tp_getattr */
(setattrfunc)frame_setattr, /* tp_setattr */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
......@@ -187,13 +185,22 @@ PyTypeObject PyFrame_Type = {
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)frame_traverse, /* tp_traverse */
(inquiry)frame_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
frame_memberlist, /* tp_members */
frame_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
};
PyFrameObject *
......
This diff is collapsed.
......@@ -742,6 +742,41 @@ int_hex(PyIntObject *v)
return PyString_FromString(buf);
}
static PyObject *
int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *x = NULL;
int base = -909;
static char *kwlist[] = {"x", "base", 0};
assert(type == &PyInt_Type);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
&x, &base))
return NULL;
if (x == NULL)
return PyInt_FromLong(0L);
if (base == -909)
return PyNumber_Int(x);
if (PyString_Check(x))
return PyInt_FromString(PyString_AS_STRING(x), NULL, base);
if (PyUnicode_Check(x))
return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
PyUnicode_GET_SIZE(x),
base);
PyErr_SetString(PyExc_TypeError,
"int() can't convert non-string with explicit base");
return NULL;
}
static char int_doc[] =
"int(x[, base]) -> integer\n\
\n\
Convert a string or number to an integer, if possible. A floating point\n\
argument will be truncated towards zero (this does not include a string\n\
representation of a floating point number!) When converting a string, use\n\
the optional base. It is an error to supply a base when converting a\n\
non-string.";
static PyNumberMethods int_as_number = {
(binaryfunc)int_add, /*nb_add*/
(binaryfunc)int_sub, /*nb_subtract*/
......@@ -785,22 +820,40 @@ PyTypeObject PyInt_Type = {
"int",
sizeof(PyIntObject),
0,
(destructor)int_dealloc, /*tp_dealloc*/
(printfunc)int_print, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
(cmpfunc)int_compare, /*tp_compare*/
(reprfunc)int_repr, /*tp_repr*/
&int_as_number, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
(hashfunc)int_hash, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_CHECKTYPES /*tp_flags*/
(destructor)int_dealloc, /* tp_dealloc */
(printfunc)int_print, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc)int_compare, /* tp_compare */
(reprfunc)int_repr, /* tp_repr */
&int_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)int_hash, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
int_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
int_new, /* tp_new */
};
void
......
......@@ -96,12 +96,6 @@ static PyMethodDef iter_methods[] = {
{NULL, NULL} /* sentinel */
};
static PyObject *
iter_getattr(seqiterobject *it, char *name)
{
return Py_FindMethod(iter_methods, (PyObject *)it, name);
}
PyTypeObject PySeqIter_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0, /* ob_size */
......@@ -111,7 +105,7 @@ PyTypeObject PySeqIter_Type = {
/* methods */
(destructor)iter_dealloc, /* tp_dealloc */
0, /* tp_print */
(getattrfunc)iter_getattr, /* tp_getattr */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
......@@ -121,7 +115,7 @@ PyTypeObject PySeqIter_Type = {
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
......@@ -132,6 +126,13 @@ PyTypeObject PySeqIter_Type = {
0, /* tp_weaklistoffset */
(getiterfunc)iter_getiter, /* tp_iter */
(iternextfunc)iter_iternext, /* tp_iternext */
iter_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
};
/* -------------------------------------- */
......@@ -197,12 +198,6 @@ static PyMethodDef calliter_methods[] = {
{NULL, NULL} /* sentinel */
};
static PyObject *
calliter_getattr(calliterobject *it, char *name)
{
return Py_FindMethod(calliter_methods, (PyObject *)it, name);
}
static PyObject *
calliter_iternext(calliterobject *it)
{
......@@ -228,7 +223,7 @@ PyTypeObject PyCallIter_Type = {
/* methods */
(destructor)calliter_dealloc, /* tp_dealloc */
0, /* tp_print */
(getattrfunc)calliter_getattr, /* tp_getattr */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
......@@ -238,7 +233,7 @@ PyTypeObject PyCallIter_Type = {
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
......@@ -249,4 +244,11 @@ PyTypeObject PyCallIter_Type = {
0, /* tp_weaklistoffset */
(getiterfunc)iter_getiter, /* tp_iter */
(iternextfunc)calliter_iternext, /* tp_iternext */
calliter_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
};
......@@ -523,6 +523,10 @@ list_ass_slice(PyListObject *a, int ilow, int ihigh, PyObject *v)
Py_XDECREF(*p);
PyMem_DEL(recycle);
}
if (a->ob_size == 0 && a->ob_item != NULL) {
PyMem_FREE(a->ob_item);
a->ob_item = NULL;
}
return 0;
#undef b
}
......@@ -1289,16 +1293,18 @@ listsort(PyListObject *self, PyObject *args)
{
int err;
PyObject *compare = NULL;
PyTypeObject *savetype;
if (args != NULL) {
if (!PyArg_ParseTuple(args, "|O:sort", &compare))
return NULL;
}
savetype = self->ob_type;
self->ob_type = &immutable_list_type;
err = samplesortslice(self->ob_item,
self->ob_item + self->ob_size,
compare);
self->ob_type = &PyList_Type;
self->ob_type = savetype;
if (err < 0)
return NULL;
Py_INCREF(Py_None);
......@@ -1541,6 +1547,100 @@ list_richcompare(PyObject *v, PyObject *w, int op)
return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
}
/* Adapted from newer code by Tim */
static int
list_fill(PyListObject *result, PyObject *v)
{
PyObject *it; /* iter(v) */
int n; /* guess for result list size */
int i;
n = result->ob_size;
/* Special-case list(a_list), for speed. */
if (PyList_Check(v)) {
if (v == (PyObject *)result)
return 0; /* source is destination, we're done */
return list_ass_slice(result, 0, n, v);
}
/* Empty previous contents */
if (n != 0) {
if (list_ass_slice(result, 0, n, (PyObject *)NULL) != 0)
return -1;
}
/* Get iterator. There may be some low-level efficiency to be gained
* by caching the tp_iternext slot instead of using PyIter_Next()
* later, but premature optimization is the root etc.
*/
it = PyObject_GetIter(v);
if (it == NULL)
return -1;
/* Guess a result list size. */
n = -1; /* unknown */
if (PySequence_Check(v) &&
v->ob_type->tp_as_sequence->sq_length) {
n = PySequence_Size(v);
if (n < 0)
PyErr_Clear();
}
if (n < 0)
n = 8; /* arbitrary */
NRESIZE(result->ob_item, PyObject*, n);
if (result->ob_item == NULL)
goto error;
for (i = 0; i < n; i++)
result->ob_item[i] = NULL;
result->ob_size = n;
/* Run iterator to exhaustion. */
for (i = 0; ; i++) {
PyObject *item = PyIter_Next(it);
if (item == NULL) {
if (PyErr_Occurred())
goto error;
break;
}
if (i < n)
PyList_SET_ITEM(result, i, item); /* steals ref */
else {
int status = ins1(result, result->ob_size, item);
Py_DECREF(item); /* append creates a new ref */
if (status < 0)
goto error;
}
}
/* Cut back result list if initial guess was too large. */
if (i < n && result != NULL) {
if (list_ass_slice(result, i, n, (PyObject *)NULL) != 0)
goto error;
}
Py_DECREF(it);
return 0;
error:
Py_DECREF(it);
return -1;
}
static int
list_init(PyListObject *self, PyObject *args, PyObject *kw)
{
PyObject *arg = NULL;
static char *kwlist[] = {"sequence", 0};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg))
return -1;
if (arg != NULL)
return list_fill(self, arg);
if (self->ob_size > 0)
return list_ass_slice(self, 0, self->ob_size, (PyObject*)NULL);
return 0;
}
static char append_doc[] =
"L.append(object) -- append object to end";
static char extend_doc[] =
......@@ -1573,12 +1673,6 @@ static PyMethodDef list_methods[] = {
{NULL, NULL} /* sentinel */
};
static PyObject *
list_getattr(PyListObject *f, char *name)
{
return Py_FindMethod(list_methods, (PyObject *)f, name);
}
static PySequenceMethods list_as_sequence = {
(inquiry)list_length, /* sq_length */
(binaryfunc)list_concat, /* sq_concat */
......@@ -1592,6 +1686,10 @@ static PySequenceMethods list_as_sequence = {
(intargfunc)list_inplace_repeat, /* sq_inplace_repeat */
};
static char list_doc[] =
"list() -> new list\n"
"list(sequence) -> new list initialized from sequence's items";
PyTypeObject PyList_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
......@@ -1600,7 +1698,7 @@ PyTypeObject PyList_Type = {
0,
(destructor)list_dealloc, /* tp_dealloc */
(printfunc)list_print, /* tp_print */
(getattrfunc)list_getattr, /* tp_getattr */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)list_repr, /* tp_repr */
......@@ -1610,14 +1708,29 @@ PyTypeObject PyList_Type = {
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
0, /* tp_doc */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
list_doc, /* tp_doc */
(traverseproc)list_traverse, /* tp_traverse */
(inquiry)list_clear, /* tp_clear */
list_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
list_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)list_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
......@@ -1646,12 +1759,6 @@ static PyMethodDef immutable_list_methods[] = {
{NULL, NULL} /* sentinel */
};
static PyObject *
immutable_list_getattr(PyListObject *f, char *name)
{
return Py_FindMethod(immutable_list_methods, (PyObject *)f, name);
}
static int
immutable_list_ass(void)
{
......@@ -1678,7 +1785,7 @@ static PyTypeObject immutable_list_type = {
0,
0, /* Cannot happen */ /* tp_dealloc */
(printfunc)list_print, /* tp_print */
(getattrfunc)immutable_list_getattr, /* tp_getattr */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* Won't be called */ /* tp_compare */
(reprfunc)list_repr, /* tp_repr */
......@@ -1688,13 +1795,24 @@ static PyTypeObject immutable_list_type = {
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
0, /* tp_doc */
list_doc, /* tp_doc */
(traverseproc)list_traverse, /* tp_traverse */
0, /* tp_clear */
list_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
immutable_list_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_init */
/* NOTE: This is *not* the standard list_type struct! */
};
......@@ -2031,6 +2031,43 @@ long_hex(PyObject *v)
return long_format(v, 16, 1);
}
static PyObject *
long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *x = NULL;
int base = -909; /* unlikely! */
static char *kwlist[] = {"x", "base", 0};
assert(type == &PyLong_Type);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
&x, &base))
return NULL;
if (x == NULL)
return PyLong_FromLong(0L);
if (base == -909)
return PyNumber_Long(x);
else if (PyString_Check(x))
return PyLong_FromString(PyString_AS_STRING(x), NULL, base);
else if (PyUnicode_Check(x))
return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
PyUnicode_GET_SIZE(x),
base);
else {
PyErr_SetString(PyExc_TypeError,
"long() can't convert non-string with explicit base");
return NULL;
}
}
static char long_doc[] =
"long(x[, base]) -> integer\n\
\n\
Convert a string or number to a long integer, if possible. A floating\n\
point argument will be truncated towards zero (this does not include a\n\
string representation of a floating point number!) When converting a\n\
string, use the optional base. It is an error to supply a base when\n\
converting a non-string.";
static PyNumberMethods long_as_number = {
(binaryfunc) long_add, /*nb_add*/
(binaryfunc) long_sub, /*nb_subtract*/
......@@ -2070,24 +2107,42 @@ static PyNumberMethods long_as_number = {
PyTypeObject PyLong_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"long int",
sizeof(PyLongObject) - sizeof(digit),
sizeof(digit),
(destructor)long_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
(cmpfunc)long_compare, /*tp_compare*/
(reprfunc)long_repr, /*tp_repr*/
&long_as_number, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
(hashfunc)long_hash, /*tp_hash*/
0, /*tp_call*/
(reprfunc)long_str, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_CHECKTYPES /*tp_flags*/
0, /* ob_size */
"long", /* tp_name */
sizeof(PyLongObject) - sizeof(digit), /* tp_basicsize */
sizeof(digit), /* tp_itemsize */
(destructor)long_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc)long_compare, /* tp_compare */
(reprfunc)long_repr, /* tp_repr */
&long_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)long_hash, /* tp_hash */
0, /* tp_call */
(reprfunc)long_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
long_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
long_new, /* tp_new */
};
......@@ -3,8 +3,6 @@
#include "Python.h"
#include "token.h"
static PyCFunctionObject *free_list = NULL;
PyObject *
......@@ -69,6 +67,23 @@ meth_dealloc(PyCFunctionObject *m)
free_list = m;
}
static PyObject *
meth_get__doc__(PyCFunctionObject *m, void *closure)
{
char *doc = m->m_ml->ml_doc;
if (doc != NULL)
return PyString_FromString(doc);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
meth_get__name__(PyCFunctionObject *m, void *closure)
{
return PyString_FromString(m->m_ml->ml_name);
}
static int
meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
{
......@@ -79,39 +94,28 @@ meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
}
static PyObject *
meth_getattr(PyCFunctionObject *m, char *name)
meth_get__self__(PyCFunctionObject *m, void *closure)
{
if (strcmp(name, "__name__") == 0) {
return PyString_FromString(m->m_ml->ml_name);
}
if (strcmp(name, "__doc__") == 0) {
char *doc = m->m_ml->ml_doc;
if (doc != NULL)
return PyString_FromString(doc);
Py_INCREF(Py_None);
return Py_None;
}
if (strcmp(name, "__self__") == 0) {
PyObject *self;
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"method.__self__ not accessible in restricted mode");
return NULL;
}
self = m->m_self;
if (self == NULL)
self = Py_None;
Py_INCREF(self);
return self;
}
if (strcmp(name, "__members__") == 0) {
return Py_BuildValue("[sss]",
"__doc__", "__name__", "__self__");
PyObject *self;
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"method.__self__ not accessible in restricted mode");
return NULL;
}
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
self = m->m_self;
if (self == NULL)
self = Py_None;
Py_INCREF(self);
return self;
}
static struct getsetlist meth_getsets [] = {
{"__doc__", (getter)meth_get__doc__, NULL, NULL},
{"__name__", (getter)meth_get__name__, NULL, NULL},
{"__self__", (getter)meth_get__self__, NULL, NULL},
{0}
};
static PyObject *
meth_repr(PyCFunctionObject *m)
{
......@@ -159,6 +163,41 @@ meth_hash(PyCFunctionObject *a)
return x;
}
static PyObject *
meth_call(PyObject *func, PyObject *arg, PyObject *kw)
{
PyCFunctionObject* f = (PyCFunctionObject*)func;
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
PyObject *self = PyCFunction_GET_SELF(func);
int flags = PyCFunction_GET_FLAGS(func);
if (flags & METH_KEYWORDS) {
return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
}
if (kw != NULL && PyDict_Size(kw) != 0) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes no keyword arguments",
f->m_ml->ml_name);
return NULL;
}
if (flags & METH_VARARGS) {
return (*meth)(self, arg);
}
if (!(flags & METH_VARARGS)) {
/* the really old style */
int size = PyTuple_GET_SIZE(arg);
if (size == 1)
arg = PyTuple_GET_ITEM(arg, 0);
else if (size == 0)
arg = NULL;
return (*meth)(self, arg);
}
/* should never get here ??? */
PyErr_BadInternalCall();
return NULL;
}
PyTypeObject PyCFunction_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
......@@ -167,7 +206,7 @@ PyTypeObject PyCFunction_Type = {
0,
(destructor)meth_dealloc, /* tp_dealloc */
0, /* tp_print */
(getattrfunc)meth_getattr, /* tp_getattr */
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc)meth_compare, /* tp_compare */
(reprfunc)meth_repr, /* tp_repr */
......@@ -175,14 +214,24 @@ PyTypeObject PyCFunction_Type = {
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)meth_hash, /* tp_hash */
0, /* tp_call */
meth_call, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)meth_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
meth_getsets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
};
/* List all methods in a chain -- helper for findmethodinchain */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -44,6 +44,7 @@ extern void init_locale(void);
extern void init_codecs(void);
extern void initxreadlines(void);
extern void init_weakref(void);
extern void initxxsubtype(void);
/* XXX tim: what's the purpose of ADDMODULE MARKER? */
/* -- ADDMODULE MARKER 1 -- */
......@@ -98,6 +99,8 @@ struct _inittab _PyImport_Inittab[] = {
{"xreadlines", initxreadlines},
{"_weakref", init_weakref},
{"xxsubtype", initxxsubtype},
/* XXX tim: what's the purpose of ADDMODULE MARKER? */
/* -- ADDMODULE MARKER 2 -- */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -43,7 +43,7 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
/* XXX Perhaps the magic number should be frozen and a version field
added to the .pyc file header? */
/* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */
#define MAGIC (60420 | ((long)'\r'<<16) | ((long)'\n'<<24))
#define MAGIC (60717 | ((long)'\r'<<16) | ((long)'\n'<<24))
/* Magic word as global; note that _PyImport_Init() can change the
value of this global to accommodate for alterations of how the
......@@ -1968,8 +1968,11 @@ PyImport_Import(PyObject *module_name)
}
/* Get the __import__ function from the builtins */
if (PyDict_Check(builtins))
if (PyDict_Check(builtins)) {
import = PyObject_GetItem(builtins, import_str);
if (import == NULL)
PyErr_SetObject(PyExc_KeyError, import_str);
}
else
import = PyObject_GetAttr(builtins, import_str);
if (import == NULL)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment