mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Merge of descr-branch back into trunk.
This commit is contained in:
		
							parent
							
								
									52d55a3926
								
							
						
					
					
						commit
						6d6c1a35e0
					
				
					 57 changed files with 6923 additions and 1309 deletions
				
			
		| 
						 | 
					@ -89,6 +89,7 @@
 | 
				
			||||||
#include "sliceobject.h"
 | 
					#include "sliceobject.h"
 | 
				
			||||||
#include "cellobject.h"
 | 
					#include "cellobject.h"
 | 
				
			||||||
#include "iterobject.h"
 | 
					#include "iterobject.h"
 | 
				
			||||||
 | 
					#include "descrobject.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "codecs.h"
 | 
					#include "codecs.h"
 | 
				
			||||||
#include "pyerrors.h"
 | 
					#include "pyerrors.h"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,6 +295,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,
 | 
					     DL_IMPORT(PyObject *) PyObject_CallObject(PyObject *callable_object,
 | 
				
			||||||
                                               PyObject *args);
 | 
					                                               PyObject *args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,9 @@ DL_IMPORT(int) Py_MakePendingCalls(void);
 | 
				
			||||||
DL_IMPORT(void) Py_SetRecursionLimit(int);
 | 
					DL_IMPORT(void) Py_SetRecursionLimit(int);
 | 
				
			||||||
DL_IMPORT(int) Py_GetRecursionLimit(void);
 | 
					DL_IMPORT(int) Py_GetRecursionLimit(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DL_IMPORT(char *) PyEval_GetFuncName(PyObject *);
 | 
				
			||||||
 | 
					DL_IMPORT(char *) PyEval_GetFuncDesc(PyObject *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Interface for threads.
 | 
					/* Interface for threads.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   A module that plans to do a blocking system call (or something else
 | 
					   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 *) PyInstance_NewRaw(PyObject *, PyObject *);
 | 
				
			||||||
extern DL_IMPORT(PyObject *) PyMethod_New(PyObject *, 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*
 | 
					/* Macros for direct access to these values. Type checks are *not*
 | 
				
			||||||
   done, so use with care. */
 | 
					   done, so use with care. */
 | 
				
			||||||
#define PyMethod_GET_FUNCTION(meth) \
 | 
					#define PyMethod_GET_FUNCTION(meth) \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										32
									
								
								Include/descrobject.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								Include/descrobject.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					/* 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 */
 | 
					/* 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;
 | 
					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_New(void);
 | 
				
			||||||
extern DL_IMPORT(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
 | 
					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(PyObject *) PyDict_Items(PyObject *mp);
 | 
				
			||||||
extern DL_IMPORT(int) PyDict_Size(PyObject *mp);
 | 
					extern DL_IMPORT(int) PyDict_Size(PyObject *mp);
 | 
				
			||||||
extern DL_IMPORT(PyObject *) PyDict_Copy(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);
 | 
					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_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
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,13 @@ extern DL_IMPORT(int) PyFunction_SetClosure(PyObject *, PyObject *);
 | 
				
			||||||
#define PyFunction_GET_CLOSURE(func) \
 | 
					#define PyFunction_GET_CLOSURE(func) \
 | 
				
			||||||
	(((PyFunctionObject *)func) -> func_closure)
 | 
						(((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
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ typedef struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern DL_IMPORT(PyTypeObject) PyList_Type;
 | 
					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(PyObject *) PyList_New(int size);
 | 
				
			||||||
extern DL_IMPORT(int) PyList_Size(PyObject *);
 | 
					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_AddIntConstant(PyObject *, char *, long);
 | 
				
			||||||
extern DL_IMPORT(int) PyModule_AddStringConstant(PyObject *, char *, char *);
 | 
					extern DL_IMPORT(int) PyModule_AddStringConstant(PyObject *, char *, char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PYTHON_API_VERSION 1010
 | 
					#define PYTHON_API_VERSION 1011
 | 
				
			||||||
#define PYTHON_API_STRING "1010"
 | 
					#define PYTHON_API_STRING "1011"
 | 
				
			||||||
/* The API version is maintained (independently from the Python version)
 | 
					/* The API version is maintained (independently from the Python version)
 | 
				
			||||||
   so we can detect mismatches between the interpreter and dynamically
 | 
					   so we can detect mismatches between the interpreter and dynamically
 | 
				
			||||||
   loaded modules.  These are diagnosed by an error message but
 | 
					   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
 | 
					   Please add a line or two to the top of this log for each API
 | 
				
			||||||
   version change:
 | 
					   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
 | 
					   25-Jan-2001  FLD     1010    Parameters added to PyCode_New() and
 | 
				
			||||||
                                PyFrame_New(); Python 2.1a2
 | 
					                                PyFrame_New(); Python 2.1a2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,6 +202,11 @@ typedef long (*hashfunc)(PyObject *);
 | 
				
			||||||
typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
 | 
					typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
 | 
				
			||||||
typedef PyObject *(*getiterfunc) (PyObject *);
 | 
					typedef PyObject *(*getiterfunc) (PyObject *);
 | 
				
			||||||
typedef PyObject *(*iternextfunc) (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 {
 | 
					typedef struct _typeobject {
 | 
				
			||||||
	PyObject_VAR_HEAD
 | 
						PyObject_VAR_HEAD
 | 
				
			||||||
| 
						 | 
					@ -255,18 +260,48 @@ typedef struct _typeobject {
 | 
				
			||||||
	getiterfunc tp_iter;
 | 
						getiterfunc tp_iter;
 | 
				
			||||||
	iternextfunc tp_iternext;
 | 
						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
 | 
					#ifdef COUNT_ALLOCS
 | 
				
			||||||
	/* these must be last and never explicitly initialized */
 | 
						/* these must be last and never explicitly initialized */
 | 
				
			||||||
	int tp_alloc;
 | 
						int tp_allocs;
 | 
				
			||||||
	int tp_free;
 | 
						int tp_frees;
 | 
				
			||||||
	int tp_maxalloc;
 | 
						int tp_maxalloc;
 | 
				
			||||||
	struct _typeobject *tp_next;
 | 
						struct _typeobject *tp_next;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
} PyTypeObject;
 | 
					} 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 */
 | 
					/* Generic operations on objects */
 | 
				
			||||||
extern DL_IMPORT(int) PyObject_Print(PyObject *, FILE *, int);
 | 
					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(PyObject *) PyObject_GetAttr(PyObject *, PyObject *);
 | 
				
			||||||
extern DL_IMPORT(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *);
 | 
					extern DL_IMPORT(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *);
 | 
				
			||||||
extern DL_IMPORT(int) PyObject_HasAttr(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(long) PyObject_Hash(PyObject *);
 | 
				
			||||||
extern DL_IMPORT(int) PyObject_IsTrue(PyObject *);
 | 
					extern DL_IMPORT(int) PyObject_IsTrue(PyObject *);
 | 
				
			||||||
extern DL_IMPORT(int) PyObject_Not(PyObject *);
 | 
					extern DL_IMPORT(int) PyObject_Not(PyObject *);
 | 
				
			||||||
| 
						 | 
					@ -357,6 +396,18 @@ given type object has a specified feature.
 | 
				
			||||||
/* tp_iter is defined */
 | 
					/* tp_iter is defined */
 | 
				
			||||||
#define Py_TPFLAGS_HAVE_ITER (1L<<7)
 | 
					#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  ( \
 | 
					#define Py_TPFLAGS_DEFAULT  ( \
 | 
				
			||||||
                             Py_TPFLAGS_HAVE_GETCHARBUFFER | \
 | 
					                             Py_TPFLAGS_HAVE_GETCHARBUFFER | \
 | 
				
			||||||
                             Py_TPFLAGS_HAVE_SEQUENCE_IN | \
 | 
					                             Py_TPFLAGS_HAVE_SEQUENCE_IN | \
 | 
				
			||||||
| 
						 | 
					@ -364,6 +415,7 @@ given type object has a specified feature.
 | 
				
			||||||
                             Py_TPFLAGS_HAVE_RICHCOMPARE | \
 | 
					                             Py_TPFLAGS_HAVE_RICHCOMPARE | \
 | 
				
			||||||
                             Py_TPFLAGS_HAVE_WEAKREFS | \
 | 
					                             Py_TPFLAGS_HAVE_WEAKREFS | \
 | 
				
			||||||
                             Py_TPFLAGS_HAVE_ITER | \
 | 
					                             Py_TPFLAGS_HAVE_ITER | \
 | 
				
			||||||
 | 
					                             Py_TPFLAGS_HAVE_CLASS | \
 | 
				
			||||||
                            0)
 | 
					                            0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PyType_HasFeature(t,f)  (((t)->tp_flags & (f)) != 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
 | 
					#ifndef Py_TRACE_REFS
 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
					#ifdef COUNT_ALLOCS
 | 
				
			||||||
#define _Py_Dealloc(op) ((op)->ob_type->tp_free++, (*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
 | 
					#define _Py_Dealloc(op) ((op)->ob_type->tp_frees++, (*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
 | 
				
			||||||
#define _Py_ForgetReference(op) ((op)->ob_type->tp_free++)
 | 
					#define _Py_ForgetReference(op) ((op)->ob_type->tp_frees++)
 | 
				
			||||||
#else /* !COUNT_ALLOCS */
 | 
					#else /* !COUNT_ALLOCS */
 | 
				
			||||||
#define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op))
 | 
					#define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op))
 | 
				
			||||||
#define _Py_ForgetReference(op) /*empty*/
 | 
					#define _Py_ForgetReference(op) /*empty*/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,6 +236,12 @@ extern DL_IMPORT(void) _PyObject_Del(PyObject *);
 | 
				
			||||||
#define PyObject_GC_Fini(op)
 | 
					#define PyObject_GC_Fini(op)
 | 
				
			||||||
#define PyObject_AS_GC(op) (op)
 | 
					#define PyObject_AS_GC(op) (op)
 | 
				
			||||||
#define PyObject_FROM_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
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -269,6 +275,13 @@ typedef struct _gc_head {
 | 
				
			||||||
/* Get the object given the PyGC_Head */
 | 
					/* Get the object given the PyGC_Head */
 | 
				
			||||||
#define PyObject_FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1))
 | 
					#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 *);
 | 
					extern DL_IMPORT(void) _PyGC_Dump(PyGC_Head *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* WITH_CYCLE_GC */
 | 
					#endif /* WITH_CYCLE_GC */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,13 +23,13 @@
 | 
				
			||||||
#define PY_MINOR_VERSION	2
 | 
					#define PY_MINOR_VERSION	2
 | 
				
			||||||
#define PY_MICRO_VERSION	0
 | 
					#define PY_MICRO_VERSION	0
 | 
				
			||||||
#define PY_RELEASE_LEVEL	PY_RELEASE_LEVEL_ALPHA
 | 
					#define PY_RELEASE_LEVEL	PY_RELEASE_LEVEL_ALPHA
 | 
				
			||||||
#define PY_RELEASE_SERIAL	0
 | 
					#define PY_RELEASE_SERIAL	1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Version as a string */
 | 
					/* Version as a string */
 | 
				
			||||||
#define PY_VERSION		"2.2a0"
 | 
					#define PY_VERSION		"2.2a1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Historic */
 | 
					/* Historic */
 | 
				
			||||||
#define PATCHLEVEL		"2.2a0"
 | 
					#define PATCHLEVEL		"2.2a1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
 | 
					/* 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 >= ... */
 | 
					   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 *) _PyBuiltin_Init(void);
 | 
				
			||||||
DL_IMPORT(PyObject *) _PySys_Init(void);
 | 
					DL_IMPORT(PyObject *) _PySys_Init(void);
 | 
				
			||||||
DL_IMPORT(void) _PyImport_Init(void);
 | 
					DL_IMPORT(void) _PyImport_Init(void);
 | 
				
			||||||
DL_IMPORT(void) init_exceptions(void);
 | 
					DL_IMPORT(void) _PyExc_Init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Various internal finalizers */
 | 
					/* Various internal finalizers */
 | 
				
			||||||
DL_IMPORT(void) fini_exceptions(void);
 | 
					DL_IMPORT(void) _PyExc_Fini(void);
 | 
				
			||||||
DL_IMPORT(void) _PyImport_Fini(void);
 | 
					DL_IMPORT(void) _PyImport_Fini(void);
 | 
				
			||||||
DL_IMPORT(void) PyMethod_Fini(void);
 | 
					DL_IMPORT(void) PyMethod_Fini(void);
 | 
				
			||||||
DL_IMPORT(void) PyFrame_Fini(void);
 | 
					DL_IMPORT(void) PyFrame_Fini(void);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -504,6 +504,7 @@ def save_global(self, object, name = None):
 | 
				
			||||||
    dispatch[ClassType] = save_global
 | 
					    dispatch[ClassType] = save_global
 | 
				
			||||||
    dispatch[FunctionType] = save_global
 | 
					    dispatch[FunctionType] = save_global
 | 
				
			||||||
    dispatch[BuiltinFunctionType] = save_global
 | 
					    dispatch[BuiltinFunctionType] = save_global
 | 
				
			||||||
 | 
					    dispatch[TypeType] = save_global
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _keep_alive(x, memo):
 | 
					def _keep_alive(x, memo):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ def repr_dictionary(self, x, level):
 | 
				
			||||||
            s = s + ': ' + self.repr1(x[key], level-1)
 | 
					            s = s + ': ' + self.repr1(x[key], level-1)
 | 
				
			||||||
        if n > self.maxdict: s = s + ', ...'
 | 
					        if n > self.maxdict: s = s + ', ...'
 | 
				
			||||||
        return '{' + s + '}'
 | 
					        return '{' + s + '}'
 | 
				
			||||||
    def repr_string(self, x, level):
 | 
					    def repr_str(self, x, level):
 | 
				
			||||||
        s = `x[:self.maxstring]`
 | 
					        s = `x[:self.maxstring]`
 | 
				
			||||||
        if len(s) > self.maxstring:
 | 
					        if len(s) > self.maxstring:
 | 
				
			||||||
            i = max(0, (self.maxstring-3)/2)
 | 
					            i = max(0, (self.maxstring-3)/2)
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,7 @@ def repr_string(self, x, level):
 | 
				
			||||||
            s = `x[:i] + x[len(x)-j:]`
 | 
					            s = `x[:i] + x[len(x)-j:]`
 | 
				
			||||||
            s = s[:i] + '...' + s[len(s)-j:]
 | 
					            s = s[:i] + '...' + s[len(s)-j:]
 | 
				
			||||||
        return s
 | 
					        return s
 | 
				
			||||||
    def repr_long_int(self, x, level):
 | 
					    def repr_long(self, x, level):
 | 
				
			||||||
        s = `x` # XXX Hope this isn't too slow...
 | 
					        s = `x` # XXX Hope this isn't too slow...
 | 
				
			||||||
        if len(s) > self.maxlong:
 | 
					        if len(s) > self.maxlong:
 | 
				
			||||||
            i = max(0, (self.maxlong-3)/2)
 | 
					            i = max(0, (self.maxlong-3)/2)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										829
									
								
								Lib/test/test_descr.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										829
									
								
								Lib/test/test_descr.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,829 @@
 | 
				
			||||||
 | 
					# Test descriptor-related enhancements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from test_support import verify, verbose
 | 
				
			||||||
 | 
					from copy import deepcopy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def testunop(a, res, expr="len(a)", meth="__len__"):
 | 
				
			||||||
 | 
					    if verbose: print "checking", expr
 | 
				
			||||||
 | 
					    dict = {'a': a}
 | 
				
			||||||
 | 
					    verify(eval(expr, dict) == res)
 | 
				
			||||||
 | 
					    t = type(a)
 | 
				
			||||||
 | 
					    m = getattr(t, meth)
 | 
				
			||||||
 | 
					    verify(m == t.__dict__[meth])
 | 
				
			||||||
 | 
					    verify(m(a) == res)
 | 
				
			||||||
 | 
					    bm = getattr(a, meth)
 | 
				
			||||||
 | 
					    verify(bm() == res)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def testbinop(a, b, res, expr="a+b", meth="__add__"):
 | 
				
			||||||
 | 
					    if verbose: print "checking", expr
 | 
				
			||||||
 | 
					    dict = {'a': a, 'b': b}
 | 
				
			||||||
 | 
					    verify(eval(expr, dict) == res)
 | 
				
			||||||
 | 
					    t = type(a)
 | 
				
			||||||
 | 
					    m = getattr(t, meth)
 | 
				
			||||||
 | 
					    verify(m == t.__dict__[meth])
 | 
				
			||||||
 | 
					    verify(m(a, b) == res)
 | 
				
			||||||
 | 
					    bm = getattr(a, meth)
 | 
				
			||||||
 | 
					    verify(bm(b) == res)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def testternop(a, b, c, res, expr="a[b:c]", meth="__getslice__"):
 | 
				
			||||||
 | 
					    if verbose: print "checking", expr
 | 
				
			||||||
 | 
					    dict = {'a': a, 'b': b, 'c': c}
 | 
				
			||||||
 | 
					    verify(eval(expr, dict) == res)
 | 
				
			||||||
 | 
					    t = type(a)
 | 
				
			||||||
 | 
					    m = getattr(t, meth)
 | 
				
			||||||
 | 
					    verify(m == t.__dict__[meth])
 | 
				
			||||||
 | 
					    verify(m(a, b, c) == res)
 | 
				
			||||||
 | 
					    bm = getattr(a, meth)
 | 
				
			||||||
 | 
					    verify(bm(b, c) == res)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def testsetop(a, b, res, stmt="a+=b", meth="__iadd__"):
 | 
				
			||||||
 | 
					    if verbose: print "checking", stmt
 | 
				
			||||||
 | 
					    dict = {'a': deepcopy(a), 'b': b}
 | 
				
			||||||
 | 
					    exec stmt in dict
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					    t = type(a)
 | 
				
			||||||
 | 
					    m = getattr(t, meth)
 | 
				
			||||||
 | 
					    verify(m == t.__dict__[meth])
 | 
				
			||||||
 | 
					    dict['a'] = deepcopy(a)
 | 
				
			||||||
 | 
					    m(dict['a'], b)
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					    dict['a'] = deepcopy(a)
 | 
				
			||||||
 | 
					    bm = getattr(dict['a'], meth)
 | 
				
			||||||
 | 
					    bm(b)
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def testset2op(a, b, c, res, stmt="a[b]=c", meth="__setitem__"):
 | 
				
			||||||
 | 
					    if verbose: print "checking", stmt
 | 
				
			||||||
 | 
					    dict = {'a': deepcopy(a), 'b': b, 'c': c}
 | 
				
			||||||
 | 
					    exec stmt in dict
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					    t = type(a)
 | 
				
			||||||
 | 
					    m = getattr(t, meth)
 | 
				
			||||||
 | 
					    verify(m == t.__dict__[meth])
 | 
				
			||||||
 | 
					    dict['a'] = deepcopy(a)
 | 
				
			||||||
 | 
					    m(dict['a'], b, c)
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					    dict['a'] = deepcopy(a)
 | 
				
			||||||
 | 
					    bm = getattr(dict['a'], meth)
 | 
				
			||||||
 | 
					    bm(b, c)
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def testset3op(a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
 | 
				
			||||||
 | 
					    if verbose: print "checking", stmt
 | 
				
			||||||
 | 
					    dict = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d}
 | 
				
			||||||
 | 
					    exec stmt in dict
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					    t = type(a)
 | 
				
			||||||
 | 
					    m = getattr(t, meth)
 | 
				
			||||||
 | 
					    verify(m == t.__dict__[meth])
 | 
				
			||||||
 | 
					    dict['a'] = deepcopy(a)
 | 
				
			||||||
 | 
					    m(dict['a'], b, c, d)
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					    dict['a'] = deepcopy(a)
 | 
				
			||||||
 | 
					    bm = getattr(dict['a'], meth)
 | 
				
			||||||
 | 
					    bm(b, c, d)
 | 
				
			||||||
 | 
					    verify(dict['a'] == res)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def lists():
 | 
				
			||||||
 | 
					    if verbose: print "Testing list operations..."
 | 
				
			||||||
 | 
					    testbinop([1], [2], [1,2], "a+b", "__add__")
 | 
				
			||||||
 | 
					    testbinop([1,2,3], 2, 1, "b in a", "__contains__")
 | 
				
			||||||
 | 
					    testbinop([1,2,3], 4, 0, "b in a", "__contains__")
 | 
				
			||||||
 | 
					    testbinop([1,2,3], 1, 2, "a[b]", "__getitem__")
 | 
				
			||||||
 | 
					    testternop([1,2,3], 0, 2, [1,2], "a[b:c]", "__getslice__")
 | 
				
			||||||
 | 
					    testsetop([1], [2], [1,2], "a+=b", "__iadd__")
 | 
				
			||||||
 | 
					    testsetop([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__")
 | 
				
			||||||
 | 
					    testunop([1,2,3], 3, "len(a)", "__len__")
 | 
				
			||||||
 | 
					    testbinop([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__")
 | 
				
			||||||
 | 
					    testbinop([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__")
 | 
				
			||||||
 | 
					    testset2op([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__")
 | 
				
			||||||
 | 
					    testset3op([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d", "__setslice__")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def dicts():
 | 
				
			||||||
 | 
					    if verbose: print "Testing dict operations..."
 | 
				
			||||||
 | 
					    testbinop({1:2}, {2:1}, -1, "cmp(a,b)", "__cmp__")
 | 
				
			||||||
 | 
					    testbinop({1:2,3:4}, 1, 1, "b in a", "__contains__")
 | 
				
			||||||
 | 
					    testbinop({1:2,3:4}, 2, 0, "b in a", "__contains__")
 | 
				
			||||||
 | 
					    testbinop({1:2,3:4}, 1, 2, "a[b]", "__getitem__")
 | 
				
			||||||
 | 
					    d = {1:2,3:4}
 | 
				
			||||||
 | 
					    l1 = []
 | 
				
			||||||
 | 
					    for i in d.keys(): l1.append(i)
 | 
				
			||||||
 | 
					    l = []
 | 
				
			||||||
 | 
					    for i in iter(d): l.append(i)
 | 
				
			||||||
 | 
					    verify(l == l1)
 | 
				
			||||||
 | 
					    l = []
 | 
				
			||||||
 | 
					    for i in d.__iter__(): l.append(i)
 | 
				
			||||||
 | 
					    verify(l == l1)
 | 
				
			||||||
 | 
					    l = []
 | 
				
			||||||
 | 
					    for i in dictionary.__iter__(d): l.append(i)
 | 
				
			||||||
 | 
					    verify(l == l1)
 | 
				
			||||||
 | 
					    d = {1:2, 3:4}
 | 
				
			||||||
 | 
					    testunop(d, 2, "len(a)", "__len__")
 | 
				
			||||||
 | 
					    verify(eval(repr(d), {}) == d)
 | 
				
			||||||
 | 
					    verify(eval(d.__repr__(), {}) == d)
 | 
				
			||||||
 | 
					    testset2op({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", "__setitem__")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					binops = {
 | 
				
			||||||
 | 
					    'add': '+',
 | 
				
			||||||
 | 
					    'sub': '-',
 | 
				
			||||||
 | 
					    'mul': '*',
 | 
				
			||||||
 | 
					    'div': '/',
 | 
				
			||||||
 | 
					    'mod': '%',
 | 
				
			||||||
 | 
					    'divmod': 'divmod',
 | 
				
			||||||
 | 
					    'pow': '**',
 | 
				
			||||||
 | 
					    'lshift': '<<',
 | 
				
			||||||
 | 
					    'rshift': '>>',
 | 
				
			||||||
 | 
					    'and': '&',
 | 
				
			||||||
 | 
					    'xor': '^',
 | 
				
			||||||
 | 
					    'or': '|',
 | 
				
			||||||
 | 
					    'cmp': 'cmp',
 | 
				
			||||||
 | 
					    'lt': '<',
 | 
				
			||||||
 | 
					    'le': '<=',
 | 
				
			||||||
 | 
					    'eq': '==',
 | 
				
			||||||
 | 
					    'ne': '!=',
 | 
				
			||||||
 | 
					    'gt': '>',
 | 
				
			||||||
 | 
					    'ge': '>=',
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for name, expr in binops.items():
 | 
				
			||||||
 | 
					    if expr.islower():
 | 
				
			||||||
 | 
					        expr = expr + "(a, b)"
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        expr = 'a %s b' % expr
 | 
				
			||||||
 | 
					    binops[name] = expr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unops = {
 | 
				
			||||||
 | 
					    'pos': '+',
 | 
				
			||||||
 | 
					    'neg': '-',
 | 
				
			||||||
 | 
					    'abs': 'abs',
 | 
				
			||||||
 | 
					    'invert': '~',
 | 
				
			||||||
 | 
					    'int': 'int',
 | 
				
			||||||
 | 
					    'long': 'long',
 | 
				
			||||||
 | 
					    'float': 'float',
 | 
				
			||||||
 | 
					    'oct': 'oct',
 | 
				
			||||||
 | 
					    'hex': 'hex',
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for name, expr in unops.items():
 | 
				
			||||||
 | 
					    if expr.islower():
 | 
				
			||||||
 | 
					        expr = expr + "(a)"
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        expr = '%s a' % expr
 | 
				
			||||||
 | 
					    unops[name] = expr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def numops(a, b, skip=[]):
 | 
				
			||||||
 | 
					    dict = {'a': a, 'b': b}
 | 
				
			||||||
 | 
					    for name, expr in binops.items():
 | 
				
			||||||
 | 
					        if name not in skip:
 | 
				
			||||||
 | 
					            name = "__%s__" % name
 | 
				
			||||||
 | 
					            if hasattr(a, name):
 | 
				
			||||||
 | 
					                res = eval(expr, dict)
 | 
				
			||||||
 | 
					                testbinop(a, b, res, expr, name)
 | 
				
			||||||
 | 
					    for name, expr in unops.items():
 | 
				
			||||||
 | 
					        name = "__%s__" % name
 | 
				
			||||||
 | 
					        if hasattr(a, name):
 | 
				
			||||||
 | 
					            res = eval(expr, dict)
 | 
				
			||||||
 | 
					            testunop(a, res, expr, name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def ints():
 | 
				
			||||||
 | 
					    if verbose: print "Testing int operations..."
 | 
				
			||||||
 | 
					    numops(100, 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def longs():
 | 
				
			||||||
 | 
					    if verbose: print "Testing long operations..."
 | 
				
			||||||
 | 
					    numops(100L, 3L)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def floats():
 | 
				
			||||||
 | 
					    if verbose: print "Testing float operations..."
 | 
				
			||||||
 | 
					    numops(100.0, 3.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def complexes():
 | 
				
			||||||
 | 
					    if verbose: print "Testing complex operations..."
 | 
				
			||||||
 | 
					    numops(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge'])
 | 
				
			||||||
 | 
					    class Number(complex):
 | 
				
			||||||
 | 
					        __slots__ = ['prec']
 | 
				
			||||||
 | 
					        def __init__(self, *args, **kwds):
 | 
				
			||||||
 | 
					            self.prec = kwds.get('prec', 12)
 | 
				
			||||||
 | 
					        def __repr__(self):
 | 
				
			||||||
 | 
					            prec = self.prec
 | 
				
			||||||
 | 
					            if self.imag == 0.0:
 | 
				
			||||||
 | 
					                return "%.*g" % (prec, self.real)
 | 
				
			||||||
 | 
					            if self.real == 0.0:
 | 
				
			||||||
 | 
					                return "%.*gj" % (prec, self.imag)
 | 
				
			||||||
 | 
					            return "(%.*g+%.*gj)" % (prec, self.real, prec, self.imag)
 | 
				
			||||||
 | 
					        __str__ = __repr__
 | 
				
			||||||
 | 
					    a = Number(3.14, prec=6)
 | 
				
			||||||
 | 
					    verify(`a` == "3.14")
 | 
				
			||||||
 | 
					    verify(a.prec == 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def spamlists():
 | 
				
			||||||
 | 
					    if verbose: print "Testing spamlist operations..."
 | 
				
			||||||
 | 
					    import copy, xxsubtype as spam
 | 
				
			||||||
 | 
					    def spamlist(l, memo=None):
 | 
				
			||||||
 | 
					        import xxsubtype as spam
 | 
				
			||||||
 | 
					        return spam.spamlist(l)
 | 
				
			||||||
 | 
					    # This is an ugly hack:
 | 
				
			||||||
 | 
					    copy._deepcopy_dispatch[spam.spamlist] = spamlist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    testbinop(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b", "__add__")
 | 
				
			||||||
 | 
					    testbinop(spamlist([1,2,3]), 2, 1, "b in a", "__contains__")
 | 
				
			||||||
 | 
					    testbinop(spamlist([1,2,3]), 4, 0, "b in a", "__contains__")
 | 
				
			||||||
 | 
					    testbinop(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__")
 | 
				
			||||||
 | 
					    testternop(spamlist([1,2,3]), 0, 2, spamlist([1,2]),
 | 
				
			||||||
 | 
					               "a[b:c]", "__getslice__")
 | 
				
			||||||
 | 
					    testsetop(spamlist([1]), spamlist([2]), spamlist([1,2]),
 | 
				
			||||||
 | 
					              "a+=b", "__iadd__")
 | 
				
			||||||
 | 
					    testsetop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b", "__imul__")
 | 
				
			||||||
 | 
					    testunop(spamlist([1,2,3]), 3, "len(a)", "__len__")
 | 
				
			||||||
 | 
					    testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b", "__mul__")
 | 
				
			||||||
 | 
					    testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a", "__rmul__")
 | 
				
			||||||
 | 
					    testset2op(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c", "__setitem__")
 | 
				
			||||||
 | 
					    testset3op(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]),
 | 
				
			||||||
 | 
					               spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__")
 | 
				
			||||||
 | 
					    # Test subclassing
 | 
				
			||||||
 | 
					    class C(spam.spamlist):
 | 
				
			||||||
 | 
					        def foo(self): return 1
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    verify(a == [])
 | 
				
			||||||
 | 
					    verify(a.foo() == 1)
 | 
				
			||||||
 | 
					    a.append(100)
 | 
				
			||||||
 | 
					    verify(a == [100])
 | 
				
			||||||
 | 
					    verify(a.getstate() == 0)
 | 
				
			||||||
 | 
					    a.setstate(42)
 | 
				
			||||||
 | 
					    verify(a.getstate() == 42)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def spamdicts():
 | 
				
			||||||
 | 
					    if verbose: print "Testing spamdict operations..."
 | 
				
			||||||
 | 
					    import copy, xxsubtype as spam
 | 
				
			||||||
 | 
					    def spamdict(d, memo=None):
 | 
				
			||||||
 | 
					        import xxsubtype as spam
 | 
				
			||||||
 | 
					        sd = spam.spamdict()
 | 
				
			||||||
 | 
					        for k, v in d.items(): sd[k] = v
 | 
				
			||||||
 | 
					        return sd
 | 
				
			||||||
 | 
					    # This is an ugly hack:
 | 
				
			||||||
 | 
					    copy._deepcopy_dispatch[spam.spamdict] = spamdict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    testbinop(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)", "__cmp__")
 | 
				
			||||||
 | 
					    testbinop(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__")
 | 
				
			||||||
 | 
					    testbinop(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__")
 | 
				
			||||||
 | 
					    testbinop(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__")
 | 
				
			||||||
 | 
					    d = spamdict({1:2,3:4})
 | 
				
			||||||
 | 
					    l1 = []
 | 
				
			||||||
 | 
					    for i in d.keys(): l1.append(i)
 | 
				
			||||||
 | 
					    l = []
 | 
				
			||||||
 | 
					    for i in iter(d): l.append(i)
 | 
				
			||||||
 | 
					    verify(l == l1)
 | 
				
			||||||
 | 
					    l = []
 | 
				
			||||||
 | 
					    for i in d.__iter__(): l.append(i)
 | 
				
			||||||
 | 
					    verify(l == l1)
 | 
				
			||||||
 | 
					    l = []
 | 
				
			||||||
 | 
					    for i in type(spamdict({})).__iter__(d): l.append(i)
 | 
				
			||||||
 | 
					    verify(l == l1)
 | 
				
			||||||
 | 
					    straightd = {1:2, 3:4}
 | 
				
			||||||
 | 
					    spamd = spamdict(straightd)
 | 
				
			||||||
 | 
					    testunop(spamd, 2, "len(a)", "__len__")
 | 
				
			||||||
 | 
					    testunop(spamd, repr(straightd), "repr(a)", "__repr__")
 | 
				
			||||||
 | 
					    testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}),
 | 
				
			||||||
 | 
					               "a[b]=c", "__setitem__")
 | 
				
			||||||
 | 
					    # Test subclassing
 | 
				
			||||||
 | 
					    class C(spam.spamdict):
 | 
				
			||||||
 | 
					        def foo(self): return 1
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    verify(a.items() == [])
 | 
				
			||||||
 | 
					    verify(a.foo() == 1)
 | 
				
			||||||
 | 
					    a['foo'] = 'bar'
 | 
				
			||||||
 | 
					    verify(a.items() == [('foo', 'bar')])
 | 
				
			||||||
 | 
					    verify(a.getstate() == 0)
 | 
				
			||||||
 | 
					    a.setstate(100)
 | 
				
			||||||
 | 
					    verify(a.getstate() == 100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def pydicts():
 | 
				
			||||||
 | 
					    if verbose: print "Testing Python subclass of dict..."
 | 
				
			||||||
 | 
					    verify(issubclass(dictionary, dictionary))
 | 
				
			||||||
 | 
					    verify(isinstance({}, dictionary))
 | 
				
			||||||
 | 
					    d = dictionary()
 | 
				
			||||||
 | 
					    verify(d == {})
 | 
				
			||||||
 | 
					    verify(d.__class__ is dictionary)
 | 
				
			||||||
 | 
					    verify(isinstance(d, dictionary))
 | 
				
			||||||
 | 
					    class C(dictionary):
 | 
				
			||||||
 | 
					        state = -1
 | 
				
			||||||
 | 
					        def __init__(self, *a, **kw):
 | 
				
			||||||
 | 
					            if a:
 | 
				
			||||||
 | 
					                assert len(a) == 1
 | 
				
			||||||
 | 
					                self.state = a[0]
 | 
				
			||||||
 | 
					            if kw:
 | 
				
			||||||
 | 
					                for k, v in kw.items(): self[v] = k
 | 
				
			||||||
 | 
					        def __getitem__(self, key):
 | 
				
			||||||
 | 
					            return self.get(key, 0)
 | 
				
			||||||
 | 
					        def __setitem__(self, key, value):
 | 
				
			||||||
 | 
					            assert isinstance(key, type(0))
 | 
				
			||||||
 | 
					            dictionary.__setitem__(self, key, value)
 | 
				
			||||||
 | 
					        def setstate(self, state):
 | 
				
			||||||
 | 
					            self.state = state
 | 
				
			||||||
 | 
					        def getstate(self):
 | 
				
			||||||
 | 
					            return self.state
 | 
				
			||||||
 | 
					    verify(issubclass(C, dictionary))
 | 
				
			||||||
 | 
					    a1 = C(12)
 | 
				
			||||||
 | 
					    verify(a1.state == 12)
 | 
				
			||||||
 | 
					    a2 = C(foo=1, bar=2)
 | 
				
			||||||
 | 
					    verify(a2[1] == 'foo' and a2[2] == 'bar')
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    verify(a.state == -1)
 | 
				
			||||||
 | 
					    verify(a.getstate() == -1)
 | 
				
			||||||
 | 
					    a.setstate(0)
 | 
				
			||||||
 | 
					    verify(a.state == 0)
 | 
				
			||||||
 | 
					    verify(a.getstate() == 0)
 | 
				
			||||||
 | 
					    a.setstate(10)
 | 
				
			||||||
 | 
					    verify(a.state == 10)
 | 
				
			||||||
 | 
					    verify(a.getstate() == 10)
 | 
				
			||||||
 | 
					    verify(a[42] == 0)
 | 
				
			||||||
 | 
					    a[42] = 24
 | 
				
			||||||
 | 
					    verify(a[42] == 24)
 | 
				
			||||||
 | 
					    if verbose: print "pydict stress test ..."
 | 
				
			||||||
 | 
					    N = 50
 | 
				
			||||||
 | 
					    for i in range(N):
 | 
				
			||||||
 | 
					        a[i] = C()
 | 
				
			||||||
 | 
					        for j in range(N):
 | 
				
			||||||
 | 
					            a[i][j] = i*j
 | 
				
			||||||
 | 
					    for i in range(N):
 | 
				
			||||||
 | 
					        for j in range(N):
 | 
				
			||||||
 | 
					            verify(a[i][j] == i*j)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def pylists():
 | 
				
			||||||
 | 
					    if verbose: print "Testing Python subclass of list..."
 | 
				
			||||||
 | 
					    class C(list):
 | 
				
			||||||
 | 
					        def __getitem__(self, i):
 | 
				
			||||||
 | 
					            return list.__getitem__(self, i) + 100
 | 
				
			||||||
 | 
					        def __getslice__(self, i, j):
 | 
				
			||||||
 | 
					            return (i, j)
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    a.extend([0,1,2])
 | 
				
			||||||
 | 
					    verify(a[0] == 100)
 | 
				
			||||||
 | 
					    verify(a[1] == 101)
 | 
				
			||||||
 | 
					    verify(a[2] == 102)
 | 
				
			||||||
 | 
					    verify(a[100:200] == (100,200))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def metaclass():
 | 
				
			||||||
 | 
					    if verbose: print "Testing __metaclass__..."
 | 
				
			||||||
 | 
					    global C
 | 
				
			||||||
 | 
					    class C:
 | 
				
			||||||
 | 
					        __metaclass__ = type
 | 
				
			||||||
 | 
					        def __init__(self):
 | 
				
			||||||
 | 
					            self.__state = 0
 | 
				
			||||||
 | 
					        def getstate(self):
 | 
				
			||||||
 | 
					            return self.__state
 | 
				
			||||||
 | 
					        def setstate(self, state):
 | 
				
			||||||
 | 
					            self.__state = state
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    verify(a.getstate() == 0)
 | 
				
			||||||
 | 
					    a.setstate(10)
 | 
				
			||||||
 | 
					    verify(a.getstate() == 10)
 | 
				
			||||||
 | 
					    class D:
 | 
				
			||||||
 | 
					        class __metaclass__(type):
 | 
				
			||||||
 | 
					            def myself(cls): return cls
 | 
				
			||||||
 | 
					    verify(D.myself() == D)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					MT = type(sys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def pymods():
 | 
				
			||||||
 | 
					    if verbose: print "Testing Python subclass of module..."
 | 
				
			||||||
 | 
					    global log
 | 
				
			||||||
 | 
					    log = []
 | 
				
			||||||
 | 
					    class MM(MT):
 | 
				
			||||||
 | 
					        def __init__(self):
 | 
				
			||||||
 | 
					            MT.__init__(self)
 | 
				
			||||||
 | 
					        def __getattr__(self, name):
 | 
				
			||||||
 | 
					            log.append(("getattr", name))
 | 
				
			||||||
 | 
					            return MT.__getattr__(self, name)
 | 
				
			||||||
 | 
					        def __setattr__(self, name, value):
 | 
				
			||||||
 | 
					            log.append(("setattr", name, value))
 | 
				
			||||||
 | 
					            MT.__setattr__(self, name, value)
 | 
				
			||||||
 | 
					        def __delattr__(self, name):
 | 
				
			||||||
 | 
					            log.append(("delattr", name))
 | 
				
			||||||
 | 
					            MT.__delattr__(self, name)
 | 
				
			||||||
 | 
					    a = MM()
 | 
				
			||||||
 | 
					    a.foo = 12
 | 
				
			||||||
 | 
					    x = a.foo
 | 
				
			||||||
 | 
					    del a.foo
 | 
				
			||||||
 | 
					    verify(log == [('getattr', '__init__'),
 | 
				
			||||||
 | 
					                   ('getattr', '__setattr__'),
 | 
				
			||||||
 | 
					                   ("setattr", "foo", 12),
 | 
				
			||||||
 | 
					                   ("getattr", "foo"),
 | 
				
			||||||
 | 
					                   ('getattr', '__delattr__'),
 | 
				
			||||||
 | 
					                   ("delattr", "foo")], log)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def multi():
 | 
				
			||||||
 | 
					    if verbose: print "Testing multiple inheritance..."
 | 
				
			||||||
 | 
					    global C
 | 
				
			||||||
 | 
					    class C(object):
 | 
				
			||||||
 | 
					        def __init__(self):
 | 
				
			||||||
 | 
					            self.__state = 0
 | 
				
			||||||
 | 
					        def getstate(self):
 | 
				
			||||||
 | 
					            return self.__state
 | 
				
			||||||
 | 
					        def setstate(self, state):
 | 
				
			||||||
 | 
					            self.__state = state
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    verify(a.getstate() == 0)
 | 
				
			||||||
 | 
					    a.setstate(10)
 | 
				
			||||||
 | 
					    verify(a.getstate() == 10)
 | 
				
			||||||
 | 
					    class D(dictionary, C):
 | 
				
			||||||
 | 
					        def __init__(self):
 | 
				
			||||||
 | 
					            type({}).__init__(self)
 | 
				
			||||||
 | 
					            C.__init__(self)
 | 
				
			||||||
 | 
					    d = D()
 | 
				
			||||||
 | 
					    verify(d.keys() == [])
 | 
				
			||||||
 | 
					    d["hello"] = "world"
 | 
				
			||||||
 | 
					    verify(d.items() == [("hello", "world")])
 | 
				
			||||||
 | 
					    verify(d["hello"] == "world")
 | 
				
			||||||
 | 
					    verify(d.getstate() == 0)
 | 
				
			||||||
 | 
					    d.setstate(10)
 | 
				
			||||||
 | 
					    verify(d.getstate() == 10)
 | 
				
			||||||
 | 
					    verify(D.__mro__ == (D, dictionary, C, object))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def diamond():
 | 
				
			||||||
 | 
					    if verbose: print "Testing multiple inheritance special cases..."
 | 
				
			||||||
 | 
					    class A(object):
 | 
				
			||||||
 | 
					        def spam(self): return "A"
 | 
				
			||||||
 | 
					    verify(A().spam() == "A")
 | 
				
			||||||
 | 
					    class B(A):
 | 
				
			||||||
 | 
					        def boo(self): return "B"
 | 
				
			||||||
 | 
					        def spam(self): return "B"
 | 
				
			||||||
 | 
					    verify(B().spam() == "B")
 | 
				
			||||||
 | 
					    verify(B().boo() == "B")
 | 
				
			||||||
 | 
					    class C(A):
 | 
				
			||||||
 | 
					        def boo(self): return "C"
 | 
				
			||||||
 | 
					    verify(C().spam() == "A")
 | 
				
			||||||
 | 
					    verify(C().boo() == "C")
 | 
				
			||||||
 | 
					    class D(B, C): pass
 | 
				
			||||||
 | 
					    verify(D().spam() == "B")
 | 
				
			||||||
 | 
					    verify(D().boo() == "B")
 | 
				
			||||||
 | 
					    verify(D.__mro__ == (D, B, C, A, object))
 | 
				
			||||||
 | 
					    class E(C, B): pass
 | 
				
			||||||
 | 
					    verify(E().spam() == "B")
 | 
				
			||||||
 | 
					    verify(E().boo() == "C")
 | 
				
			||||||
 | 
					    verify(E.__mro__ == (E, C, B, A, object))
 | 
				
			||||||
 | 
					    class F(D, E): pass
 | 
				
			||||||
 | 
					    verify(F().spam() == "B")
 | 
				
			||||||
 | 
					    verify(F().boo() == "B")
 | 
				
			||||||
 | 
					    verify(F.__mro__ == (F, D, E, B, C, A, object))
 | 
				
			||||||
 | 
					    class G(E, D): pass
 | 
				
			||||||
 | 
					    verify(G().spam() == "B")
 | 
				
			||||||
 | 
					    verify(G().boo() == "C")
 | 
				
			||||||
 | 
					    verify(G.__mro__ == (G, E, D, C, B, A, object))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def objects():
 | 
				
			||||||
 | 
					    if verbose: print "Testing object class..."
 | 
				
			||||||
 | 
					    a = object()
 | 
				
			||||||
 | 
					    verify(a.__class__ == object == type(a))
 | 
				
			||||||
 | 
					    b = object()
 | 
				
			||||||
 | 
					    verify(a is not b)
 | 
				
			||||||
 | 
					    verify(not hasattr(a, "foo"))
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        a.foo = 12
 | 
				
			||||||
 | 
					    except TypeError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "object() should not allow setting a foo attribute")
 | 
				
			||||||
 | 
					    verify(not hasattr(object(), "__dict__"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Cdict(object):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    x = Cdict()
 | 
				
			||||||
 | 
					    verify(x.__dict__ is None)
 | 
				
			||||||
 | 
					    x.foo = 1
 | 
				
			||||||
 | 
					    verify(x.foo == 1)
 | 
				
			||||||
 | 
					    verify(x.__dict__ == {'foo': 1})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def slots():
 | 
				
			||||||
 | 
					    if verbose: print "Testing __slots__..."
 | 
				
			||||||
 | 
					    class C0(object):
 | 
				
			||||||
 | 
					        __slots__ = []
 | 
				
			||||||
 | 
					    x = C0()
 | 
				
			||||||
 | 
					    verify(not hasattr(x, "__dict__"))
 | 
				
			||||||
 | 
					    verify(not hasattr(x, "foo"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class C1(object):
 | 
				
			||||||
 | 
					        __slots__ = ['a']
 | 
				
			||||||
 | 
					    x = C1()
 | 
				
			||||||
 | 
					    verify(not hasattr(x, "__dict__"))
 | 
				
			||||||
 | 
					    verify(x.a == None)
 | 
				
			||||||
 | 
					    x.a = 1
 | 
				
			||||||
 | 
					    verify(x.a == 1)
 | 
				
			||||||
 | 
					    del x.a
 | 
				
			||||||
 | 
					    verify(x.a == None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class C3(object):
 | 
				
			||||||
 | 
					        __slots__ = ['a', 'b', 'c']
 | 
				
			||||||
 | 
					    x = C3()
 | 
				
			||||||
 | 
					    verify(not hasattr(x, "__dict__"))
 | 
				
			||||||
 | 
					    verify(x.a is None)
 | 
				
			||||||
 | 
					    verify(x.b is None)
 | 
				
			||||||
 | 
					    verify(x.c is None)
 | 
				
			||||||
 | 
					    x.a = 1
 | 
				
			||||||
 | 
					    x.b = 2
 | 
				
			||||||
 | 
					    x.c = 3
 | 
				
			||||||
 | 
					    verify(x.a == 1)
 | 
				
			||||||
 | 
					    verify(x.b == 2)
 | 
				
			||||||
 | 
					    verify(x.c == 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def dynamics():
 | 
				
			||||||
 | 
					    if verbose: print "Testing __dynamic__..."
 | 
				
			||||||
 | 
					    verify(object.__dynamic__ == 0)
 | 
				
			||||||
 | 
					    verify(list.__dynamic__ == 0)
 | 
				
			||||||
 | 
					    class S1:
 | 
				
			||||||
 | 
					        __metaclass__ = type
 | 
				
			||||||
 | 
					    verify(S1.__dynamic__ == 0)
 | 
				
			||||||
 | 
					    class S(object):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    verify(C.__dynamic__ == 0)
 | 
				
			||||||
 | 
					    class D(object):
 | 
				
			||||||
 | 
					        __dynamic__ = 1
 | 
				
			||||||
 | 
					    verify(D.__dynamic__ == 1)
 | 
				
			||||||
 | 
					    class E(D, S):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    verify(E.__dynamic__ == 1)
 | 
				
			||||||
 | 
					    class F(S, D):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    verify(F.__dynamic__ == 1)
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        S.foo = 1
 | 
				
			||||||
 | 
					    except (AttributeError, TypeError):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "assignment to a static class attribute should be illegal")
 | 
				
			||||||
 | 
					    D.foo = 1
 | 
				
			||||||
 | 
					    verify(D.foo == 1)
 | 
				
			||||||
 | 
					    # Test that dynamic attributes are inherited
 | 
				
			||||||
 | 
					    verify(E.foo == 1)
 | 
				
			||||||
 | 
					    verify(F.foo == 1)
 | 
				
			||||||
 | 
					    class SS(D):
 | 
				
			||||||
 | 
					        __dynamic__ = 0
 | 
				
			||||||
 | 
					    verify(SS.__dynamic__ == 0)
 | 
				
			||||||
 | 
					    verify(SS.foo == 1)
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        SS.foo = 1
 | 
				
			||||||
 | 
					    except (AttributeError, TypeError):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "assignment to SS.foo should be illegal")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def errors():
 | 
				
			||||||
 | 
					    if verbose: print "Testing errors..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        class C(list, dictionary):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					    except TypeError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "inheritance from both list and dict should be illegal")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        class C(object, None):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					    except TypeError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "inheritance from non-type should be illegal")
 | 
				
			||||||
 | 
					    class Classic:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        class C(object, Classic):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					    except TypeError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "inheritance from object and Classic should be illegal")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        class C(int):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					    except TypeError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "inheritance from int should be illegal")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        class C(object):
 | 
				
			||||||
 | 
					            __slots__ = 1
 | 
				
			||||||
 | 
					    except TypeError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "__slots__ = 1 should be illegal")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        class C(object):
 | 
				
			||||||
 | 
					            __slots__ = [1]
 | 
				
			||||||
 | 
					    except TypeError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        verify(0, "__slots__ = [1] should be illegal")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def classmethods():
 | 
				
			||||||
 | 
					    if verbose: print "Testing class methods..."
 | 
				
			||||||
 | 
					    class C(object):
 | 
				
			||||||
 | 
					        def foo(*a): return a
 | 
				
			||||||
 | 
					        goo = classmethod(foo)
 | 
				
			||||||
 | 
					    c = C()
 | 
				
			||||||
 | 
					    verify(C.goo(1) == (C, 1))
 | 
				
			||||||
 | 
					    verify(c.goo(1) == (C, 1))
 | 
				
			||||||
 | 
					    verify(c.foo(1) == (c, 1))
 | 
				
			||||||
 | 
					    class D(C):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    d = D()
 | 
				
			||||||
 | 
					    verify(D.goo(1) == (D, 1))
 | 
				
			||||||
 | 
					    verify(d.goo(1) == (D, 1))
 | 
				
			||||||
 | 
					    verify(d.foo(1) == (d, 1))
 | 
				
			||||||
 | 
					    verify(D.foo(d, 1) == (d, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def staticmethods():
 | 
				
			||||||
 | 
					    if verbose: print "Testing static methods..."
 | 
				
			||||||
 | 
					    class C(object):
 | 
				
			||||||
 | 
					        def foo(*a): return a
 | 
				
			||||||
 | 
					        goo = staticmethod(foo)
 | 
				
			||||||
 | 
					    c = C()
 | 
				
			||||||
 | 
					    verify(C.goo(1) == (1,))
 | 
				
			||||||
 | 
					    verify(c.goo(1) == (1,))
 | 
				
			||||||
 | 
					    verify(c.foo(1) == (c, 1,))
 | 
				
			||||||
 | 
					    class D(C):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    d = D()
 | 
				
			||||||
 | 
					    verify(D.goo(1) == (1,))
 | 
				
			||||||
 | 
					    verify(d.goo(1) == (1,))
 | 
				
			||||||
 | 
					    verify(d.foo(1) == (d, 1))
 | 
				
			||||||
 | 
					    verify(D.foo(d, 1) == (d, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def classic():
 | 
				
			||||||
 | 
					    if verbose: print "Testing classic classes..."
 | 
				
			||||||
 | 
					    class C:
 | 
				
			||||||
 | 
					        def foo(*a): return a
 | 
				
			||||||
 | 
					        goo = classmethod(foo)
 | 
				
			||||||
 | 
					    c = C()
 | 
				
			||||||
 | 
					    verify(C.goo(1) == (C, 1))
 | 
				
			||||||
 | 
					    verify(c.goo(1) == (C, 1))
 | 
				
			||||||
 | 
					    verify(c.foo(1) == (c, 1))
 | 
				
			||||||
 | 
					    class D(C):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    d = D()
 | 
				
			||||||
 | 
					    verify(D.goo(1) == (D, 1))
 | 
				
			||||||
 | 
					    verify(d.goo(1) == (D, 1))
 | 
				
			||||||
 | 
					    verify(d.foo(1) == (d, 1))
 | 
				
			||||||
 | 
					    verify(D.foo(d, 1) == (d, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def compattr():
 | 
				
			||||||
 | 
					    if verbose: print "Testing computed attributes..."
 | 
				
			||||||
 | 
					    class C(object):
 | 
				
			||||||
 | 
					        class computed_attribute(object):
 | 
				
			||||||
 | 
					            def __init__(self, get, set=None):
 | 
				
			||||||
 | 
					                self.__get = get
 | 
				
			||||||
 | 
					                self.__set = set
 | 
				
			||||||
 | 
					            def __get__(self, obj, type=None):
 | 
				
			||||||
 | 
					                return self.__get(obj)
 | 
				
			||||||
 | 
					            def __set__(self, obj, value):
 | 
				
			||||||
 | 
					                return self.__set(obj, value)
 | 
				
			||||||
 | 
					        def __init__(self):
 | 
				
			||||||
 | 
					            self.__x = 0
 | 
				
			||||||
 | 
					        def __get_x(self):
 | 
				
			||||||
 | 
					            x = self.__x
 | 
				
			||||||
 | 
					            self.__x = x+1
 | 
				
			||||||
 | 
					            return x
 | 
				
			||||||
 | 
					        def __set_x(self, x):
 | 
				
			||||||
 | 
					            self.__x = x
 | 
				
			||||||
 | 
					        x = computed_attribute(__get_x, __set_x)
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    verify(a.x == 0)
 | 
				
			||||||
 | 
					    verify(a.x == 1)
 | 
				
			||||||
 | 
					    a.x = 10
 | 
				
			||||||
 | 
					    verify(a.x == 10)
 | 
				
			||||||
 | 
					    verify(a.x == 11)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def newslot():
 | 
				
			||||||
 | 
					    if verbose: print "Testing __new__ slot override..."
 | 
				
			||||||
 | 
					    class C(list):
 | 
				
			||||||
 | 
					        def __new__(cls):
 | 
				
			||||||
 | 
					            self = list.__new__(cls)
 | 
				
			||||||
 | 
					            self.foo = 1
 | 
				
			||||||
 | 
					            return self
 | 
				
			||||||
 | 
					        def __init__(self):
 | 
				
			||||||
 | 
					            self.foo = self.foo + 2
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    verify(a.foo == 3)
 | 
				
			||||||
 | 
					    verify(a.__class__ is C)
 | 
				
			||||||
 | 
					    class D(C):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    b = D()
 | 
				
			||||||
 | 
					    verify(b.foo == 3)
 | 
				
			||||||
 | 
					    verify(b.__class__ is D)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PerverseMetaType(type):
 | 
				
			||||||
 | 
					    def mro(cls):
 | 
				
			||||||
 | 
					        L = type.mro(cls)
 | 
				
			||||||
 | 
					        L.reverse()
 | 
				
			||||||
 | 
					        return L
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def altmro():
 | 
				
			||||||
 | 
					    if verbose: print "Testing mro() and overriding it..."
 | 
				
			||||||
 | 
					    class A(object):
 | 
				
			||||||
 | 
					        def f(self): return "A"
 | 
				
			||||||
 | 
					    class B(A):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    class C(A):
 | 
				
			||||||
 | 
					        def f(self): return "C"
 | 
				
			||||||
 | 
					    class D(B, C):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    verify(D.mro() == [D, B, C, A, object] == list(D.__mro__))
 | 
				
			||||||
 | 
					    verify(D().f() == "C")
 | 
				
			||||||
 | 
					    class X(A,B,C,D):
 | 
				
			||||||
 | 
					        __metaclass__ = PerverseMetaType
 | 
				
			||||||
 | 
					    verify(X.__mro__ == (object, A, C, B, D, X))
 | 
				
			||||||
 | 
					    verify(X().f() == "A")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def overloading():
 | 
				
			||||||
 | 
					    if verbose: print "testing operator overloading..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class B(object):
 | 
				
			||||||
 | 
					        "Intermediate class because object doesn't have a __setattr__"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class C(B):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def __getattr__(self, name):
 | 
				
			||||||
 | 
					            if name == "foo":
 | 
				
			||||||
 | 
					                return ("getattr", name)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                return B.__getattr__(self, name)
 | 
				
			||||||
 | 
					        def __setattr__(self, name, value):
 | 
				
			||||||
 | 
					            if name == "foo":
 | 
				
			||||||
 | 
					                self.setattr = (name, value)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                return B.__setattr__(self, name, value)
 | 
				
			||||||
 | 
					        def __delattr__(self, name):
 | 
				
			||||||
 | 
					            if name == "foo":
 | 
				
			||||||
 | 
					                self.delattr = name
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                return B.__delattr__(self, name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def __getitem__(self, key):
 | 
				
			||||||
 | 
					            return ("getitem", key)
 | 
				
			||||||
 | 
					        def __setitem__(self, key, value):
 | 
				
			||||||
 | 
					            self.setitem = (key, value)
 | 
				
			||||||
 | 
					        def __delitem__(self, key):
 | 
				
			||||||
 | 
					            self.delitem = key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def __getslice__(self, i, j):
 | 
				
			||||||
 | 
					            return ("getslice", i, j)
 | 
				
			||||||
 | 
					        def __setslice__(self, i, j, value):
 | 
				
			||||||
 | 
					            self.setslice = (i, j, value)
 | 
				
			||||||
 | 
					        def __delslice__(self, i, j):
 | 
				
			||||||
 | 
					            self.delslice = (i, j)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a = C()
 | 
				
			||||||
 | 
					    verify(a.foo == ("getattr", "foo"))
 | 
				
			||||||
 | 
					    a.foo = 12
 | 
				
			||||||
 | 
					    verify(a.setattr == ("foo", 12))
 | 
				
			||||||
 | 
					    del a.foo
 | 
				
			||||||
 | 
					    verify(a.delattr == "foo")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    verify(a[12] == ("getitem", 12))
 | 
				
			||||||
 | 
					    a[12] = 21
 | 
				
			||||||
 | 
					    verify(a.setitem == (12, 21))
 | 
				
			||||||
 | 
					    del a[12]
 | 
				
			||||||
 | 
					    verify(a.delitem == 12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    verify(a[0:10] == ("getslice", 0, 10))
 | 
				
			||||||
 | 
					    a[0:10] = "foo"
 | 
				
			||||||
 | 
					    verify(a.setslice == (0, 10, "foo"))
 | 
				
			||||||
 | 
					    del a[0:10]
 | 
				
			||||||
 | 
					    verify(a.delslice == (0, 10))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def all():
 | 
				
			||||||
 | 
					    lists()
 | 
				
			||||||
 | 
					    dicts()
 | 
				
			||||||
 | 
					    ints()
 | 
				
			||||||
 | 
					    longs()
 | 
				
			||||||
 | 
					    floats()
 | 
				
			||||||
 | 
					    complexes()
 | 
				
			||||||
 | 
					    spamlists()
 | 
				
			||||||
 | 
					    spamdicts()
 | 
				
			||||||
 | 
					    pydicts()
 | 
				
			||||||
 | 
					    pylists()
 | 
				
			||||||
 | 
					    metaclass()
 | 
				
			||||||
 | 
					    pymods()
 | 
				
			||||||
 | 
					    multi()
 | 
				
			||||||
 | 
					    diamond()
 | 
				
			||||||
 | 
					    objects()
 | 
				
			||||||
 | 
					    slots()
 | 
				
			||||||
 | 
					    dynamics()
 | 
				
			||||||
 | 
					    errors()
 | 
				
			||||||
 | 
					    classmethods()
 | 
				
			||||||
 | 
					    staticmethods()
 | 
				
			||||||
 | 
					    classic()
 | 
				
			||||||
 | 
					    compattr()
 | 
				
			||||||
 | 
					    newslot()
 | 
				
			||||||
 | 
					    altmro()
 | 
				
			||||||
 | 
					    overloading()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if verbose: print "All OK"
 | 
				
			||||||
| 
						 | 
					@ -380,10 +380,16 @@
 | 
				
			||||||
>>> i = g()
 | 
					>>> i = g()
 | 
				
			||||||
>>> type(i)
 | 
					>>> type(i)
 | 
				
			||||||
<type 'generator'>
 | 
					<type 'generator'>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					XXX dir(object) *generally* doesn't return useful stuff in descr-branch.
 | 
				
			||||||
>>> dir(i)
 | 
					>>> dir(i)
 | 
				
			||||||
 | 
					[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Was hoping to see this instead:
 | 
				
			||||||
['gi_frame', 'gi_running', 'next']
 | 
					['gi_frame', 'gi_running', 'next']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
>>> print i.next.__doc__
 | 
					>>> print i.next.__doc__
 | 
				
			||||||
next() -- get the next value, or raise StopIteration
 | 
					x.next() -> the next value, or raise StopIteration
 | 
				
			||||||
>>> iter(i) is i
 | 
					>>> iter(i) is i
 | 
				
			||||||
1
 | 
					1
 | 
				
			||||||
>>> import types
 | 
					>>> import types
 | 
				
			||||||
| 
						 | 
					@ -399,7 +405,7 @@
 | 
				
			||||||
>>> i.gi_running = 42
 | 
					>>> i.gi_running = 42
 | 
				
			||||||
Traceback (most recent call last):
 | 
					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():
 | 
					>>> def g():
 | 
				
			||||||
...     yield me.gi_running
 | 
					...     yield me.gi_running
 | 
				
			||||||
>>> me = g()
 | 
					>>> me = g()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								Lib/types.py
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								Lib/types.py
									
										
									
									
									
								
							| 
						 | 
					@ -7,7 +7,8 @@
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NoneType = type(None)
 | 
					NoneType = type(None)
 | 
				
			||||||
TypeType = type(NoneType)
 | 
					TypeType = type
 | 
				
			||||||
 | 
					ObjectType = object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IntType = type(0)
 | 
					IntType = type(0)
 | 
				
			||||||
LongType = type(0L)
 | 
					LongType = type(0L)
 | 
				
			||||||
| 
						 | 
					@ -22,8 +23,8 @@
 | 
				
			||||||
BufferType = type(buffer(''))
 | 
					BufferType = type(buffer(''))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TupleType = type(())
 | 
					TupleType = type(())
 | 
				
			||||||
ListType = type([])
 | 
					ListType = list
 | 
				
			||||||
DictType = DictionaryType = type({})
 | 
					DictType = DictionaryType = dictionary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _f(): pass
 | 
					def _f(): pass
 | 
				
			||||||
FunctionType = type(_f)
 | 
					FunctionType = type(_f)
 | 
				
			||||||
| 
						 | 
					@ -71,4 +72,9 @@ def _m(self): pass
 | 
				
			||||||
SliceType = type(slice(0))
 | 
					SliceType = type(slice(0))
 | 
				
			||||||
EllipsisType = type(Ellipsis)
 | 
					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
 | 
					del sys, _f, _C, _x                     # Not for export
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -237,6 +237,7 @@ OBJECT_OBJS=	\
 | 
				
			||||||
		Objects/classobject.o \
 | 
							Objects/classobject.o \
 | 
				
			||||||
		Objects/cobject.o \
 | 
							Objects/cobject.o \
 | 
				
			||||||
		Objects/complexobject.o \
 | 
							Objects/complexobject.o \
 | 
				
			||||||
 | 
							Objects/descrobject.o \
 | 
				
			||||||
		Objects/fileobject.o \
 | 
							Objects/fileobject.o \
 | 
				
			||||||
		Objects/floatobject.o \
 | 
							Objects/floatobject.o \
 | 
				
			||||||
		Objects/frameobject.o \
 | 
							Objects/frameobject.o \
 | 
				
			||||||
| 
						 | 
					@ -438,6 +439,7 @@ PYTHON_HEADERS= \
 | 
				
			||||||
		Include/tupleobject.h \
 | 
							Include/tupleobject.h \
 | 
				
			||||||
		Include/listobject.h \
 | 
							Include/listobject.h \
 | 
				
			||||||
		Include/iterobject.h \
 | 
							Include/iterobject.h \
 | 
				
			||||||
 | 
							Include/descrobject.h \
 | 
				
			||||||
		Include/dictobject.h \
 | 
							Include/dictobject.h \
 | 
				
			||||||
		Include/methodobject.h \
 | 
							Include/methodobject.h \
 | 
				
			||||||
		Include/moduleobject.h \
 | 
							Include/moduleobject.h \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								Misc/NEWS
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								Misc/NEWS
									
										
									
									
									
								
							| 
						 | 
					@ -44,6 +44,17 @@ What's New in Python 2.2a1?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Core
 | 
					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
 | 
					- Generators were added; this is a new way to create an iterator (see
 | 
				
			||||||
  below) using what looks like a simple function containing one or
 | 
					  below) using what looks like a simple function containing one or
 | 
				
			||||||
  more 'yield' statements.  See PEP 255.  Since this adds a new
 | 
					  more 'yield' statements.  See PEP 255.  Since this adds a new
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -464,3 +464,5 @@ GLHACK=-Dclear=__GLclear
 | 
				
			||||||
# Example -- included for reference only:
 | 
					# Example -- included for reference only:
 | 
				
			||||||
# xx xxmodule.c
 | 
					# 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);
 | 
					                res = save_tuple(self, args);
 | 
				
			||||||
                goto finally;
 | 
					                goto finally;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
						    if (type == &PyType_Type) {
 | 
				
			||||||
 | 
							res = save_global(self, args, NULL);
 | 
				
			||||||
 | 
							goto finally;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case 'l':
 | 
					        case 'l':
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,7 @@ struct _inittab _PyImport_Inittab[] = {
 | 
				
			||||||
	{"__main__", NULL},
 | 
						{"__main__", NULL},
 | 
				
			||||||
	{"__builtin__", NULL},
 | 
						{"__builtin__", NULL},
 | 
				
			||||||
	{"sys", NULL},
 | 
						{"sys", NULL},
 | 
				
			||||||
	{"exceptions", init_exceptions},
 | 
						{"exceptions", NULL},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Sentinel */
 | 
						/* Sentinel */
 | 
				
			||||||
	{0, 0}
 | 
						{0, 0}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										233
									
								
								Modules/xxsubtype.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								Modules/xxsubtype.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,233 @@
 | 
				
			||||||
 | 
					#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;
 | 
						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 *
 | 
				
			||||||
PyObject_CallFunction(PyObject *callable, char *format, ...)
 | 
					PyObject_CallFunction(PyObject *callable, char *format, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1746,7 +1764,7 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (PyType_Check(cls)) {
 | 
						else if (PyType_Check(cls)) {
 | 
				
			||||||
		retval = ((PyObject *)(inst->ob_type) == cls);
 | 
							retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (!PyInstance_Check(inst)) {
 | 
						else if (!PyInstance_Check(inst)) {
 | 
				
			||||||
		if (__class__ == NULL) {
 | 
							if (__class__ == NULL) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -549,7 +549,7 @@ PyTypeObject PyBuffer_Type = {
 | 
				
			||||||
	(hashfunc)buffer_hash,			/* tp_hash */
 | 
						(hashfunc)buffer_hash,			/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	(reprfunc)buffer_str,			/* tp_str */
 | 
						(reprfunc)buffer_str,			/* tp_str */
 | 
				
			||||||
	0,		/*tp_getattro*/
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	&buffer_as_buffer,			/* tp_as_buffer */
 | 
						&buffer_as_buffer,			/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,7 +106,7 @@ PyTypeObject PyCell_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,12 +36,12 @@ PyClass_New(PyObject *bases, PyObject *dict, PyObject *name)
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (name == NULL || !PyString_Check(name)) {
 | 
						if (name == NULL || !PyString_Check(name)) {
 | 
				
			||||||
		PyErr_SetString(PyExc_SystemError,
 | 
							PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
				"PyClass_New: name must be a string");
 | 
									"PyClass_New: name must be a string");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (dict == NULL || !PyDict_Check(dict)) {
 | 
						if (dict == NULL || !PyDict_Check(dict)) {
 | 
				
			||||||
		PyErr_SetString(PyExc_SystemError,
 | 
							PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
				"PyClass_New: dict must be a dictionary");
 | 
									"PyClass_New: dict must be a dictionary");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -67,14 +67,14 @@ PyClass_New(PyObject *bases, PyObject *dict, PyObject *name)
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		int i;
 | 
							int i;
 | 
				
			||||||
		if (!PyTuple_Check(bases)) {
 | 
							if (!PyTuple_Check(bases)) {
 | 
				
			||||||
			PyErr_SetString(PyExc_SystemError,
 | 
								PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
					"PyClass_New: bases must be a tuple");
 | 
										"PyClass_New: bases must be a tuple");
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		i = PyTuple_Size(bases);
 | 
							i = PyTuple_Size(bases);
 | 
				
			||||||
		while (--i >= 0) {
 | 
							while (--i >= 0) {
 | 
				
			||||||
			if (!PyClass_Check(PyTuple_GetItem(bases, i))) {
 | 
								if (!PyClass_Check(PyTuple_GetItem(bases, i))) {
 | 
				
			||||||
				PyErr_SetString(PyExc_SystemError,
 | 
									PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
					"PyClass_New: base must be a class");
 | 
										"PyClass_New: base must be a class");
 | 
				
			||||||
				return NULL;
 | 
									return NULL;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -106,6 +106,18 @@ PyClass_New(PyObject *bases, PyObject *dict, PyObject *name)
 | 
				
			||||||
	return (PyObject *) op;
 | 
						return (PyObject *) op;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					class_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *name, *bases, *dict;
 | 
				
			||||||
 | 
						static char *kwlist[] = {"name", "bases", "dict", 0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist,
 | 
				
			||||||
 | 
										 &name, &bases, &dict))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						return PyClass_New(bases, dict, name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Class methods */
 | 
					/* Class methods */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -149,6 +161,8 @@ class_getattr(register PyClassObject *op, PyObject *name)
 | 
				
			||||||
	register PyObject *v;
 | 
						register PyObject *v;
 | 
				
			||||||
	register char *sname = PyString_AsString(name);
 | 
						register char *sname = PyString_AsString(name);
 | 
				
			||||||
	PyClassObject *class;
 | 
						PyClassObject *class;
 | 
				
			||||||
 | 
						descrgetfunc f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sname[0] == '_' && sname[1] == '_') {
 | 
						if (sname[0] == '_' && sname[1] == '_') {
 | 
				
			||||||
		if (strcmp(sname, "__dict__") == 0) {
 | 
							if (strcmp(sname, "__dict__") == 0) {
 | 
				
			||||||
			if (PyEval_GetRestricted()) {
 | 
								if (PyEval_GetRestricted()) {
 | 
				
			||||||
| 
						 | 
					@ -186,6 +200,11 @@ class_getattr(register PyClassObject *op, PyObject *name)
 | 
				
			||||||
		Py_DECREF(v);
 | 
							Py_DECREF(v);
 | 
				
			||||||
		v = w;
 | 
							v = w;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						f = v->ob_type->tp_descr_get;
 | 
				
			||||||
 | 
						if (f == NULL)
 | 
				
			||||||
 | 
							Py_INCREF(v);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							v = f(v, (PyObject *)NULL, (PyObject *)op);
 | 
				
			||||||
	return v;
 | 
						return v;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -396,7 +415,7 @@ PyTypeObject PyClass_Type = {
 | 
				
			||||||
	0,					/* tp_as_sequence */
 | 
						0,					/* tp_as_sequence */
 | 
				
			||||||
	0,					/* tp_as_mapping */
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						PyInstance_New,				/* tp_call */
 | 
				
			||||||
	(reprfunc)class_str,			/* tp_str */
 | 
						(reprfunc)class_str,			/* tp_str */
 | 
				
			||||||
	(getattrofunc)class_getattr,		/* tp_getattro */
 | 
						(getattrofunc)class_getattr,		/* tp_getattro */
 | 
				
			||||||
	(setattrofunc)class_setattr,		/* tp_setattro */
 | 
						(setattrofunc)class_setattr,		/* tp_setattro */
 | 
				
			||||||
| 
						 | 
					@ -404,6 +423,22 @@ PyTypeObject PyClass_Type = {
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
	0,					/* tp_doc */
 | 
						0,					/* tp_doc */
 | 
				
			||||||
	(traverseproc)class_traverse,		/* tp_traverse */
 | 
						(traverseproc)class_traverse,		/* 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 */
 | 
				
			||||||
 | 
						class_new,				/* tp_new */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
| 
						 | 
					@ -531,7 +566,7 @@ instance_dealloc(register PyInstanceObject *inst)
 | 
				
			||||||
	/* compensate for boost in _Py_NewReference; note that
 | 
						/* compensate for boost in _Py_NewReference; note that
 | 
				
			||||||
	 * _Py_RefTotal was also boosted; we'll knock that down later.
 | 
						 * _Py_RefTotal was also boosted; we'll knock that down later.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	inst->ob_type->tp_alloc--;
 | 
						inst->ob_type->tp_allocs--;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#else /* !Py_TRACE_REFS */
 | 
					#else /* !Py_TRACE_REFS */
 | 
				
			||||||
	/* Py_INCREF boosts _Py_RefTotal if Py_REF_DEBUG is defined */
 | 
						/* Py_INCREF boosts _Py_RefTotal if Py_REF_DEBUG is defined */
 | 
				
			||||||
| 
						 | 
					@ -564,7 +599,7 @@ instance_dealloc(register PyInstanceObject *inst)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	if (--inst->ob_refcnt > 0) {
 | 
						if (--inst->ob_refcnt > 0) {
 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
					#ifdef COUNT_ALLOCS
 | 
				
			||||||
		inst->ob_type->tp_free--;
 | 
							inst->ob_type->tp_frees--;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		return; /* __del__ added a reference; don't delete now */
 | 
							return; /* __del__ added a reference; don't delete now */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -572,7 +607,7 @@ instance_dealloc(register PyInstanceObject *inst)
 | 
				
			||||||
	_Py_ForgetReference((PyObject *)inst);
 | 
						_Py_ForgetReference((PyObject *)inst);
 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
					#ifdef COUNT_ALLOCS
 | 
				
			||||||
	/* compensate for increment in _Py_ForgetReference */
 | 
						/* compensate for increment in _Py_ForgetReference */
 | 
				
			||||||
	inst->ob_type->tp_free--;
 | 
						inst->ob_type->tp_frees--;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifndef WITH_CYCLE_GC
 | 
					#ifndef WITH_CYCLE_GC
 | 
				
			||||||
	inst->ob_type = NULL;
 | 
						inst->ob_type = NULL;
 | 
				
			||||||
| 
						 | 
					@ -619,6 +654,8 @@ instance_getattr2(register PyInstanceObject *inst, PyObject *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	register PyObject *v;
 | 
						register PyObject *v;
 | 
				
			||||||
	PyClassObject *class;
 | 
						PyClassObject *class;
 | 
				
			||||||
 | 
						descrgetfunc f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class = NULL;
 | 
						class = NULL;
 | 
				
			||||||
	v = PyDict_GetItem(inst->in_dict, name);
 | 
						v = PyDict_GetItem(inst->in_dict, name);
 | 
				
			||||||
	if (v == NULL) {
 | 
						if (v == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -628,17 +665,20 @@ instance_getattr2(register PyInstanceObject *inst, PyObject *name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	Py_INCREF(v);
 | 
						Py_INCREF(v);
 | 
				
			||||||
	if (class != NULL) {
 | 
						if (class != NULL) {
 | 
				
			||||||
		if (PyFunction_Check(v)) {
 | 
							f = v->ob_type->tp_descr_get;
 | 
				
			||||||
			PyObject *w = PyMethod_New(v, (PyObject *)inst,
 | 
							if (f != NULL) {
 | 
				
			||||||
						   (PyObject *)class);
 | 
								PyObject *w = f(v, (PyObject *)inst,
 | 
				
			||||||
 | 
										(PyObject *)(inst->in_class));
 | 
				
			||||||
			Py_DECREF(v);
 | 
								Py_DECREF(v);
 | 
				
			||||||
			v = w;
 | 
								v = w;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if (PyMethod_Check(v)) {
 | 
							else if (PyMethod_Check(v)) {
 | 
				
			||||||
			PyObject *im_class = PyMethod_Class(v);
 | 
								/* XXX This should be a tp_descr_get slot of
 | 
				
			||||||
 | 
								   PyMethodObjects */
 | 
				
			||||||
 | 
								PyObject *im_class = PyMethod_GET_CLASS(v);
 | 
				
			||||||
			/* Only if classes are compatible */
 | 
								/* Only if classes are compatible */
 | 
				
			||||||
			if (PyClass_IsSubclass((PyObject *)class, im_class)) {
 | 
								if (PyClass_IsSubclass((PyObject *)class, im_class)) {
 | 
				
			||||||
				PyObject *im_func = PyMethod_Function(v);
 | 
									PyObject *im_func = PyMethod_GET_FUNCTION(v);
 | 
				
			||||||
				PyObject *w = PyMethod_New(im_func,
 | 
									PyObject *w = PyMethod_New(im_func,
 | 
				
			||||||
						(PyObject *)inst, im_class);
 | 
											(PyObject *)inst, im_class);
 | 
				
			||||||
				Py_DECREF(v);
 | 
									Py_DECREF(v);
 | 
				
			||||||
| 
						 | 
					@ -1814,6 +1854,23 @@ instance_iternext(PyInstanceObject *self)
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					instance_call(PyObject *func, PyObject *arg, PyObject *kw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *res, *call = PyObject_GetAttrString(func, "__call__");
 | 
				
			||||||
 | 
						if (call == NULL) {
 | 
				
			||||||
 | 
							PyInstanceObject *inst = (PyInstanceObject*) func;
 | 
				
			||||||
 | 
							PyErr_Clear();
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_AttributeError,
 | 
				
			||||||
 | 
								     "%.200s instance has no __call__ method",
 | 
				
			||||||
 | 
								     PyString_AsString(inst->in_class->cl_name));
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res = PyObject_Call(call, arg, kw);
 | 
				
			||||||
 | 
						Py_DECREF(call);
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyNumberMethods instance_as_number = {
 | 
					static PyNumberMethods instance_as_number = {
 | 
				
			||||||
	(binaryfunc)instance_add,		/* nb_add */
 | 
						(binaryfunc)instance_add,		/* nb_add */
 | 
				
			||||||
| 
						 | 
					@ -1868,7 +1925,7 @@ PyTypeObject PyInstance_Type = {
 | 
				
			||||||
	&instance_as_sequence,			/* tp_as_sequence */
 | 
						&instance_as_sequence,			/* tp_as_sequence */
 | 
				
			||||||
	&instance_as_mapping,			/* tp_as_mapping */
 | 
						&instance_as_mapping,			/* tp_as_mapping */
 | 
				
			||||||
	(hashfunc)instance_hash,		/* tp_hash */
 | 
						(hashfunc)instance_hash,		/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						instance_call,				/* tp_call */
 | 
				
			||||||
	(reprfunc)instance_str,			/* tp_str */
 | 
						(reprfunc)instance_str,			/* tp_str */
 | 
				
			||||||
	(getattrofunc)instance_getattr,		/* tp_getattro */
 | 
						(getattrofunc)instance_getattr,		/* tp_getattro */
 | 
				
			||||||
	(setattrofunc)instance_setattr,		/* tp_setattro */
 | 
						(setattrofunc)instance_setattr,		/* tp_setattro */
 | 
				
			||||||
| 
						 | 
					@ -1921,36 +1978,6 @@ PyMethod_New(PyObject *func, PyObject *self, PyObject *class)
 | 
				
			||||||
	return (PyObject *)im;
 | 
						return (PyObject *)im;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyObject *
 | 
					 | 
				
			||||||
PyMethod_Function(register PyObject *im)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!PyMethod_Check(im)) {
 | 
					 | 
				
			||||||
		PyErr_BadInternalCall();
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ((PyMethodObject *)im)->im_func;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PyObject *
 | 
					 | 
				
			||||||
PyMethod_Self(register PyObject *im)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!PyMethod_Check(im)) {
 | 
					 | 
				
			||||||
		PyErr_BadInternalCall();
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ((PyMethodObject *)im)->im_self;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PyObject *
 | 
					 | 
				
			||||||
PyMethod_Class(register PyObject *im)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!PyMethod_Check(im)) {
 | 
					 | 
				
			||||||
		PyErr_BadInternalCall();
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ((PyMethodObject *)im)->im_class;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Class method methods */
 | 
					/* Class method methods */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OFF(x) offsetof(PyMethodObject, x)
 | 
					#define OFF(x) offsetof(PyMethodObject, x)
 | 
				
			||||||
| 
						 | 
					@ -2028,43 +2055,52 @@ instancemethod_compare(PyMethodObject *a, PyMethodObject *b)
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
instancemethod_repr(PyMethodObject *a)
 | 
					instancemethod_repr(PyMethodObject *a)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[240];
 | 
						char buffer[240];
 | 
				
			||||||
	PyInstanceObject *self = (PyInstanceObject *)(a->im_self);
 | 
						PyObject *self = a->im_self;
 | 
				
			||||||
	PyObject *func = a->im_func;
 | 
						PyObject *func = a->im_func;
 | 
				
			||||||
	PyClassObject *class = (PyClassObject *)(a->im_class);
 | 
						PyObject *klass = a->im_class;
 | 
				
			||||||
	PyObject *fclassname, *iclassname, *funcname;
 | 
						PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
 | 
				
			||||||
	char *fcname, *icname, *fname;
 | 
						char *sfuncname = "?", *sklassname = "?";
 | 
				
			||||||
	fclassname = class->cl_name;
 | 
					
 | 
				
			||||||
	if (PyFunction_Check(func)) {
 | 
					 | 
				
			||||||
		funcname = ((PyFunctionObject *)func)->func_name;
 | 
					 | 
				
			||||||
		Py_INCREF(funcname);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
	funcname = PyObject_GetAttrString(func, "__name__");
 | 
						funcname = PyObject_GetAttrString(func, "__name__");
 | 
				
			||||||
	if (funcname == NULL)
 | 
						if (funcname == NULL)
 | 
				
			||||||
		PyErr_Clear();
 | 
							PyErr_Clear();
 | 
				
			||||||
 | 
						else if (!PyString_Check(funcname)) {
 | 
				
			||||||
 | 
							Py_DECREF(funcname);
 | 
				
			||||||
 | 
							funcname = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (funcname != NULL && PyString_Check(funcname))
 | 
					 | 
				
			||||||
		fname = PyString_AS_STRING(funcname);
 | 
					 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		fname = "?";
 | 
							sfuncname = PyString_AS_STRING(funcname);
 | 
				
			||||||
	if (fclassname != NULL && PyString_Check(fclassname))
 | 
						klassname = PyObject_GetAttrString(klass, "__name__");
 | 
				
			||||||
		fcname = PyString_AsString(fclassname);
 | 
						if (klassname == NULL)
 | 
				
			||||||
 | 
							PyErr_Clear();
 | 
				
			||||||
 | 
						else if (!PyString_Check(klassname)) {
 | 
				
			||||||
 | 
							Py_DECREF(klassname);
 | 
				
			||||||
 | 
							klassname = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		fcname = "?";
 | 
							sklassname = PyString_AS_STRING(klassname);
 | 
				
			||||||
	if (self == NULL)
 | 
						if (self == NULL)
 | 
				
			||||||
		sprintf(buf, "<unbound method %.100s.%.100s>", fcname, fname);
 | 
							sprintf(buffer, "<unbound method %.100s.%.100s>",
 | 
				
			||||||
 | 
								sklassname, sfuncname);
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		iclassname = self->in_class->cl_name;
 | 
							/* XXX Shouldn't use repr() here! */
 | 
				
			||||||
		if (iclassname != NULL && PyString_Check(iclassname))
 | 
							PyObject *selfrepr = PyObject_Repr(self);
 | 
				
			||||||
			icname = PyString_AsString(iclassname);
 | 
							if (selfrepr == NULL)
 | 
				
			||||||
		else
 | 
								goto fail;
 | 
				
			||||||
			icname = "?";
 | 
							if (!PyString_Check(selfrepr)) {
 | 
				
			||||||
		sprintf(buf, "<method %.60s.%.60s of %.60s instance at %p>",
 | 
								Py_DECREF(selfrepr);
 | 
				
			||||||
			fcname, fname, icname, self);
 | 
								goto fail;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							sprintf(buffer, "<bound method %.60s.%.60s of %.60s>",
 | 
				
			||||||
 | 
								sklassname, sfuncname, PyString_AS_STRING(selfrepr));
 | 
				
			||||||
 | 
							Py_DECREF(selfrepr);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result = PyString_FromString(buffer);
 | 
				
			||||||
 | 
					  fail:
 | 
				
			||||||
	Py_XDECREF(funcname);
 | 
						Py_XDECREF(funcname);
 | 
				
			||||||
	return PyString_FromString(buf);
 | 
						Py_XDECREF(klassname);
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static long
 | 
					static long
 | 
				
			||||||
| 
						 | 
					@ -2105,6 +2141,57 @@ instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *self = PyMethod_GET_SELF(func);
 | 
				
			||||||
 | 
						PyObject *class = PyMethod_GET_CLASS(func);
 | 
				
			||||||
 | 
						PyObject *result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						func = PyMethod_GET_FUNCTION(func);
 | 
				
			||||||
 | 
						if (self == NULL) {
 | 
				
			||||||
 | 
							/* Unbound methods must be called with an instance of
 | 
				
			||||||
 | 
							   the class (or a derived class) as first argument */
 | 
				
			||||||
 | 
							int ok;
 | 
				
			||||||
 | 
							if (PyTuple_Size(arg) >= 1)
 | 
				
			||||||
 | 
								self = PyTuple_GET_ITEM(arg, 0);
 | 
				
			||||||
 | 
							if (self == NULL)
 | 
				
			||||||
 | 
								ok = 0;
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								ok = PyObject_IsInstance(self, class);
 | 
				
			||||||
 | 
								if (ok < 0)
 | 
				
			||||||
 | 
									return NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!ok) {
 | 
				
			||||||
 | 
								PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
									     "unbound method %s%s must be "
 | 
				
			||||||
 | 
									     "called with instance as first argument",
 | 
				
			||||||
 | 
									     PyEval_GetFuncName(func),
 | 
				
			||||||
 | 
									     PyEval_GetFuncDesc(func));
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							Py_INCREF(arg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							int argcount = PyTuple_Size(arg);
 | 
				
			||||||
 | 
							PyObject *newarg = PyTuple_New(argcount + 1);
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
							if (newarg == NULL)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							Py_INCREF(self);
 | 
				
			||||||
 | 
							PyTuple_SET_ITEM(newarg, 0, self);
 | 
				
			||||||
 | 
							for (i = 0; i < argcount; i++) {
 | 
				
			||||||
 | 
								PyObject *v = PyTuple_GET_ITEM(arg, i);
 | 
				
			||||||
 | 
								Py_XINCREF(v);
 | 
				
			||||||
 | 
								PyTuple_SET_ITEM(newarg, i+1, v);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							arg = newarg;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result = PyObject_Call((PyObject *)func, arg, kw);
 | 
				
			||||||
 | 
						Py_DECREF(arg);
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyTypeObject PyMethod_Type = {
 | 
					PyTypeObject PyMethod_Type = {
 | 
				
			||||||
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
| 
						 | 
					@ -2121,7 +2208,7 @@ PyTypeObject PyMethod_Type = {
 | 
				
			||||||
	0,					/* tp_as_sequence */
 | 
						0,					/* tp_as_sequence */
 | 
				
			||||||
	0,					/* tp_as_mapping */
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
	(hashfunc)instancemethod_hash,		/* tp_hash */
 | 
						(hashfunc)instancemethod_hash,		/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						instancemethod_call,			/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	(getattrofunc)instancemethod_getattro,	/* tp_getattro */
 | 
						(getattrofunc)instancemethod_getattro,	/* tp_getattro */
 | 
				
			||||||
	(setattrofunc)instancemethod_setattro,	/* tp_setattro */
 | 
						(setattrofunc)instancemethod_setattro,	/* tp_setattro */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@
 | 
				
			||||||
#ifndef WITHOUT_COMPLEX
 | 
					#ifndef WITHOUT_COMPLEX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Python.h"
 | 
					#include "Python.h"
 | 
				
			||||||
 | 
					#include "structmember.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Precisions used by repr() and str(), respectively.
 | 
					/* 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 *
 | 
					PyObject *
 | 
				
			||||||
PyComplex_FromCComplex(Py_complex cval)
 | 
					PyComplex_FromCComplex(Py_complex cval)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -196,6 +208,15 @@ PyComplex_FromCComplex(Py_complex cval)
 | 
				
			||||||
	return (PyObject *) op;
 | 
						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 *
 | 
					PyObject *
 | 
				
			||||||
PyComplex_FromDoubles(double real, double imag)
 | 
					PyComplex_FromDoubles(double real, double imag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -559,18 +580,260 @@ static PyMethodDef complex_methods[] = {
 | 
				
			||||||
	{NULL,		NULL}		/* sentinel */
 | 
						{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 *
 | 
					static PyObject *
 | 
				
			||||||
complex_getattr(PyComplexObject *self, char *name)
 | 
					complex_subtype_from_string(PyTypeObject *type, PyObject *v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (strcmp(name, "real") == 0)
 | 
						extern double strtod(const char *, char **);
 | 
				
			||||||
		return (PyObject *)PyFloat_FromDouble(self->cval.real);
 | 
						const char *s, *start;
 | 
				
			||||||
	else if (strcmp(name, "imag") == 0)
 | 
						char *end;
 | 
				
			||||||
		return (PyObject *)PyFloat_FromDouble(self->cval.imag);
 | 
						double x=0.0, y=0.0, z;
 | 
				
			||||||
	else if (strcmp(name, "__members__") == 0)
 | 
						int got_re=0, got_im=0, done=0;
 | 
				
			||||||
		return Py_BuildValue("[ss]", "imag", "real");
 | 
						int digit_or_dot;
 | 
				
			||||||
	return Py_FindMethod(complex_methods, (PyObject *)self, name);
 | 
						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 = {
 | 
					static PyNumberMethods complex_as_number = {
 | 
				
			||||||
	(binaryfunc)complex_add, 		/* nb_add */
 | 
						(binaryfunc)complex_add, 		/* nb_add */
 | 
				
			||||||
| 
						 | 
					@ -606,7 +869,7 @@ PyTypeObject PyComplex_Type = {
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	(destructor)complex_dealloc,		/* tp_dealloc */
 | 
						(destructor)complex_dealloc,		/* tp_dealloc */
 | 
				
			||||||
	(printfunc)complex_print,		/* tp_print */
 | 
						(printfunc)complex_print,		/* tp_print */
 | 
				
			||||||
	(getattrfunc)complex_getattr,		/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	(reprfunc)complex_repr,			/* tp_repr */
 | 
						(reprfunc)complex_repr,			/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -616,14 +879,28 @@ PyTypeObject PyComplex_Type = {
 | 
				
			||||||
	(hashfunc)complex_hash, 		/* tp_hash */
 | 
						(hashfunc)complex_hash, 		/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	(reprfunc)complex_str,			/* tp_str */
 | 
						(reprfunc)complex_str,			/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 | 
				
			||||||
	0,					/* tp_doc */
 | 
						complex_doc,				/* tp_doc */
 | 
				
			||||||
	0,					/* tp_traverse */
 | 
						0,					/* tp_traverse */
 | 
				
			||||||
	0,					/* tp_clear */
 | 
						0,					/* tp_clear */
 | 
				
			||||||
	complex_richcompare,			/* tp_richcompare */
 | 
						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
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										854
									
								
								Objects/descrobject.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										854
									
								
								Objects/descrobject.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,854 @@
 | 
				
			||||||
 | 
					/* Descriptors -- a new, flexible way to describe attributes */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Python.h"
 | 
				
			||||||
 | 
					#include "structmember.h" /* Why is this not included in Python.h? */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Various kinds of descriptor objects */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define COMMON \
 | 
				
			||||||
 | 
						PyObject_HEAD \
 | 
				
			||||||
 | 
						PyTypeObject *d_type; \
 | 
				
			||||||
 | 
						PyObject *d_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						COMMON;
 | 
				
			||||||
 | 
					} PyDescrObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						COMMON;
 | 
				
			||||||
 | 
						PyMethodDef *d_method;
 | 
				
			||||||
 | 
					} PyMethodDescrObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						COMMON;
 | 
				
			||||||
 | 
						struct memberlist *d_member;
 | 
				
			||||||
 | 
					} PyMemberDescrObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						COMMON;
 | 
				
			||||||
 | 
						struct getsetlist *d_getset;
 | 
				
			||||||
 | 
					} PyGetSetDescrObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						COMMON;
 | 
				
			||||||
 | 
						struct wrapperbase *d_base;
 | 
				
			||||||
 | 
						void *d_wrapped; /* This can be any function pointer */
 | 
				
			||||||
 | 
					} PyWrapperDescrObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					descr_dealloc(PyDescrObject *descr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Py_XDECREF(descr->d_type);
 | 
				
			||||||
 | 
						Py_XDECREF(descr->d_name);
 | 
				
			||||||
 | 
						PyObject_DEL(descr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *
 | 
				
			||||||
 | 
					descr_name(PyDescrObject *descr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (descr->d_name != NULL && PyString_Check(descr->d_name))
 | 
				
			||||||
 | 
							return PyString_AS_STRING(descr->d_name);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return "?";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					descr_repr(PyDescrObject *descr, char *format)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char buffer[500];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sprintf(buffer, format, descr_name(descr), descr->d_type->tp_name);
 | 
				
			||||||
 | 
						return PyString_FromString(buffer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					method_repr(PyMethodDescrObject *descr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return descr_repr((PyDescrObject *)descr, 
 | 
				
			||||||
 | 
								  "<method '%.300s' of '%.100s' objects>");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					member_repr(PyMemberDescrObject *descr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return descr_repr((PyDescrObject *)descr, 
 | 
				
			||||||
 | 
								  "<member '%.300s' of '%.100s' objects>");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					getset_repr(PyGetSetDescrObject *descr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return descr_repr((PyDescrObject *)descr, 
 | 
				
			||||||
 | 
								  "<attribute '%.300s' of '%.100s' objects>");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					wrapper_repr(PyWrapperDescrObject *descr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return descr_repr((PyDescrObject *)descr, 
 | 
				
			||||||
 | 
								  "<slot wrapper '%.300s' of '%.100s' objects>");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					descr_check(PyDescrObject *descr, PyObject *obj, PyTypeObject *type,
 | 
				
			||||||
 | 
						  PyObject **pres)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (obj == NULL || obj == Py_None) {
 | 
				
			||||||
 | 
							Py_INCREF(descr);
 | 
				
			||||||
 | 
							*pres = (PyObject *)descr;
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "descriptor '%.200s' for '%.100s' objects "
 | 
				
			||||||
 | 
								     "doesn't apply to '%.100s' object",
 | 
				
			||||||
 | 
								     descr_name((PyDescrObject *)descr),
 | 
				
			||||||
 | 
								     descr->d_type->tp_name,
 | 
				
			||||||
 | 
								     obj->ob_type->tp_name);
 | 
				
			||||||
 | 
							*pres = NULL;
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					method_get(PyMethodDescrObject *descr, PyObject *obj, PyTypeObject *type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (descr_check((PyDescrObject *)descr, obj, type, &res))
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
						return PyCFunction_New(descr->d_method, obj);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					member_get(PyMemberDescrObject *descr, PyObject *obj, PyTypeObject *type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (descr_check((PyDescrObject *)descr, obj, type, &res))
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
						return PyMember_Get((char *)obj, descr->d_member,
 | 
				
			||||||
 | 
								    descr->d_member->name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyTypeObject *type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (descr_check((PyDescrObject *)descr, obj, type, &res))
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
						if (descr->d_getset->get != NULL)
 | 
				
			||||||
 | 
							return descr->d_getset->get(obj, descr->d_getset->closure);
 | 
				
			||||||
 | 
						PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
							     "attribute '%300s' of '%.100s' objects is not readable",
 | 
				
			||||||
 | 
							     descr_name((PyDescrObject *)descr),
 | 
				
			||||||
 | 
							     descr->d_type->tp_name);
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					wrapper_get(PyWrapperDescrObject *descr, PyObject *obj, PyTypeObject *type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (descr_check((PyDescrObject *)descr, obj, type, &res))
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
						return PyWrapper_New((PyObject *)descr, obj);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
 | 
				
			||||||
 | 
						       int *pres)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						assert(obj != NULL);
 | 
				
			||||||
 | 
						if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "descriptor '%.200s' for '%.100s' objects "
 | 
				
			||||||
 | 
								     "doesn't apply to '%.100s' object",
 | 
				
			||||||
 | 
								     descr_name(descr),
 | 
				
			||||||
 | 
								     descr->d_type->tp_name,
 | 
				
			||||||
 | 
								     obj->ob_type->tp_name);
 | 
				
			||||||
 | 
							*pres = -1;
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
						return PyMember_Set((char *)obj, descr->d_member,
 | 
				
			||||||
 | 
								    descr->d_member->name, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
						if (descr->d_getset->set != NULL)
 | 
				
			||||||
 | 
							return descr->d_getset->set(obj, value,
 | 
				
			||||||
 | 
										    descr->d_getset->closure);
 | 
				
			||||||
 | 
						PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
							     "attribute '%300s' of '%.100s' objects is not writable",
 | 
				
			||||||
 | 
							     descr_name((PyDescrObject *)descr),
 | 
				
			||||||
 | 
							     descr->d_type->tp_name);
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int argc;
 | 
				
			||||||
 | 
						PyObject *self, *func, *result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make sure that the first argument is acceptable as 'self' */
 | 
				
			||||||
 | 
						assert(PyTuple_Check(args));
 | 
				
			||||||
 | 
						argc = PyTuple_GET_SIZE(args);
 | 
				
			||||||
 | 
						if (argc < 1) {
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "descriptor '%.300s' of '%.100s' "
 | 
				
			||||||
 | 
								     "object needs an argument",
 | 
				
			||||||
 | 
								     descr_name((PyDescrObject *)descr),
 | 
				
			||||||
 | 
								     descr->d_type->tp_name);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						self = PyTuple_GET_ITEM(args, 0);
 | 
				
			||||||
 | 
						if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "descriptor '%.200s' "
 | 
				
			||||||
 | 
								     "requires a '%.100s' object "
 | 
				
			||||||
 | 
								     "but received a '%.100s'",
 | 
				
			||||||
 | 
								     descr_name((PyDescrObject *)descr),
 | 
				
			||||||
 | 
								     descr->d_type->tp_name,
 | 
				
			||||||
 | 
								     self->ob_type->tp_name);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						func = PyCFunction_New(descr->d_method, self);
 | 
				
			||||||
 | 
						if (func == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						args = PyTuple_GetSlice(args, 1, argc);
 | 
				
			||||||
 | 
						if (args == NULL) {
 | 
				
			||||||
 | 
							Py_DECREF(func);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result = PyEval_CallObjectWithKeywords(func, args, kwds);
 | 
				
			||||||
 | 
						Py_DECREF(args);
 | 
				
			||||||
 | 
						Py_DECREF(func);
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int argc;
 | 
				
			||||||
 | 
						PyObject *self, *func, *result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make sure that the first argument is acceptable as 'self' */
 | 
				
			||||||
 | 
						assert(PyTuple_Check(args));
 | 
				
			||||||
 | 
						argc = PyTuple_GET_SIZE(args);
 | 
				
			||||||
 | 
						if (argc < 1) {
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "descriptor '%.300s' of '%.100s' "
 | 
				
			||||||
 | 
								     "object needs an argument",
 | 
				
			||||||
 | 
								     descr_name((PyDescrObject *)descr),
 | 
				
			||||||
 | 
								     descr->d_type->tp_name);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						self = PyTuple_GET_ITEM(args, 0);
 | 
				
			||||||
 | 
						if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "descriptor '%.200s' "
 | 
				
			||||||
 | 
								     "requires a '%.100s' object "
 | 
				
			||||||
 | 
								     "but received a '%.100s'",
 | 
				
			||||||
 | 
								     descr_name((PyDescrObject *)descr),
 | 
				
			||||||
 | 
								     descr->d_type->tp_name,
 | 
				
			||||||
 | 
								     self->ob_type->tp_name);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						func = PyWrapper_New((PyObject *)descr, self);
 | 
				
			||||||
 | 
						if (func == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						args = PyTuple_GetSlice(args, 1, argc);
 | 
				
			||||||
 | 
						if (args == NULL) {
 | 
				
			||||||
 | 
							Py_DECREF(func);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result = PyEval_CallObjectWithKeywords(func, args, kwds);
 | 
				
			||||||
 | 
						Py_DECREF(args);
 | 
				
			||||||
 | 
						Py_DECREF(func);
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					member_get_doc(PyMethodDescrObject *descr, void *closure)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (descr->d_method->ml_doc == NULL) {
 | 
				
			||||||
 | 
							Py_INCREF(Py_None);
 | 
				
			||||||
 | 
							return Py_None;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return PyString_FromString(descr->d_method->ml_doc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct memberlist descr_members[] = {
 | 
				
			||||||
 | 
						{"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
 | 
				
			||||||
 | 
						{"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
 | 
				
			||||||
 | 
						{0}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct getsetlist member_getset[] = {
 | 
				
			||||||
 | 
						{"__doc__", (getter)member_get_doc},
 | 
				
			||||||
 | 
						{0}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					wrapper_get_doc(PyWrapperDescrObject *descr, void *closure)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (descr->d_base->doc == NULL) {
 | 
				
			||||||
 | 
							Py_INCREF(Py_None);
 | 
				
			||||||
 | 
							return Py_None;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return PyString_FromString(descr->d_base->doc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct getsetlist wrapper_getset[] = {
 | 
				
			||||||
 | 
						{"__doc__", (getter)wrapper_get_doc},
 | 
				
			||||||
 | 
						{0}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyTypeObject PyMethodDescr_Type = {
 | 
				
			||||||
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						"method_descriptor",
 | 
				
			||||||
 | 
						sizeof(PyMethodDescrObject),
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						(destructor)descr_dealloc,		/* tp_dealloc */
 | 
				
			||||||
 | 
						0,					/* tp_print */
 | 
				
			||||||
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
 | 
						0,					/* tp_compare */
 | 
				
			||||||
 | 
						(reprfunc)method_repr,			/* tp_repr */
 | 
				
			||||||
 | 
						0,					/* tp_as_number */
 | 
				
			||||||
 | 
						0,					/* tp_as_sequence */
 | 
				
			||||||
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
 | 
						0,					/* tp_hash */
 | 
				
			||||||
 | 
						(ternaryfunc)methoddescr_call,		/* tp_call */
 | 
				
			||||||
 | 
						0,					/* tp_str */
 | 
				
			||||||
 | 
						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_richcompare */
 | 
				
			||||||
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
						0,					/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						descr_members,				/* tp_members */
 | 
				
			||||||
 | 
						member_getset,				/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						(descrgetfunc)method_get,		/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyTypeObject PyMemberDescr_Type = {
 | 
				
			||||||
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						"member_descriptor",
 | 
				
			||||||
 | 
						sizeof(PyMemberDescrObject),
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						(destructor)descr_dealloc,		/* tp_dealloc */
 | 
				
			||||||
 | 
						0,					/* tp_print */
 | 
				
			||||||
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
 | 
						0,					/* tp_compare */
 | 
				
			||||||
 | 
						(reprfunc)member_repr,			/* tp_repr */
 | 
				
			||||||
 | 
						0,					/* tp_as_number */
 | 
				
			||||||
 | 
						0,					/* tp_as_sequence */
 | 
				
			||||||
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
 | 
						0,					/* tp_hash */
 | 
				
			||||||
 | 
						(ternaryfunc)0,				/* tp_call */
 | 
				
			||||||
 | 
						0,					/* tp_str */
 | 
				
			||||||
 | 
						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_richcompare */
 | 
				
			||||||
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
						0,					/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						descr_members,				/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						(descrgetfunc)member_get,		/* tp_descr_get */
 | 
				
			||||||
 | 
						(descrsetfunc)member_set,		/* tp_descr_set */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyTypeObject PyGetSetDescr_Type = {
 | 
				
			||||||
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						"getset_descriptor",
 | 
				
			||||||
 | 
						sizeof(PyGetSetDescrObject),
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						(destructor)descr_dealloc,		/* tp_dealloc */
 | 
				
			||||||
 | 
						0,					/* tp_print */
 | 
				
			||||||
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
 | 
						0,					/* tp_compare */
 | 
				
			||||||
 | 
						(reprfunc)getset_repr,			/* tp_repr */
 | 
				
			||||||
 | 
						0,					/* tp_as_number */
 | 
				
			||||||
 | 
						0,					/* tp_as_sequence */
 | 
				
			||||||
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
 | 
						0,					/* tp_hash */
 | 
				
			||||||
 | 
						(ternaryfunc)0,				/* tp_call */
 | 
				
			||||||
 | 
						0,					/* tp_str */
 | 
				
			||||||
 | 
						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_richcompare */
 | 
				
			||||||
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
						0,					/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						descr_members,				/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						(descrgetfunc)getset_get,		/* tp_descr_get */
 | 
				
			||||||
 | 
						(descrsetfunc)getset_set,		/* tp_descr_set */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyTypeObject PyWrapperDescr_Type = {
 | 
				
			||||||
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						"wrapper_descriptor",
 | 
				
			||||||
 | 
						sizeof(PyWrapperDescrObject),
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						(destructor)descr_dealloc,		/* tp_dealloc */
 | 
				
			||||||
 | 
						0,					/* tp_print */
 | 
				
			||||||
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
 | 
						0,					/* tp_compare */
 | 
				
			||||||
 | 
						(reprfunc)wrapper_repr,			/* tp_repr */
 | 
				
			||||||
 | 
						0,					/* tp_as_number */
 | 
				
			||||||
 | 
						0,					/* tp_as_sequence */
 | 
				
			||||||
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
 | 
						0,					/* tp_hash */
 | 
				
			||||||
 | 
						(ternaryfunc)wrapperdescr_call,		/* tp_call */
 | 
				
			||||||
 | 
						0,					/* tp_str */
 | 
				
			||||||
 | 
						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_richcompare */
 | 
				
			||||||
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
						0,					/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						descr_members,				/* tp_members */
 | 
				
			||||||
 | 
						wrapper_getset,				/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						(descrgetfunc)wrapper_get,		/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyDescrObject *
 | 
				
			||||||
 | 
					descr_new(PyTypeObject *descrtype, PyTypeObject *type, char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyDescrObject *descr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
 | 
				
			||||||
 | 
						if (descr != NULL) {
 | 
				
			||||||
 | 
							Py_XINCREF(type);
 | 
				
			||||||
 | 
							descr->d_type = type;
 | 
				
			||||||
 | 
							descr->d_name = PyString_InternFromString(name);
 | 
				
			||||||
 | 
							if (descr->d_name == NULL) {
 | 
				
			||||||
 | 
								Py_DECREF(descr);
 | 
				
			||||||
 | 
								descr = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return descr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyMethodDescrObject *descr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
 | 
				
			||||||
 | 
											 type, method->ml_name);
 | 
				
			||||||
 | 
						if (descr != NULL)
 | 
				
			||||||
 | 
							descr->d_method = method;
 | 
				
			||||||
 | 
						return (PyObject *)descr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyDescr_NewMember(PyTypeObject *type, struct memberlist *member)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyMemberDescrObject *descr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
 | 
				
			||||||
 | 
											 type, member->name);
 | 
				
			||||||
 | 
						if (descr != NULL)
 | 
				
			||||||
 | 
							descr->d_member = member;
 | 
				
			||||||
 | 
						return (PyObject *)descr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyDescr_NewGetSet(PyTypeObject *type, struct getsetlist *getset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyGetSetDescrObject *descr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
 | 
				
			||||||
 | 
											 type, getset->name);
 | 
				
			||||||
 | 
						if (descr != NULL)
 | 
				
			||||||
 | 
							descr->d_getset = getset;
 | 
				
			||||||
 | 
						return (PyObject *)descr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyWrapperDescrObject *descr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
 | 
				
			||||||
 | 
											 type, base->name);
 | 
				
			||||||
 | 
						if (descr != NULL) {
 | 
				
			||||||
 | 
							descr->d_base = base;
 | 
				
			||||||
 | 
							descr->d_wrapped = wrapped;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (PyObject *)descr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					PyDescr_IsData(PyObject *d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return d->ob_type->tp_descr_set != NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* --- Readonly proxy for dictionaries (actually any mapping) --- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This has no reason to be in this file except that adding new files is a
 | 
				
			||||||
 | 
					   bit of a pain */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						PyObject_HEAD
 | 
				
			||||||
 | 
						PyObject *dict;
 | 
				
			||||||
 | 
					} proxyobject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					proxy_len(proxyobject *pp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PyObject_Size(pp->dict);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					proxy_getitem(proxyobject *pp, PyObject *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PyObject_GetItem(pp->dict, key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyMappingMethods proxy_as_mapping = {
 | 
				
			||||||
 | 
						(inquiry)proxy_len,			/* mp_length */
 | 
				
			||||||
 | 
						(binaryfunc)proxy_getitem,		/* mp_subscript */
 | 
				
			||||||
 | 
						0,					/* mp_ass_subscript */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					proxy_contains(proxyobject *pp, PyObject *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PySequence_Contains(pp->dict, key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PySequenceMethods proxy_as_sequence = {
 | 
				
			||||||
 | 
						0,					/* sq_length */
 | 
				
			||||||
 | 
						0,					/* sq_concat */
 | 
				
			||||||
 | 
						0,					/* sq_repeat */
 | 
				
			||||||
 | 
						0,					/* sq_item */
 | 
				
			||||||
 | 
						0,					/* sq_slice */
 | 
				
			||||||
 | 
						0,					/* sq_ass_item */
 | 
				
			||||||
 | 
						0,					/* sq_ass_slice */
 | 
				
			||||||
 | 
						(objobjproc)proxy_contains,		/* sq_contains */
 | 
				
			||||||
 | 
						0,					/* sq_inplace_concat */
 | 
				
			||||||
 | 
						0,					/* sq_inplace_repeat */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					proxy_has_key(proxyobject *pp, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, "O:has_key", &key))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						return PyInt_FromLong(PySequence_Contains(pp->dict, key));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					proxy_get(proxyobject *pp, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *key, *def = Py_None;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, "O|O:get", &key, &def))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					proxy_keys(proxyobject *pp, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, ":keys"))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						return PyMapping_Keys(pp->dict);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					proxy_values(proxyobject *pp, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, ":values"))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						return PyMapping_Values(pp->dict);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					proxy_items(proxyobject *pp, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, ":items"))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						return PyMapping_Items(pp->dict);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					proxy_copy(proxyobject *pp, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, ":copy"))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						return PyObject_CallMethod(pp->dict, "copy", NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyMethodDef proxy_methods[] = {
 | 
				
			||||||
 | 
						{"has_key", (PyCFunction)proxy_has_key, METH_VARARGS, "XXX"},
 | 
				
			||||||
 | 
						{"get",	    (PyCFunction)proxy_get,     METH_VARARGS, "XXX"},
 | 
				
			||||||
 | 
						{"keys",    (PyCFunction)proxy_keys,    METH_VARARGS, "XXX"},
 | 
				
			||||||
 | 
						{"values",  (PyCFunction)proxy_values,  METH_VARARGS, "XXX"},
 | 
				
			||||||
 | 
						{"items",   (PyCFunction)proxy_items,   METH_VARARGS, "XXX"},
 | 
				
			||||||
 | 
						{"copy",    (PyCFunction)proxy_copy,    METH_VARARGS, "XXX"},
 | 
				
			||||||
 | 
						{0}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					proxy_dealloc(proxyobject *pp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Py_DECREF(pp->dict);
 | 
				
			||||||
 | 
						PyObject_DEL(pp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					proxy_getiter(proxyobject *pp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PyObject_GetIter(pp->dict);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					proxy_str(proxyobject *pp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return PyObject_Str(pp->dict);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyTypeObject proxytype = {
 | 
				
			||||||
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
 | 
						0,					/* ob_size */
 | 
				
			||||||
 | 
						"dict-proxy",				/* tp_name */
 | 
				
			||||||
 | 
						sizeof(proxyobject),			/* tp_basicsize */
 | 
				
			||||||
 | 
						0,					/* tp_itemsize */
 | 
				
			||||||
 | 
						/* methods */
 | 
				
			||||||
 | 
						(destructor)proxy_dealloc, 		/* tp_dealloc */
 | 
				
			||||||
 | 
						0,					/* tp_print */
 | 
				
			||||||
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
 | 
						0,					/* tp_compare */
 | 
				
			||||||
 | 
						0,					/* tp_repr */
 | 
				
			||||||
 | 
						0,					/* tp_as_number */
 | 
				
			||||||
 | 
						&proxy_as_sequence,			/* tp_as_sequence */
 | 
				
			||||||
 | 
						&proxy_as_mapping,			/* tp_as_mapping */
 | 
				
			||||||
 | 
						0,					/* tp_hash */
 | 
				
			||||||
 | 
						0,					/* tp_call */
 | 
				
			||||||
 | 
						(reprfunc)proxy_str,			/* tp_str */
 | 
				
			||||||
 | 
						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_richcompare */
 | 
				
			||||||
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
						(getiterfunc)proxy_getiter,		/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						proxy_methods,				/* tp_methods */
 | 
				
			||||||
 | 
						0,					/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						0,					/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyDictProxy_New(PyObject *dict)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						proxyobject *pp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pp = PyObject_NEW(proxyobject, &proxytype);
 | 
				
			||||||
 | 
						if (pp != NULL) {
 | 
				
			||||||
 | 
							Py_INCREF(dict);
 | 
				
			||||||
 | 
							pp->dict = dict;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (PyObject *)pp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* --- Wrapper object for "slot" methods --- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This has no reason to be in this file except that adding new files is a
 | 
				
			||||||
 | 
					   bit of a pain */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						PyObject_HEAD
 | 
				
			||||||
 | 
						PyWrapperDescrObject *descr;
 | 
				
			||||||
 | 
						PyObject *self;
 | 
				
			||||||
 | 
					} wrapperobject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					wrapper_dealloc(wrapperobject *wp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Py_XDECREF(wp->descr);
 | 
				
			||||||
 | 
						Py_XDECREF(wp->self);
 | 
				
			||||||
 | 
						PyObject_DEL(wp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyMethodDef wrapper_methods[] = {
 | 
				
			||||||
 | 
						{0}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					wrapper_name(wrapperobject *wp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *s = wp->descr->d_base->name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return PyString_FromString(s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					wrapper_doc(wrapperobject *wp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *s = wp->descr->d_base->doc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (s == NULL) {
 | 
				
			||||||
 | 
							Py_INCREF(Py_None);
 | 
				
			||||||
 | 
							return Py_None;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							return PyString_FromString(s);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct getsetlist wrapper_getsets[] = {
 | 
				
			||||||
 | 
						{"__name__", (getter)wrapper_name},
 | 
				
			||||||
 | 
						{"__doc__", (getter)wrapper_doc},
 | 
				
			||||||
 | 
						{0}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						wrapperfunc wrapper = wp->descr->d_base->wrapper;
 | 
				
			||||||
 | 
						PyObject *self = wp->self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (*wrapper)(self, args, wp->descr->d_wrapped);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyTypeObject wrappertype = {
 | 
				
			||||||
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
 | 
						0,					/* ob_size */
 | 
				
			||||||
 | 
						"method-wrapper",			/* tp_name */
 | 
				
			||||||
 | 
						sizeof(wrapperobject),			/* tp_basicsize */
 | 
				
			||||||
 | 
						0,					/* tp_itemsize */
 | 
				
			||||||
 | 
						/* methods */
 | 
				
			||||||
 | 
						(destructor)wrapper_dealloc, 		/* 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 */
 | 
				
			||||||
 | 
						(ternaryfunc)wrapper_call,		/* tp_call */
 | 
				
			||||||
 | 
						0,					/* tp_str */
 | 
				
			||||||
 | 
						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_richcompare */
 | 
				
			||||||
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
						0,					/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						wrapper_methods,			/* tp_methods */
 | 
				
			||||||
 | 
						0,					/* tp_members */
 | 
				
			||||||
 | 
						wrapper_getsets,			/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						0,					/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyWrapper_New(PyObject *d, PyObject *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						wrapperobject *wp;
 | 
				
			||||||
 | 
						PyWrapperDescrObject *descr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
 | 
				
			||||||
 | 
						descr = (PyWrapperDescrObject *)d;
 | 
				
			||||||
 | 
						assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wp = PyObject_NEW(wrapperobject, &wrappertype);
 | 
				
			||||||
 | 
						if (wp != NULL) {
 | 
				
			||||||
 | 
							Py_INCREF(descr);
 | 
				
			||||||
 | 
							wp->descr = descr;
 | 
				
			||||||
 | 
							Py_INCREF(self);
 | 
				
			||||||
 | 
							wp->self = self;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (PyObject *)wp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3,15 +3,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Python.h"
 | 
					#include "Python.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* MINSIZE is the minimum size of a dictionary.  This many slots are
 | 
					typedef PyDictEntry dictentry;
 | 
				
			||||||
 * allocated directly in the dict object (in the ma_smalltable member).
 | 
					typedef PyDictObject dictobject;
 | 
				
			||||||
 * 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 MINSIZE 8
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Define this out if you don't want conversion statistics on exit. */
 | 
					/* Define this out if you don't want conversion statistics on exit. */
 | 
				
			||||||
#undef SHOW_CONVERSION_COUNTS
 | 
					#undef SHOW_CONVERSION_COUNTS
 | 
				
			||||||
| 
						 | 
					@ -116,69 +109,6 @@ equally good collision statistics, needed less code & used less memory.
 | 
				
			||||||
/* Object used as dummy key to fill deleted entries */
 | 
					/* Object used as dummy key to fill deleted entries */
 | 
				
			||||||
static PyObject *dummy; /* Initialized by first call to newdictobject() */
 | 
					static PyObject *dummy; /* Initialized by first call to newdictobject() */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
	long me_hash;      /* cached hash code of me_key */
 | 
					 | 
				
			||||||
	PyObject *me_key;
 | 
					 | 
				
			||||||
	PyObject *me_value;
 | 
					 | 
				
			||||||
#ifdef USE_CACHE_ALIGNED
 | 
					 | 
				
			||||||
	long	aligner;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
} dictentry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
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 dictobject;
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	dictentry *ma_table;
 | 
					 | 
				
			||||||
	dictentry *(*ma_lookup)(dictobject *mp, PyObject *key, long hash);
 | 
					 | 
				
			||||||
	dictentry ma_smalltable[MINSIZE];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* forward declarations */
 | 
					/* forward declarations */
 | 
				
			||||||
static dictentry *
 | 
					static dictentry *
 | 
				
			||||||
lookdict_string(dictobject *mp, PyObject *key, long hash);
 | 
					lookdict_string(dictobject *mp, PyObject *key, long hash);
 | 
				
			||||||
| 
						 | 
					@ -196,12 +126,24 @@ show_counts(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Set dictobject* mp to empty but w/ MINSIZE slots, using ma_smalltable. */
 | 
					/* Initialization macros.
 | 
				
			||||||
#define empty_to_minsize(mp) do { 					\
 | 
					   There are two ways to create a dict:  PyDict_New() is the main C API
 | 
				
			||||||
	memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable));	\
 | 
					   function, and the tp_new slot maps to dict_new().  In the latter case we
 | 
				
			||||||
 | 
					   can save a little time over what PyDict_New does because it's guaranteed
 | 
				
			||||||
 | 
					   that the PyDictObject struct is already zeroed out.
 | 
				
			||||||
 | 
					   Everyone except dict_new() should use EMPTY_TO_MINSIZE (unless they have
 | 
				
			||||||
 | 
					   an excellent reason not to).
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define INIT_NONZERO_DICT_SLOTS(mp) do {				\
 | 
				
			||||||
	(mp)->ma_table = (mp)->ma_smalltable;				\
 | 
						(mp)->ma_table = (mp)->ma_smalltable;				\
 | 
				
			||||||
	(mp)->ma_mask = MINSIZE - 1;					\
 | 
						(mp)->ma_mask = PyDict_MINSIZE - 1;				\
 | 
				
			||||||
 | 
					    } while(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EMPTY_TO_MINSIZE(mp) do {					\
 | 
				
			||||||
 | 
						memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable));	\
 | 
				
			||||||
	(mp)->ma_used = (mp)->ma_fill = 0;				\
 | 
						(mp)->ma_used = (mp)->ma_fill = 0;				\
 | 
				
			||||||
 | 
						INIT_NONZERO_DICT_SLOTS(mp);					\
 | 
				
			||||||
    } while(0)
 | 
					    } while(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
| 
						 | 
					@ -219,7 +161,7 @@ PyDict_New(void)
 | 
				
			||||||
	mp = PyObject_NEW(dictobject, &PyDict_Type);
 | 
						mp = PyObject_NEW(dictobject, &PyDict_Type);
 | 
				
			||||||
	if (mp == NULL)
 | 
						if (mp == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	empty_to_minsize(mp);
 | 
						EMPTY_TO_MINSIZE(mp);
 | 
				
			||||||
	mp->ma_lookup = lookdict_string;
 | 
						mp->ma_lookup = lookdict_string;
 | 
				
			||||||
#ifdef SHOW_CONVERSION_COUNTS
 | 
					#ifdef SHOW_CONVERSION_COUNTS
 | 
				
			||||||
	++created;
 | 
						++created;
 | 
				
			||||||
| 
						 | 
					@ -418,7 +360,10 @@ insertdict(register dictobject *mp, PyObject *key, long hash, PyObject *value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PyObject *old_value;
 | 
						PyObject *old_value;
 | 
				
			||||||
	register dictentry *ep;
 | 
						register dictentry *ep;
 | 
				
			||||||
	ep = (mp->ma_lookup)(mp, key, hash);
 | 
						typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(mp->ma_lookup != NULL);
 | 
				
			||||||
 | 
						ep = mp->ma_lookup(mp, key, hash);
 | 
				
			||||||
	if (ep->me_value != NULL) {
 | 
						if (ep->me_value != NULL) {
 | 
				
			||||||
		old_value = ep->me_value;
 | 
							old_value = ep->me_value;
 | 
				
			||||||
		ep->me_value = value;
 | 
							ep->me_value = value;
 | 
				
			||||||
| 
						 | 
					@ -449,12 +394,12 @@ dictresize(dictobject *mp, int minused)
 | 
				
			||||||
	dictentry *oldtable, *newtable, *ep;
 | 
						dictentry *oldtable, *newtable, *ep;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int is_oldtable_malloced;
 | 
						int is_oldtable_malloced;
 | 
				
			||||||
	dictentry small_copy[MINSIZE];
 | 
						dictentry small_copy[PyDict_MINSIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert(minused >= 0);
 | 
						assert(minused >= 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Find the smallest table size > minused. */
 | 
						/* Find the smallest table size > minused. */
 | 
				
			||||||
	for (newsize = MINSIZE;
 | 
						for (newsize = PyDict_MINSIZE;
 | 
				
			||||||
	     newsize <= minused && newsize > 0;
 | 
						     newsize <= minused && newsize > 0;
 | 
				
			||||||
	     newsize <<= 1)
 | 
						     newsize <<= 1)
 | 
				
			||||||
		;
 | 
							;
 | 
				
			||||||
| 
						 | 
					@ -468,7 +413,7 @@ dictresize(dictobject *mp, int minused)
 | 
				
			||||||
	assert(oldtable != NULL);
 | 
						assert(oldtable != NULL);
 | 
				
			||||||
	is_oldtable_malloced = oldtable != mp->ma_smalltable;
 | 
						is_oldtable_malloced = oldtable != mp->ma_smalltable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (newsize == MINSIZE) {
 | 
						if (newsize == PyDict_MINSIZE) {
 | 
				
			||||||
		/* A large table is shrinking, or we can't get any smaller. */
 | 
							/* A large table is shrinking, or we can't get any smaller. */
 | 
				
			||||||
		newtable = mp->ma_smalltable;
 | 
							newtable = mp->ma_smalltable;
 | 
				
			||||||
		if (newtable == oldtable) {
 | 
							if (newtable == oldtable) {
 | 
				
			||||||
| 
						 | 
					@ -649,7 +594,7 @@ PyDict_Clear(PyObject *op)
 | 
				
			||||||
	dictentry *ep, *table;
 | 
						dictentry *ep, *table;
 | 
				
			||||||
	int table_is_malloced;
 | 
						int table_is_malloced;
 | 
				
			||||||
	int fill;
 | 
						int fill;
 | 
				
			||||||
	dictentry small_copy[MINSIZE];
 | 
						dictentry small_copy[PyDict_MINSIZE];
 | 
				
			||||||
#ifdef Py_DEBUG
 | 
					#ifdef Py_DEBUG
 | 
				
			||||||
	int i, n;
 | 
						int i, n;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -674,7 +619,7 @@ PyDict_Clear(PyObject *op)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	fill = mp->ma_fill;
 | 
						fill = mp->ma_fill;
 | 
				
			||||||
	if (table_is_malloced)
 | 
						if (table_is_malloced)
 | 
				
			||||||
		empty_to_minsize(mp);
 | 
							EMPTY_TO_MINSIZE(mp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	else if (fill > 0) {
 | 
						else if (fill > 0) {
 | 
				
			||||||
		/* It's a small table with something that needs to be cleared.
 | 
							/* It's a small table with something that needs to be cleared.
 | 
				
			||||||
| 
						 | 
					@ -683,7 +628,7 @@ PyDict_Clear(PyObject *op)
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		memcpy(small_copy, table, sizeof(small_copy));
 | 
							memcpy(small_copy, table, sizeof(small_copy));
 | 
				
			||||||
		table = small_copy;
 | 
							table = small_copy;
 | 
				
			||||||
		empty_to_minsize(mp);
 | 
							EMPTY_TO_MINSIZE(mp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/* else it's a small table that's already empty */
 | 
						/* else it's a small table that's already empty */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1042,32 +987,47 @@ dict_items(register dictobject *mp, PyObject *args)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
dict_update(register dictobject *mp, PyObject *args)
 | 
					dict_update(PyObject *mp, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						PyObject *other;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, "O:update", &other))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_Update(mp, other) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						Py_INCREF(Py_None);
 | 
				
			||||||
 | 
						return Py_None;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					PyDict_Update(PyObject *a, PyObject *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						register PyDictObject *mp, *other;
 | 
				
			||||||
	register int i;
 | 
						register int i;
 | 
				
			||||||
	dictobject *other;
 | 
					 | 
				
			||||||
	dictentry *entry;
 | 
						dictentry *entry;
 | 
				
			||||||
	PyObject *param;
 | 
					
 | 
				
			||||||
	/* We accept for the argument either a concrete dictionary object,
 | 
						/* We accept for the argument either a concrete dictionary object,
 | 
				
			||||||
	 * or an abstract "mapping" object.  For the former, we can do
 | 
						 * or an abstract "mapping" object.  For the former, we can do
 | 
				
			||||||
	 * things quite efficiently.  For the latter, we only require that
 | 
						 * things quite efficiently.  For the latter, we only require that
 | 
				
			||||||
	 * PyMapping_Keys() and PyObject_GetItem() be supported.
 | 
						 * PyMapping_Keys() and PyObject_GetItem() be supported.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O:update", ¶m))
 | 
						if (a == NULL || !PyDict_Check(a) || b == NULL) {
 | 
				
			||||||
		return NULL;
 | 
							PyErr_BadInternalCall();
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
	if (PyDict_Check(param)) {
 | 
						}
 | 
				
			||||||
		other = (dictobject*)param;
 | 
						mp = (dictobject*)a;
 | 
				
			||||||
 | 
						if (PyDict_Check(b)) {
 | 
				
			||||||
 | 
							other = (dictobject*)b;
 | 
				
			||||||
		if (other == mp || other->ma_used == 0)
 | 
							if (other == mp || other->ma_used == 0)
 | 
				
			||||||
			/* a.update(a) or a.update({}); nothing to do */
 | 
								/* a.update(a) or a.update({}); nothing to do */
 | 
				
			||||||
			goto done;
 | 
								return 0;
 | 
				
			||||||
		/* Do one big resize at the start, rather than
 | 
							/* Do one big resize at the start, rather than
 | 
				
			||||||
		 * incrementally resizing as we insert new items.  Expect
 | 
							 * incrementally resizing as we insert new items.  Expect
 | 
				
			||||||
		 * that there will be no (or few) overlapping keys.
 | 
							 * that there will be no (or few) overlapping keys.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) {
 | 
							if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) {
 | 
				
			||||||
		   if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0)
 | 
							   if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0)
 | 
				
			||||||
			   return NULL;
 | 
								   return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for (i = 0; i <= other->ma_mask; i++) {
 | 
							for (i = 0; i <= other->ma_mask; i++) {
 | 
				
			||||||
			entry = &other->ma_table[i];
 | 
								entry = &other->ma_table[i];
 | 
				
			||||||
| 
						 | 
					@ -1081,7 +1041,7 @@ dict_update(register dictobject *mp, PyObject *args)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		/* Do it the generic, slower way */
 | 
							/* Do it the generic, slower way */
 | 
				
			||||||
		PyObject *keys = PyMapping_Keys(param);
 | 
							PyObject *keys = PyMapping_Keys(b);
 | 
				
			||||||
		PyObject *iter;
 | 
							PyObject *iter;
 | 
				
			||||||
		PyObject *key, *value;
 | 
							PyObject *key, *value;
 | 
				
			||||||
		int status;
 | 
							int status;
 | 
				
			||||||
| 
						 | 
					@ -1092,37 +1052,34 @@ dict_update(register dictobject *mp, PyObject *args)
 | 
				
			||||||
			 * AttributeError to percolate up.  Might as well
 | 
								 * AttributeError to percolate up.  Might as well
 | 
				
			||||||
			 * do the same for any other error.
 | 
								 * do the same for any other error.
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			return NULL;
 | 
								return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		iter = PyObject_GetIter(keys);
 | 
							iter = PyObject_GetIter(keys);
 | 
				
			||||||
		Py_DECREF(keys);
 | 
							Py_DECREF(keys);
 | 
				
			||||||
		if (iter == NULL)
 | 
							if (iter == NULL)
 | 
				
			||||||
			return NULL;
 | 
								return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
 | 
							for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
 | 
				
			||||||
			value = PyObject_GetItem(param, key);
 | 
								value = PyObject_GetItem(b, key);
 | 
				
			||||||
			if (value == NULL) {
 | 
								if (value == NULL) {
 | 
				
			||||||
				Py_DECREF(iter);
 | 
									Py_DECREF(iter);
 | 
				
			||||||
				Py_DECREF(key);
 | 
									Py_DECREF(key);
 | 
				
			||||||
				return NULL;
 | 
									return -1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			status = PyDict_SetItem((PyObject*)mp, key, value);
 | 
								status = PyDict_SetItem((PyObject*)mp, key, value);
 | 
				
			||||||
			Py_DECREF(key);
 | 
								Py_DECREF(key);
 | 
				
			||||||
			Py_DECREF(value);
 | 
								Py_DECREF(value);
 | 
				
			||||||
			if (status < 0) {
 | 
								if (status < 0) {
 | 
				
			||||||
				Py_DECREF(iter);
 | 
									Py_DECREF(iter);
 | 
				
			||||||
				return NULL;
 | 
									return -1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Py_DECREF(iter);
 | 
							Py_DECREF(iter);
 | 
				
			||||||
		if (PyErr_Occurred())
 | 
							if (PyErr_Occurred())
 | 
				
			||||||
			/* Iterator completed, via error */
 | 
								/* Iterator completed, via error */
 | 
				
			||||||
			return NULL;
 | 
								return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						return 0;
 | 
				
			||||||
  done:
 | 
					 | 
				
			||||||
	Py_INCREF(Py_None);
 | 
					 | 
				
			||||||
	return Py_None;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
| 
						 | 
					@ -1694,12 +1651,6 @@ static PyMethodDef mapp_methods[] = {
 | 
				
			||||||
	{NULL,		NULL}	/* sentinel */
 | 
						{NULL,		NULL}	/* sentinel */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
dict_getattr(dictobject *mp, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return Py_FindMethod(mapp_methods, (PyObject *)mp, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
dict_contains(dictobject *mp, PyObject *key)
 | 
					dict_contains(dictobject *mp, PyObject *key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1731,6 +1682,26 @@ static PySequenceMethods dict_as_sequence = {
 | 
				
			||||||
	0,					/* sq_inplace_repeat */
 | 
						0,					/* sq_inplace_repeat */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(type != NULL && type->tp_alloc != NULL);
 | 
				
			||||||
 | 
						self = type->tp_alloc(type, 0);
 | 
				
			||||||
 | 
						if (self != NULL) {
 | 
				
			||||||
 | 
							PyDictObject *d = (PyDictObject *)self;
 | 
				
			||||||
 | 
							/* It's guaranteed that tp->alloc zeroed out the struct. */
 | 
				
			||||||
 | 
							assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0);
 | 
				
			||||||
 | 
							INIT_NONZERO_DICT_SLOTS(d);
 | 
				
			||||||
 | 
							d->ma_lookup = lookdict_string;
 | 
				
			||||||
 | 
					#ifdef SHOW_CONVERSION_COUNTS
 | 
				
			||||||
 | 
							++created;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
dict_iter(dictobject *dict)
 | 
					dict_iter(dictobject *dict)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1745,7 +1716,7 @@ PyTypeObject PyDict_Type = {
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	(destructor)dict_dealloc,		/* tp_dealloc */
 | 
						(destructor)dict_dealloc,		/* tp_dealloc */
 | 
				
			||||||
	(printfunc)dict_print,			/* tp_print */
 | 
						(printfunc)dict_print,			/* tp_print */
 | 
				
			||||||
	(getattrfunc)dict_getattr,		/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	(cmpfunc)dict_compare,			/* tp_compare */
 | 
						(cmpfunc)dict_compare,			/* tp_compare */
 | 
				
			||||||
	(reprfunc)dict_repr,			/* tp_repr */
 | 
						(reprfunc)dict_repr,			/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -1755,17 +1726,29 @@ PyTypeObject PyDict_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC |
 | 
				
			||||||
	0,					/* tp_doc */
 | 
							Py_TPFLAGS_BASETYPE,		/* tp_flags */
 | 
				
			||||||
 | 
						"dictionary type",			/* tp_doc */
 | 
				
			||||||
	(traverseproc)dict_traverse,		/* tp_traverse */
 | 
						(traverseproc)dict_traverse,		/* tp_traverse */
 | 
				
			||||||
	(inquiry)dict_tp_clear,			/* tp_clear */
 | 
						(inquiry)dict_tp_clear,			/* tp_clear */
 | 
				
			||||||
	dict_richcompare,			/* tp_richcompare */
 | 
						dict_richcompare,			/* tp_richcompare */
 | 
				
			||||||
	0,					/* tp_weaklistoffset */
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
	(getiterfunc)dict_iter,			/* tp_iter */
 | 
						(getiterfunc)dict_iter,			/* tp_iter */
 | 
				
			||||||
	0,					/* tp_iternext */
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						mapp_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 */
 | 
				
			||||||
 | 
						0,					/* tp_init */
 | 
				
			||||||
 | 
						PyType_GenericAlloc,			/* tp_alloc */
 | 
				
			||||||
 | 
						dict_new,				/* tp_new */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* For backward compatibility with old dictionary interface */
 | 
					/* For backward compatibility with old dictionary interface */
 | 
				
			||||||
| 
						 | 
					@ -1873,12 +1856,6 @@ static PyMethodDef dictiter_methods[] = {
 | 
				
			||||||
	{NULL,		NULL}		/* sentinel */
 | 
						{NULL,		NULL}		/* sentinel */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
dictiter_getattr(dictiterobject *di, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return Py_FindMethod(dictiter_methods, (PyObject *)di, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *dictiter_iternext(dictiterobject *di)
 | 
					static PyObject *dictiter_iternext(dictiterobject *di)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PyObject *key, *value;
 | 
						PyObject *key, *value;
 | 
				
			||||||
| 
						 | 
					@ -1903,7 +1880,7 @@ PyTypeObject PyDictIter_Type = {
 | 
				
			||||||
	/* methods */
 | 
						/* methods */
 | 
				
			||||||
	(destructor)dictiter_dealloc, 		/* tp_dealloc */
 | 
						(destructor)dictiter_dealloc, 		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	(getattrfunc)dictiter_getattr,		/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	0,					/* tp_repr */
 | 
						0,					/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -1913,7 +1890,7 @@ PyTypeObject PyDictIter_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
				
			||||||
| 
						 | 
					@ -1924,4 +1901,11 @@ PyTypeObject PyDictIter_Type = {
 | 
				
			||||||
	0,					/* tp_weaklistoffset */
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
	(getiterfunc)dictiter_getiter,		/* tp_iter */
 | 
						(getiterfunc)dictiter_getiter,		/* tp_iter */
 | 
				
			||||||
	(iternextfunc)dictiter_iternext,	/* tp_iternext */
 | 
						(iternextfunc)dictiter_iternext,	/* tp_iternext */
 | 
				
			||||||
 | 
						dictiter_methods,			/* tp_methods */
 | 
				
			||||||
 | 
						0,					/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						0,					/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1273,29 +1273,15 @@ static struct memberlist file_memberlist[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					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 PyInt_FromLong((long)(f->f_fp == 0));
 | 
				
			||||||
	return PyMember_Get((char *)f, file_memberlist, name);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static struct getsetlist file_getsetlist[] = {
 | 
				
			||||||
file_setattr(PyFileObject *f, char *name, PyObject *v)
 | 
						{"closed", (getter)get_closed, NULL, NULL},
 | 
				
			||||||
{
 | 
						{0},
 | 
				
			||||||
	if (v == NULL) {
 | 
					};
 | 
				
			||||||
		PyErr_SetString(PyExc_AttributeError,
 | 
					 | 
				
			||||||
				"can't delete file attributes");
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return PyMember_Set((char *)f, file_memberlist, name, v);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
file_getiter(PyObject *f)
 | 
					file_getiter(PyObject *f)
 | 
				
			||||||
| 
						 | 
					@ -1311,8 +1297,8 @@ PyTypeObject PyFile_Type = {
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	(destructor)file_dealloc,		/* tp_dealloc */
 | 
						(destructor)file_dealloc,		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	(getattrfunc)file_getattr,		/* tp_getattr */
 | 
						0,			 		/* tp_getattr */
 | 
				
			||||||
	(setattrfunc)file_setattr,		/* tp_setattr */
 | 
						0,			 		/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	(reprfunc)file_repr, 			/* tp_repr */
 | 
						(reprfunc)file_repr, 			/* tp_repr */
 | 
				
			||||||
	0,					/* tp_as_number */
 | 
						0,					/* tp_as_number */
 | 
				
			||||||
| 
						 | 
					@ -1321,7 +1307,7 @@ PyTypeObject PyFile_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
				
			||||||
| 
						 | 
					@ -1332,6 +1318,11 @@ PyTypeObject PyFile_Type = {
 | 
				
			||||||
	0,					/* tp_weaklistoffset */
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
	file_getiter,				/* tp_iter */
 | 
						file_getiter,				/* tp_iter */
 | 
				
			||||||
	0,					/* tp_iternext */
 | 
						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. */
 | 
					/* 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 = {
 | 
					static PyNumberMethods float_as_number = {
 | 
				
			||||||
	(binaryfunc)float_add, /*nb_add*/
 | 
						(binaryfunc)float_add, /*nb_add*/
 | 
				
			||||||
	(binaryfunc)float_sub, /*nb_subtract*/
 | 
						(binaryfunc)float_sub, /*nb_subtract*/
 | 
				
			||||||
| 
						 | 
					@ -691,10 +711,28 @@ PyTypeObject PyFloat_Type = {
 | 
				
			||||||
	(hashfunc)float_hash,			/* tp_hash */
 | 
						(hashfunc)float_hash,			/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	(reprfunc)float_str,			/* tp_str */
 | 
						(reprfunc)float_str,			/* tp_str */
 | 
				
			||||||
	0,			/*tp_getattro*/
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_CHECKTYPES	/*tp_flags*/
 | 
						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
 | 
					void
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,6 @@ static struct memberlist frame_memberlist[] = {
 | 
				
			||||||
	{"f_code",	T_OBJECT,	OFF(f_code),	RO},
 | 
						{"f_code",	T_OBJECT,	OFF(f_code),	RO},
 | 
				
			||||||
	{"f_builtins",	T_OBJECT,	OFF(f_builtins),RO},
 | 
						{"f_builtins",	T_OBJECT,	OFF(f_builtins),RO},
 | 
				
			||||||
	{"f_globals",	T_OBJECT,	OFF(f_globals),	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_lasti",	T_INT,		OFF(f_lasti),	RO},
 | 
				
			||||||
	{"f_lineno",	T_INT,		OFF(f_lineno),	RO},
 | 
						{"f_lineno",	T_INT,		OFF(f_lineno),	RO},
 | 
				
			||||||
	{"f_restricted",T_INT,		OFF(f_restricted),RO},
 | 
						{"f_restricted",T_INT,		OFF(f_restricted),RO},
 | 
				
			||||||
| 
						 | 
					@ -27,18 +26,17 @@ static struct memberlist frame_memberlist[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
frame_getattr(PyFrameObject *f, char *name)
 | 
					frame_getlocals(PyFrameObject *f, void *closure)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (strcmp(name, "f_locals") == 0)
 | 
					 | 
				
			||||||
	PyFrame_FastToLocals(f);
 | 
						PyFrame_FastToLocals(f);
 | 
				
			||||||
	return PyMember_Get((char *)f, frame_memberlist, name);
 | 
						Py_INCREF(f->f_locals);
 | 
				
			||||||
 | 
						return f->f_locals;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static struct getsetlist frame_getsetlist[] = {
 | 
				
			||||||
frame_setattr(PyFrameObject *f, char *name, PyObject *value)
 | 
						{"f_locals",	(getter)frame_getlocals, NULL, NULL},
 | 
				
			||||||
{
 | 
						{0}
 | 
				
			||||||
	return PyMember_Set((char *)f, frame_memberlist, name, value);
 | 
					};
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Stack frames are allocated and deallocated at a considerable rate.
 | 
					/* Stack frames are allocated and deallocated at a considerable rate.
 | 
				
			||||||
   In an attempt to improve the speed of function calls, we maintain a
 | 
					   In an attempt to improve the speed of function calls, we maintain a
 | 
				
			||||||
| 
						 | 
					@ -177,8 +175,8 @@ PyTypeObject PyFrame_Type = {
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	(destructor)frame_dealloc, 		/* tp_dealloc */
 | 
						(destructor)frame_dealloc, 		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	(getattrfunc)frame_getattr, 		/* tp_getattr */
 | 
						0, 					/* tp_getattr */
 | 
				
			||||||
	(setattrfunc)frame_setattr, 		/* tp_setattr */
 | 
						0,			 		/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	0,					/* tp_repr */
 | 
						0,					/* tp_repr */
 | 
				
			||||||
	0,					/* tp_as_number */
 | 
						0,					/* tp_as_number */
 | 
				
			||||||
| 
						 | 
					@ -187,13 +185,22 @@ PyTypeObject PyFrame_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						PyObject_GenericSetAttr,		/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
	0,             				/* tp_doc */
 | 
						0,             				/* tp_doc */
 | 
				
			||||||
 	(traverseproc)frame_traverse,		/* tp_traverse */
 | 
					 	(traverseproc)frame_traverse,		/* tp_traverse */
 | 
				
			||||||
	(inquiry)frame_clear,			/* tp_clear */
 | 
						(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 *
 | 
					PyFrameObject *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Python.h"
 | 
					#include "Python.h"
 | 
				
			||||||
#include "compile.h"
 | 
					#include "compile.h"
 | 
				
			||||||
 | 
					#include "eval.h"
 | 
				
			||||||
#include "structmember.h"
 | 
					#include "structmember.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
| 
						 | 
					@ -141,9 +142,8 @@ static struct memberlist func_memberlist[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
func_getattro(PyFunctionObject *op, PyObject *name)
 | 
					func_getattro(PyObject *op, PyObject *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PyObject *rtn;
 | 
					 | 
				
			||||||
	char *sname = PyString_AsString(name);
 | 
						char *sname = PyString_AsString(name);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (sname[0] != '_' && PyEval_GetRestricted()) {
 | 
						if (sname[0] != '_' && PyEval_GetRestricted()) {
 | 
				
			||||||
| 
						 | 
					@ -152,25 +152,12 @@ func_getattro(PyFunctionObject *op, PyObject *name)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* no API for PyMember_HasAttr() */
 | 
						return PyObject_GenericGetAttr(op, name);
 | 
				
			||||||
	rtn = PyMember_Get((char *)op, func_memberlist, sname);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (rtn == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
		PyErr_Clear();
 | 
					 | 
				
			||||||
		if (op->func_dict != NULL) {
 | 
					 | 
				
			||||||
			rtn = PyDict_GetItem(op->func_dict, name);
 | 
					 | 
				
			||||||
			Py_XINCREF(rtn);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (rtn == NULL)
 | 
					 | 
				
			||||||
			PyErr_SetObject(PyExc_AttributeError, name);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return rtn;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
func_setattro(PyFunctionObject *op, PyObject *name, PyObject *value)
 | 
					func_setattro(PyObject *op, PyObject *name, PyObject *value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rtn;
 | 
					 | 
				
			||||||
	char *sname = PyString_AsString(name);
 | 
						char *sname = PyString_AsString(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (PyEval_GetRestricted()) {
 | 
						if (PyEval_GetRestricted()) {
 | 
				
			||||||
| 
						 | 
					@ -216,31 +203,7 @@ func_setattro(PyFunctionObject *op, PyObject *name, PyObject *value)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtn = PyMember_Set((char *)op, func_memberlist, sname, value);
 | 
						return PyObject_GenericSetAttr(op, name, value);
 | 
				
			||||||
	if (rtn < 0 && PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
		PyErr_Clear();
 | 
					 | 
				
			||||||
		if (op->func_dict == NULL) {
 | 
					 | 
				
			||||||
			/* don't create the dict if we're deleting an
 | 
					 | 
				
			||||||
			 * attribute.  In that case, we know we'll get an
 | 
					 | 
				
			||||||
			 * AttributeError.
 | 
					 | 
				
			||||||
			 */
 | 
					 | 
				
			||||||
			if (value == NULL) {
 | 
					 | 
				
			||||||
				PyErr_SetString(PyExc_AttributeError, sname);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			op->func_dict = PyDict_New();
 | 
					 | 
				
			||||||
			if (op->func_dict == NULL)
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
                if (value == NULL)
 | 
					 | 
				
			||||||
			rtn = PyDict_DelItem(op->func_dict, name);
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
			rtn = PyDict_SetItem(op->func_dict, name, value);
 | 
					 | 
				
			||||||
		/* transform KeyError into AttributeError */
 | 
					 | 
				
			||||||
		if (rtn < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
 | 
					 | 
				
			||||||
			PyErr_SetString(PyExc_AttributeError, sname);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return rtn;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -314,6 +277,66 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					function_call(PyObject *func, PyObject *arg, PyObject *kw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *result;
 | 
				
			||||||
 | 
						PyObject *argdefs;
 | 
				
			||||||
 | 
						PyObject **d, **k;
 | 
				
			||||||
 | 
						int nk, nd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						argdefs = PyFunction_GET_DEFAULTS(func);
 | 
				
			||||||
 | 
						if (argdefs != NULL && PyTuple_Check(argdefs)) {
 | 
				
			||||||
 | 
							d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
 | 
				
			||||||
 | 
							nd = PyTuple_Size(argdefs);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							d = NULL;
 | 
				
			||||||
 | 
							nd = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (kw != NULL && PyDict_Check(kw)) {
 | 
				
			||||||
 | 
							int pos, i;
 | 
				
			||||||
 | 
							nk = PyDict_Size(kw);
 | 
				
			||||||
 | 
							k = PyMem_NEW(PyObject *, 2*nk);
 | 
				
			||||||
 | 
							if (k == NULL) {
 | 
				
			||||||
 | 
								PyErr_NoMemory();
 | 
				
			||||||
 | 
								Py_DECREF(arg);
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pos = i = 0;
 | 
				
			||||||
 | 
							while (PyDict_Next(kw, &pos, &k[i], &k[i+1]))
 | 
				
			||||||
 | 
								i += 2;
 | 
				
			||||||
 | 
							nk = i/2;
 | 
				
			||||||
 | 
							/* XXX This is broken if the caller deletes dict items! */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							k = NULL;
 | 
				
			||||||
 | 
							nk = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result = PyEval_EvalCodeEx(
 | 
				
			||||||
 | 
							(PyCodeObject *)PyFunction_GET_CODE(func),
 | 
				
			||||||
 | 
							PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
 | 
				
			||||||
 | 
							&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
 | 
				
			||||||
 | 
							k, nk, d, nd,
 | 
				
			||||||
 | 
							PyFunction_GET_CLOSURE(func));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (k != NULL)
 | 
				
			||||||
 | 
							PyMem_DEL(k);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Bind a function to an object */
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (obj == Py_None)
 | 
				
			||||||
 | 
							obj = NULL;
 | 
				
			||||||
 | 
						return PyMethod_New(func, obj, type);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyTypeObject PyFunction_Type = {
 | 
					PyTypeObject PyFunction_Type = {
 | 
				
			||||||
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
| 
						 | 
					@ -330,10 +353,10 @@ PyTypeObject PyFunction_Type = {
 | 
				
			||||||
	0,					/* tp_as_sequence */
 | 
						0,					/* tp_as_sequence */
 | 
				
			||||||
	0,					/* tp_as_mapping */
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,                                   /* tp_call */
 | 
						function_call,				/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	(getattrofunc)func_getattro,	     /* tp_getattro */
 | 
						func_getattro,				/* tp_getattro */
 | 
				
			||||||
	(setattrofunc)func_setattro,         /* tp_setattro */
 | 
						func_setattro,				/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
	0,					/* tp_doc */
 | 
						0,					/* tp_doc */
 | 
				
			||||||
| 
						 | 
					@ -341,4 +364,237 @@ PyTypeObject PyFunction_Type = {
 | 
				
			||||||
	0,					/* tp_clear */
 | 
						0,					/* tp_clear */
 | 
				
			||||||
	0,					/* tp_richcompare */
 | 
						0,					/* tp_richcompare */
 | 
				
			||||||
	offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
 | 
						offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
 | 
				
			||||||
 | 
						0,					/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						func_memberlist,			/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						func_descr_get,				/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
 | 
						offsetof(PyFunctionObject, func_dict),	/* tp_dictoffset */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Class method object */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* A class method receives the class as implicit first argument,
 | 
				
			||||||
 | 
					   just like an instance method receives the instance.
 | 
				
			||||||
 | 
					   To declare a class method, use this idiom:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     class C:
 | 
				
			||||||
 | 
					         def f(cls, arg1, arg2, ...): ...
 | 
				
			||||||
 | 
						 f = classmethod(f)
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   It can be called either on the class (e.g. C.f()) or on an instance
 | 
				
			||||||
 | 
					   (e.g. C().f()); the instance is ignored except for its class.
 | 
				
			||||||
 | 
					   If a class method is called for a derived class, the derived class
 | 
				
			||||||
 | 
					   object is passed as the implied first argument.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Class methods are different than C++ or Java static methods.
 | 
				
			||||||
 | 
					   If you want those, see static methods below.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						PyObject_HEAD
 | 
				
			||||||
 | 
						PyObject *cm_callable;
 | 
				
			||||||
 | 
					} classmethod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					cm_dealloc(classmethod *cm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Py_XDECREF(cm->cm_callable);
 | 
				
			||||||
 | 
						PyObject_DEL(cm);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						classmethod *cm = (classmethod *)self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cm->cm_callable == NULL) {
 | 
				
			||||||
 | 
							PyErr_SetString(PyExc_RuntimeError,
 | 
				
			||||||
 | 
									"uninitialized classmethod object");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					 	return PyMethod_New(cm->cm_callable,
 | 
				
			||||||
 | 
								    type, (PyObject *)(type->ob_type));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					cm_init(PyObject *self, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						classmethod *cm = (classmethod *)self;
 | 
				
			||||||
 | 
						PyObject *callable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, "O:callable", &callable))
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						Py_INCREF(callable);
 | 
				
			||||||
 | 
						cm->cm_callable = callable;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyTypeObject PyClassMethod_Type = {
 | 
				
			||||||
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						"classmethod",
 | 
				
			||||||
 | 
						sizeof(classmethod),
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						(destructor)cm_dealloc,			/* 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 */
 | 
				
			||||||
 | 
						PyObject_GenericGetAttr,		/* 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 */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						0,					/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						cm_descr_get,				/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
 | 
						0,					/* tp_dictoffset */
 | 
				
			||||||
 | 
						cm_init,				/* tp_init */
 | 
				
			||||||
 | 
						PyType_GenericAlloc,			/* tp_alloc */
 | 
				
			||||||
 | 
						PyType_GenericNew,			/* tp_new */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyClassMethod_New(PyObject *callable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						classmethod *cm = (classmethod *)
 | 
				
			||||||
 | 
							PyType_GenericAlloc(&PyClassMethod_Type, 0);
 | 
				
			||||||
 | 
						if (cm != NULL) {
 | 
				
			||||||
 | 
							Py_INCREF(callable);
 | 
				
			||||||
 | 
							cm->cm_callable = callable;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (PyObject *)cm;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Static method object */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* A static method does not receive an implicit first argument.
 | 
				
			||||||
 | 
					   To declare a static method, use this idiom:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     class C:
 | 
				
			||||||
 | 
					         def f(arg1, arg2, ...): ...
 | 
				
			||||||
 | 
						 f = staticmethod(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   It can be called either on the class (e.g. C.f()) or on an instance
 | 
				
			||||||
 | 
					   (e.g. C().f()); the instance is ignored except for its class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Static methods in Python are similar to those found in Java or C++.
 | 
				
			||||||
 | 
					   For a more advanced concept, see class methods above.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						PyObject_HEAD
 | 
				
			||||||
 | 
						PyObject *sm_callable;
 | 
				
			||||||
 | 
					} staticmethod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					sm_dealloc(staticmethod *sm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Py_XDECREF(sm->sm_callable);
 | 
				
			||||||
 | 
						PyObject_DEL(sm);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						staticmethod *sm = (staticmethod *)self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sm->sm_callable == NULL) {
 | 
				
			||||||
 | 
							PyErr_SetString(PyExc_RuntimeError,
 | 
				
			||||||
 | 
									"uninitialized staticmethod object");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						Py_INCREF(sm->sm_callable);
 | 
				
			||||||
 | 
						return sm->sm_callable;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					sm_init(PyObject *self, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						staticmethod *sm = (staticmethod *)self;
 | 
				
			||||||
 | 
						PyObject *callable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!PyArg_ParseTuple(args, "O:callable", &callable))
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						Py_INCREF(callable);
 | 
				
			||||||
 | 
						sm->sm_callable = callable;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyTypeObject PyStaticMethod_Type = {
 | 
				
			||||||
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						"staticmethod",
 | 
				
			||||||
 | 
						sizeof(staticmethod),
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						(destructor)sm_dealloc,			/* 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 */
 | 
				
			||||||
 | 
						PyObject_GenericGetAttr,		/* 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 */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						0,					/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						sm_descr_get,				/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
 | 
						0,					/* tp_dictoffset */
 | 
				
			||||||
 | 
						sm_init,				/* tp_init */
 | 
				
			||||||
 | 
						PyType_GenericAlloc,			/* tp_alloc */
 | 
				
			||||||
 | 
						PyType_GenericNew,			/* tp_new */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyStaticMethod_New(PyObject *callable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						staticmethod *sm = (staticmethod *)
 | 
				
			||||||
 | 
							PyType_GenericAlloc(&PyStaticMethod_Type, 0);
 | 
				
			||||||
 | 
						if (sm != NULL) {
 | 
				
			||||||
 | 
							Py_INCREF(callable);
 | 
				
			||||||
 | 
							sm->sm_callable = callable;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (PyObject *)sm;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -742,6 +742,41 @@ int_hex(PyIntObject *v)
 | 
				
			||||||
	return PyString_FromString(buf);
 | 
						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 = {
 | 
					static PyNumberMethods int_as_number = {
 | 
				
			||||||
	(binaryfunc)int_add,	/*nb_add*/
 | 
						(binaryfunc)int_add,	/*nb_add*/
 | 
				
			||||||
	(binaryfunc)int_sub,	/*nb_subtract*/
 | 
						(binaryfunc)int_sub,	/*nb_subtract*/
 | 
				
			||||||
| 
						 | 
					@ -797,10 +832,28 @@ PyTypeObject PyInt_Type = {
 | 
				
			||||||
	(hashfunc)int_hash,			/* tp_hash */
 | 
						(hashfunc)int_hash,			/* tp_hash */
 | 
				
			||||||
        0,					/* tp_call */
 | 
					        0,					/* tp_call */
 | 
				
			||||||
        0,					/* tp_str */
 | 
					        0,					/* tp_str */
 | 
				
			||||||
	0,			/*tp_getattro*/
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_CHECKTYPES	/*tp_flags*/
 | 
						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
 | 
					void
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,12 +96,6 @@ static PyMethodDef iter_methods[] = {
 | 
				
			||||||
	{NULL,		NULL}		/* sentinel */
 | 
						{NULL,		NULL}		/* sentinel */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
iter_getattr(seqiterobject *it, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return Py_FindMethod(iter_methods, (PyObject *)it, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PyTypeObject PySeqIter_Type = {
 | 
					PyTypeObject PySeqIter_Type = {
 | 
				
			||||||
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
	0,					/* ob_size */
 | 
						0,					/* ob_size */
 | 
				
			||||||
| 
						 | 
					@ -111,7 +105,7 @@ PyTypeObject PySeqIter_Type = {
 | 
				
			||||||
	/* methods */
 | 
						/* methods */
 | 
				
			||||||
	(destructor)iter_dealloc, 		/* tp_dealloc */
 | 
						(destructor)iter_dealloc, 		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	(getattrfunc)iter_getattr,		/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	0,					/* tp_repr */
 | 
						0,					/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -121,7 +115,7 @@ PyTypeObject PySeqIter_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
| 
						 | 
					@ -132,6 +126,13 @@ PyTypeObject PySeqIter_Type = {
 | 
				
			||||||
	0,					/* tp_weaklistoffset */
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
	(getiterfunc)iter_getiter,		/* tp_iter */
 | 
						(getiterfunc)iter_getiter,		/* tp_iter */
 | 
				
			||||||
	(iternextfunc)iter_iternext,		/* tp_iternext */
 | 
						(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 */
 | 
						{NULL,		NULL}		/* sentinel */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
calliter_getattr(calliterobject *it, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return Py_FindMethod(calliter_methods, (PyObject *)it, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
calliter_iternext(calliterobject *it)
 | 
					calliter_iternext(calliterobject *it)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -228,7 +223,7 @@ PyTypeObject PyCallIter_Type = {
 | 
				
			||||||
	/* methods */
 | 
						/* methods */
 | 
				
			||||||
	(destructor)calliter_dealloc, 		/* tp_dealloc */
 | 
						(destructor)calliter_dealloc, 		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	(getattrfunc)calliter_getattr,		/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	0,					/* tp_repr */
 | 
						0,					/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -238,7 +233,7 @@ PyTypeObject PyCallIter_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
| 
						 | 
					@ -249,4 +244,11 @@ PyTypeObject PyCallIter_Type = {
 | 
				
			||||||
	0,					/* tp_weaklistoffset */
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
	(getiterfunc)iter_getiter,		/* tp_iter */
 | 
						(getiterfunc)iter_getiter,		/* tp_iter */
 | 
				
			||||||
	(iternextfunc)calliter_iternext,	/* tp_iternext */
 | 
						(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);
 | 
								Py_XDECREF(*p);
 | 
				
			||||||
		PyMem_DEL(recycle);
 | 
							PyMem_DEL(recycle);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (a->ob_size == 0 && a->ob_item != NULL) {
 | 
				
			||||||
 | 
							PyMem_FREE(a->ob_item);
 | 
				
			||||||
 | 
							a->ob_item = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
#undef b
 | 
					#undef b
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1289,16 +1293,18 @@ listsort(PyListObject *self, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	PyObject *compare = NULL;
 | 
						PyObject *compare = NULL;
 | 
				
			||||||
 | 
						PyTypeObject *savetype;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args != NULL) {
 | 
						if (args != NULL) {
 | 
				
			||||||
		if (!PyArg_ParseTuple(args, "|O:sort", &compare))
 | 
							if (!PyArg_ParseTuple(args, "|O:sort", &compare))
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						savetype = self->ob_type;
 | 
				
			||||||
	self->ob_type = &immutable_list_type;
 | 
						self->ob_type = &immutable_list_type;
 | 
				
			||||||
	err = samplesortslice(self->ob_item,
 | 
						err = samplesortslice(self->ob_item,
 | 
				
			||||||
			      self->ob_item + self->ob_size,
 | 
								      self->ob_item + self->ob_size,
 | 
				
			||||||
			      compare);
 | 
								      compare);
 | 
				
			||||||
	self->ob_type = &PyList_Type;
 | 
						self->ob_type = savetype;
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	Py_INCREF(Py_None);
 | 
						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);
 | 
						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[] =
 | 
					static char append_doc[] =
 | 
				
			||||||
"L.append(object) -- append object to end";
 | 
					"L.append(object) -- append object to end";
 | 
				
			||||||
static char extend_doc[] =
 | 
					static char extend_doc[] =
 | 
				
			||||||
| 
						 | 
					@ -1573,12 +1673,6 @@ static PyMethodDef list_methods[] = {
 | 
				
			||||||
	{NULL,		NULL}		/* sentinel */
 | 
						{NULL,		NULL}		/* sentinel */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
list_getattr(PyListObject *f, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return Py_FindMethod(list_methods, (PyObject *)f, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PySequenceMethods list_as_sequence = {
 | 
					static PySequenceMethods list_as_sequence = {
 | 
				
			||||||
	(inquiry)list_length,			/* sq_length */
 | 
						(inquiry)list_length,			/* sq_length */
 | 
				
			||||||
	(binaryfunc)list_concat,		/* sq_concat */
 | 
						(binaryfunc)list_concat,		/* sq_concat */
 | 
				
			||||||
| 
						 | 
					@ -1592,6 +1686,10 @@ static PySequenceMethods list_as_sequence = {
 | 
				
			||||||
	(intargfunc)list_inplace_repeat,	/* sq_inplace_repeat */
 | 
						(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 = {
 | 
					PyTypeObject PyList_Type = {
 | 
				
			||||||
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
| 
						 | 
					@ -1600,7 +1698,7 @@ PyTypeObject PyList_Type = {
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	(destructor)list_dealloc,		/* tp_dealloc */
 | 
						(destructor)list_dealloc,		/* tp_dealloc */
 | 
				
			||||||
	(printfunc)list_print,			/* tp_print */
 | 
						(printfunc)list_print,			/* tp_print */
 | 
				
			||||||
	(getattrfunc)list_getattr,		/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	(reprfunc)list_repr,			/* tp_repr */
 | 
						(reprfunc)list_repr,			/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -1610,14 +1708,29 @@ PyTypeObject PyList_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC |
 | 
				
			||||||
 	0,					/* tp_doc */
 | 
							Py_TPFLAGS_BASETYPE,		/* tp_flags */
 | 
				
			||||||
 | 
					 	list_doc,				/* tp_doc */
 | 
				
			||||||
 	(traverseproc)list_traverse,		/* tp_traverse */
 | 
					 	(traverseproc)list_traverse,		/* tp_traverse */
 | 
				
			||||||
 	(inquiry)list_clear,			/* tp_clear */
 | 
					 	(inquiry)list_clear,			/* tp_clear */
 | 
				
			||||||
	list_richcompare,			/* tp_richcompare */
 | 
						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 */
 | 
						{NULL,		NULL}		/* sentinel */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
immutable_list_getattr(PyListObject *f, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return Py_FindMethod(immutable_list_methods, (PyObject *)f, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
immutable_list_ass(void)
 | 
					immutable_list_ass(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1678,7 +1785,7 @@ static PyTypeObject immutable_list_type = {
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	0, /* Cannot happen */			/* tp_dealloc */
 | 
						0, /* Cannot happen */			/* tp_dealloc */
 | 
				
			||||||
	(printfunc)list_print,			/* tp_print */
 | 
						(printfunc)list_print,			/* tp_print */
 | 
				
			||||||
	(getattrfunc)immutable_list_getattr,	/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	0, /* Won't be called */		/* tp_compare */
 | 
						0, /* Won't be called */		/* tp_compare */
 | 
				
			||||||
	(reprfunc)list_repr,			/* tp_repr */
 | 
						(reprfunc)list_repr,			/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -1688,13 +1795,24 @@ static PyTypeObject immutable_list_type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
 	0,					/* tp_doc */
 | 
					 	list_doc,				/* tp_doc */
 | 
				
			||||||
 	(traverseproc)list_traverse,		/* tp_traverse */
 | 
					 	(traverseproc)list_traverse,		/* tp_traverse */
 | 
				
			||||||
	0,					/* tp_clear */
 | 
						0,					/* tp_clear */
 | 
				
			||||||
	list_richcompare,			/* tp_richcompare */
 | 
						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! */
 | 
						/* NOTE: This is *not* the standard list_type struct! */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2031,6 +2031,43 @@ long_hex(PyObject *v)
 | 
				
			||||||
	return long_format(v, 16, 1);
 | 
						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 = {
 | 
					static PyNumberMethods long_as_number = {
 | 
				
			||||||
	(binaryfunc)	long_add,	/*nb_add*/
 | 
						(binaryfunc)	long_add,	/*nb_add*/
 | 
				
			||||||
	(binaryfunc)	long_sub,	/*nb_subtract*/
 | 
						(binaryfunc)	long_sub,	/*nb_subtract*/
 | 
				
			||||||
| 
						 | 
					@ -2070,10 +2107,10 @@ static PyNumberMethods long_as_number = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyTypeObject PyLong_Type = {
 | 
					PyTypeObject PyLong_Type = {
 | 
				
			||||||
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
	0,
 | 
						0,					/* ob_size */
 | 
				
			||||||
	"long int",
 | 
						"long",					/* tp_name */
 | 
				
			||||||
	sizeof(PyLongObject) - sizeof(digit),
 | 
						sizeof(PyLongObject) - sizeof(digit),	/* tp_basicsize */
 | 
				
			||||||
	sizeof(digit),
 | 
						sizeof(digit),				/* tp_itemsize */
 | 
				
			||||||
	(destructor)long_dealloc,		/* tp_dealloc */
 | 
						(destructor)long_dealloc,		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	0,					/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
| 
						 | 
					@ -2086,8 +2123,26 @@ PyTypeObject PyLong_Type = {
 | 
				
			||||||
	(hashfunc)long_hash,			/* tp_hash */
 | 
						(hashfunc)long_hash,			/* tp_hash */
 | 
				
			||||||
        0,              			/* tp_call */
 | 
					        0,              			/* tp_call */
 | 
				
			||||||
        (reprfunc)long_str,			/* tp_str */
 | 
					        (reprfunc)long_str,			/* tp_str */
 | 
				
			||||||
	0,				/*tp_getattro*/
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_CHECKTYPES		/*tp_flags*/
 | 
						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 "Python.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "token.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyCFunctionObject *free_list = NULL;
 | 
					static PyCFunctionObject *free_list = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
| 
						 | 
					@ -69,6 +67,23 @@ meth_dealloc(PyCFunctionObject *m)
 | 
				
			||||||
	free_list = 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
 | 
					static int
 | 
				
			||||||
meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
 | 
					meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -79,19 +94,8 @@ meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					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;
 | 
						PyObject *self;
 | 
				
			||||||
	if (PyEval_GetRestricted()) {
 | 
						if (PyEval_GetRestricted()) {
 | 
				
			||||||
		PyErr_SetString(PyExc_RuntimeError,
 | 
							PyErr_SetString(PyExc_RuntimeError,
 | 
				
			||||||
| 
						 | 
					@ -104,13 +108,13 @@ meth_getattr(PyCFunctionObject *m, char *name)
 | 
				
			||||||
	Py_INCREF(self);
 | 
						Py_INCREF(self);
 | 
				
			||||||
	return self;
 | 
						return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
	if (strcmp(name, "__members__") == 0) {
 | 
					
 | 
				
			||||||
		return Py_BuildValue("[sss]",
 | 
					static struct getsetlist meth_getsets [] = {
 | 
				
			||||||
				     "__doc__", "__name__", "__self__");
 | 
						{"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
 | 
				
			||||||
	}
 | 
						{"__name__", (getter)meth_get__name__, NULL, NULL},
 | 
				
			||||||
	PyErr_SetString(PyExc_AttributeError, name);
 | 
						{"__self__", (getter)meth_get__self__, NULL, NULL},
 | 
				
			||||||
	return NULL;
 | 
						{0}
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
meth_repr(PyCFunctionObject *m)
 | 
					meth_repr(PyCFunctionObject *m)
 | 
				
			||||||
| 
						 | 
					@ -159,6 +163,41 @@ meth_hash(PyCFunctionObject *a)
 | 
				
			||||||
	return x;
 | 
						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 = {
 | 
					PyTypeObject PyCFunction_Type = {
 | 
				
			||||||
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
| 
						 | 
					@ -167,7 +206,7 @@ PyTypeObject PyCFunction_Type = {
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	(destructor)meth_dealloc, 		/* tp_dealloc */
 | 
						(destructor)meth_dealloc, 		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	(getattrfunc)meth_getattr,		/* tp_getattr */
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	(cmpfunc)meth_compare,			/* tp_compare */
 | 
						(cmpfunc)meth_compare,			/* tp_compare */
 | 
				
			||||||
	(reprfunc)meth_repr,			/* tp_repr */
 | 
						(reprfunc)meth_repr,			/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -175,14 +214,24 @@ PyTypeObject PyCFunction_Type = {
 | 
				
			||||||
	0,					/* tp_as_sequence */
 | 
						0,					/* tp_as_sequence */
 | 
				
			||||||
	0,					/* tp_as_mapping */
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
	(hashfunc)meth_hash,			/* tp_hash */
 | 
						(hashfunc)meth_hash,			/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						meth_call,				/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
 	0,					/* tp_doc */
 | 
					 	0,					/* tp_doc */
 | 
				
			||||||
 	(traverseproc)meth_traverse,		/* tp_traverse */
 | 
					 	(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 */
 | 
					/* List all methods in a chain -- helper for findmethodinchain */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,12 +2,18 @@
 | 
				
			||||||
/* Module object implementation */
 | 
					/* Module object implementation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Python.h"
 | 
					#include "Python.h"
 | 
				
			||||||
 | 
					#include "structmember.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	PyObject_HEAD
 | 
						PyObject_HEAD
 | 
				
			||||||
	PyObject *md_dict;
 | 
						PyObject *md_dict;
 | 
				
			||||||
} PyModuleObject;
 | 
					} PyModuleObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct memberlist module_members[] = {
 | 
				
			||||||
 | 
						{"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
 | 
				
			||||||
 | 
						{0}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
PyModule_New(char *name)
 | 
					PyModule_New(char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -128,6 +134,15 @@ _PyModule_Clear(PyObject *m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Methods */
 | 
					/* Methods */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					module_init(PyModuleObject *m, PyObject *args, PyObject *kw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m->md_dict = PyDict_New();
 | 
				
			||||||
 | 
						if (m->md_dict == NULL)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
module_dealloc(PyModuleObject *m)
 | 
					module_dealloc(PyModuleObject *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -161,59 +176,6 @@ module_repr(PyModuleObject *m)
 | 
				
			||||||
	return PyString_FromString(buf);
 | 
						return PyString_FromString(buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
module_getattro(PyModuleObject *m, PyObject *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *res;
 | 
					 | 
				
			||||||
	char *sname = PyString_AsString(name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (sname[0] == '_' && strcmp(sname, "__dict__") == 0) {
 | 
					 | 
				
			||||||
		Py_INCREF(m->md_dict);
 | 
					 | 
				
			||||||
		return m->md_dict;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	res = PyDict_GetItem(m->md_dict, name);
 | 
					 | 
				
			||||||
	if (res == NULL) {
 | 
					 | 
				
			||||||
		char *modname = PyModule_GetName((PyObject *)m);
 | 
					 | 
				
			||||||
		if (modname == NULL) {
 | 
					 | 
				
			||||||
			PyErr_Clear();
 | 
					 | 
				
			||||||
			modname = "?";
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		PyErr_Format(PyExc_AttributeError,
 | 
					 | 
				
			||||||
			     "'%.50s' module has no attribute '%.400s'",
 | 
					 | 
				
			||||||
			     modname, sname);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		Py_INCREF(res);
 | 
					 | 
				
			||||||
	return res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
module_setattro(PyModuleObject *m, PyObject *name, PyObject *v)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char *sname = PyString_AsString(name);
 | 
					 | 
				
			||||||
	if (sname[0] == '_' && strcmp(sname, "__dict__") == 0) {
 | 
					 | 
				
			||||||
		PyErr_SetString(PyExc_TypeError,
 | 
					 | 
				
			||||||
				"read-only special attribute");
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (v == NULL) {
 | 
					 | 
				
			||||||
		int rv = PyDict_DelItem(m->md_dict, name);
 | 
					 | 
				
			||||||
		if (rv < 0) {
 | 
					 | 
				
			||||||
			char *modname = PyModule_GetName((PyObject *)m);
 | 
					 | 
				
			||||||
			if (modname == NULL) {
 | 
					 | 
				
			||||||
				PyErr_Clear();
 | 
					 | 
				
			||||||
				modname = "?";
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			PyErr_Format(PyExc_AttributeError,
 | 
					 | 
				
			||||||
				     "'%.50s' module has no attribute '%.400s'",
 | 
					 | 
				
			||||||
				     modname, sname);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return rv;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		return PyDict_SetItem(m->md_dict, name, v);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* We only need a traverse function, no clear function: If the module
 | 
					/* We only need a traverse function, no clear function: If the module
 | 
				
			||||||
   is in a cycle, md_dict will be cleared as well, which will break
 | 
					   is in a cycle, md_dict will be cleared as well, which will break
 | 
				
			||||||
   the cycle. */
 | 
					   the cycle. */
 | 
				
			||||||
| 
						 | 
					@ -243,10 +205,27 @@ PyTypeObject PyModule_Type = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	(getattrofunc)module_getattro,		/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	(setattrofunc)module_setattro,		/* tp_setattro */
 | 
						PyObject_GenericSetAttr,		/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC |
 | 
				
			||||||
 | 
							Py_TPFLAGS_BASETYPE,		/* tp_flags */
 | 
				
			||||||
	0,					/* tp_doc */
 | 
						0,					/* tp_doc */
 | 
				
			||||||
	(traverseproc)module_traverse,		/* tp_traverse */
 | 
						(traverseproc)module_traverse,		/* tp_traverse */
 | 
				
			||||||
 | 
						0,					/* tp_clear */
 | 
				
			||||||
 | 
						0,					/* tp_richcompare */
 | 
				
			||||||
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
						0,					/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						module_members,				/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
 | 
						0,					/* tp_descr_get */
 | 
				
			||||||
 | 
						0,					/* tp_descr_set */
 | 
				
			||||||
 | 
						offsetof(PyModuleObject, md_dict),	/* tp_dictoffset */
 | 
				
			||||||
 | 
						(initproc)module_init,			/* tp_init */
 | 
				
			||||||
 | 
						PyType_GenericAlloc,			/* tp_alloc */
 | 
				
			||||||
 | 
						PyType_GenericNew,			/* tp_new */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										273
									
								
								Objects/object.c
									
										
									
									
									
								
							
							
						
						
									
										273
									
								
								Objects/object.c
									
										
									
									
									
								
							| 
						 | 
					@ -32,7 +32,7 @@ dump_counts(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (tp = type_list; tp; tp = tp->tp_next)
 | 
						for (tp = type_list; tp; tp = tp->tp_next)
 | 
				
			||||||
		fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n",
 | 
							fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n",
 | 
				
			||||||
			tp->tp_name, tp->tp_alloc, tp->tp_free,
 | 
								tp->tp_name, tp->tp_allocs, tp->tp_frees,
 | 
				
			||||||
			tp->tp_maxalloc);
 | 
								tp->tp_maxalloc);
 | 
				
			||||||
	fprintf(stderr, "fast tuple allocs: %d, empty: %d\n",
 | 
						fprintf(stderr, "fast tuple allocs: %d, empty: %d\n",
 | 
				
			||||||
		fast_tuple_allocs, tuple_zero_allocs);
 | 
							fast_tuple_allocs, tuple_zero_allocs);
 | 
				
			||||||
| 
						 | 
					@ -53,8 +53,8 @@ get_counts(void)
 | 
				
			||||||
	if (result == NULL)
 | 
						if (result == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	for (tp = type_list; tp; tp = tp->tp_next) {
 | 
						for (tp = type_list; tp; tp = tp->tp_next) {
 | 
				
			||||||
		v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_alloc,
 | 
							v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_allocs,
 | 
				
			||||||
				  tp->tp_free, tp->tp_maxalloc);
 | 
									  tp->tp_frees, tp->tp_maxalloc);
 | 
				
			||||||
		if (v == NULL) {
 | 
							if (v == NULL) {
 | 
				
			||||||
			Py_DECREF(result);
 | 
								Py_DECREF(result);
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
| 
						 | 
					@ -72,16 +72,16 @@ get_counts(void)
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
inc_count(PyTypeObject *tp)
 | 
					inc_count(PyTypeObject *tp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (tp->tp_alloc == 0) {
 | 
						if (tp->tp_allocs == 0) {
 | 
				
			||||||
		/* first time; insert in linked list */
 | 
							/* first time; insert in linked list */
 | 
				
			||||||
		if (tp->tp_next != NULL) /* sanity check */
 | 
							if (tp->tp_next != NULL) /* sanity check */
 | 
				
			||||||
			Py_FatalError("XXX inc_count sanity check");
 | 
								Py_FatalError("XXX inc_count sanity check");
 | 
				
			||||||
		tp->tp_next = type_list;
 | 
							tp->tp_next = type_list;
 | 
				
			||||||
		type_list = tp;
 | 
							type_list = tp;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tp->tp_alloc++;
 | 
						tp->tp_allocs++;
 | 
				
			||||||
	if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc)
 | 
						if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc)
 | 
				
			||||||
		tp->tp_maxalloc = tp->tp_alloc - tp->tp_free;
 | 
							tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,10 +93,8 @@ PyObject_Init(PyObject *op, PyTypeObject *tp)
 | 
				
			||||||
				"NULL object passed to PyObject_Init");
 | 
									"NULL object passed to PyObject_Init");
 | 
				
			||||||
		return op;
 | 
							return op;
 | 
				
			||||||
  	}
 | 
					  	}
 | 
				
			||||||
#ifdef WITH_CYCLE_GC
 | 
					 | 
				
			||||||
	if (PyType_IS_GC(tp))
 | 
						if (PyType_IS_GC(tp))
 | 
				
			||||||
		op = (PyObject *) PyObject_FROM_GC(op);
 | 
							op = (PyObject *) PyObject_FROM_GC(op);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	/* Any changes should be reflected in PyObject_INIT (objimpl.h) */
 | 
						/* Any changes should be reflected in PyObject_INIT (objimpl.h) */
 | 
				
			||||||
	op->ob_type = tp;
 | 
						op->ob_type = tp;
 | 
				
			||||||
	_Py_NewReference(op);
 | 
						_Py_NewReference(op);
 | 
				
			||||||
| 
						 | 
					@ -111,10 +109,8 @@ PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, int size)
 | 
				
			||||||
				"NULL object passed to PyObject_InitVar");
 | 
									"NULL object passed to PyObject_InitVar");
 | 
				
			||||||
		return op;
 | 
							return op;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#ifdef WITH_CYCLE_GC
 | 
					 | 
				
			||||||
	if (PyType_IS_GC(tp))
 | 
						if (PyType_IS_GC(tp))
 | 
				
			||||||
		op = (PyVarObject *) PyObject_FROM_GC(op);
 | 
							op = (PyVarObject *) PyObject_FROM_GC(op);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	/* Any changes should be reflected in PyObject_INIT_VAR */
 | 
						/* Any changes should be reflected in PyObject_INIT_VAR */
 | 
				
			||||||
	op->ob_size = size;
 | 
						op->ob_size = size;
 | 
				
			||||||
	op->ob_type = tp;
 | 
						op->ob_type = tp;
 | 
				
			||||||
| 
						 | 
					@ -129,10 +125,8 @@ _PyObject_New(PyTypeObject *tp)
 | 
				
			||||||
	op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp));
 | 
						op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp));
 | 
				
			||||||
	if (op == NULL)
 | 
						if (op == NULL)
 | 
				
			||||||
		return PyErr_NoMemory();
 | 
							return PyErr_NoMemory();
 | 
				
			||||||
#ifdef WITH_CYCLE_GC
 | 
					 | 
				
			||||||
	if (PyType_IS_GC(tp))
 | 
						if (PyType_IS_GC(tp))
 | 
				
			||||||
		op = (PyObject *) PyObject_FROM_GC(op);
 | 
							op = (PyObject *) PyObject_FROM_GC(op);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	return PyObject_INIT(op, tp);
 | 
						return PyObject_INIT(op, tp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,21 +137,17 @@ _PyObject_NewVar(PyTypeObject *tp, int size)
 | 
				
			||||||
	op = (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE(tp, size));
 | 
						op = (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE(tp, size));
 | 
				
			||||||
	if (op == NULL)
 | 
						if (op == NULL)
 | 
				
			||||||
		return (PyVarObject *)PyErr_NoMemory();
 | 
							return (PyVarObject *)PyErr_NoMemory();
 | 
				
			||||||
#ifdef WITH_CYCLE_GC
 | 
					 | 
				
			||||||
	if (PyType_IS_GC(tp))
 | 
						if (PyType_IS_GC(tp))
 | 
				
			||||||
		op = (PyVarObject *) PyObject_FROM_GC(op);
 | 
							op = (PyVarObject *) PyObject_FROM_GC(op);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	return PyObject_INIT_VAR(op, tp, size);
 | 
						return PyObject_INIT_VAR(op, tp, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
_PyObject_Del(PyObject *op)
 | 
					_PyObject_Del(PyObject *op)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef WITH_CYCLE_GC
 | 
					 | 
				
			||||||
	if (op && PyType_IS_GC(op->ob_type)) {
 | 
						if (op && PyType_IS_GC(op->ob_type)) {
 | 
				
			||||||
		op = (PyObject *) PyObject_AS_GC(op);
 | 
							op = (PyObject *) PyObject_AS_GC(op);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	PyObject_FREE(op);
 | 
						PyObject_FREE(op);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -994,28 +984,18 @@ PyObject_Hash(PyObject *v)
 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
PyObject_GetAttrString(PyObject *v, char *name)
 | 
					PyObject_GetAttrString(PyObject *v, char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (v->ob_type->tp_getattro != NULL) {
 | 
					 | 
				
			||||||
	PyObject *w, *res;
 | 
						PyObject *w, *res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (v->ob_type->tp_getattr != NULL)
 | 
				
			||||||
 | 
							return (*v->ob_type->tp_getattr)(v, name);
 | 
				
			||||||
	w = PyString_InternFromString(name);
 | 
						w = PyString_InternFromString(name);
 | 
				
			||||||
	if (w == NULL)
 | 
						if (w == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
		res = (*v->ob_type->tp_getattro)(v, w);
 | 
						res = PyObject_GetAttr(v, w);
 | 
				
			||||||
	Py_XDECREF(w);
 | 
						Py_XDECREF(w);
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (v->ob_type->tp_getattr == NULL) {
 | 
					 | 
				
			||||||
		PyErr_Format(PyExc_AttributeError,
 | 
					 | 
				
			||||||
			     "'%.50s' object has no attribute '%.400s'",
 | 
					 | 
				
			||||||
			     v->ob_type->tp_name,
 | 
					 | 
				
			||||||
			     name);
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		return (*v->ob_type->tp_getattr)(v, name);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
PyObject_HasAttrString(PyObject *v, char *name)
 | 
					PyObject_HasAttrString(PyObject *v, char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1031,34 +1011,24 @@ PyObject_HasAttrString(PyObject *v, char *name)
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
PyObject_SetAttrString(PyObject *v, char *name, PyObject *w)
 | 
					PyObject_SetAttrString(PyObject *v, char *name, PyObject *w)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (v->ob_type->tp_setattro != NULL) {
 | 
					 | 
				
			||||||
	PyObject *s;
 | 
						PyObject *s;
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (v->ob_type->tp_setattr != NULL)
 | 
				
			||||||
 | 
							return (*v->ob_type->tp_setattr)(v, name, w);
 | 
				
			||||||
	s = PyString_InternFromString(name);
 | 
						s = PyString_InternFromString(name);
 | 
				
			||||||
	if (s == NULL)
 | 
						if (s == NULL)
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
		res = (*v->ob_type->tp_setattro)(v, s, w);
 | 
						res = PyObject_SetAttr(v, s, w);
 | 
				
			||||||
	Py_XDECREF(s);
 | 
						Py_XDECREF(s);
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (v->ob_type->tp_setattr == NULL) {
 | 
					 | 
				
			||||||
		if (v->ob_type->tp_getattr == NULL)
 | 
					 | 
				
			||||||
			PyErr_SetString(PyExc_TypeError,
 | 
					 | 
				
			||||||
				   "attribute-less object (assign or del)");
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			PyErr_SetString(PyExc_TypeError,
 | 
					 | 
				
			||||||
				   "object has read-only attributes");
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		return (*v->ob_type->tp_setattr)(v, name, w);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
PyObject_GetAttr(PyObject *v, PyObject *name)
 | 
					PyObject_GetAttr(PyObject *v, PyObject *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						PyTypeObject *tp = v->ob_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* The Unicode to string conversion is done here because the
 | 
						/* The Unicode to string conversion is done here because the
 | 
				
			||||||
	   existing tp_getattro slots expect a string object as name
 | 
						   existing tp_getattro slots expect a string object as name
 | 
				
			||||||
	   and we wouldn't want to break those. */
 | 
						   and we wouldn't want to break those. */
 | 
				
			||||||
| 
						 | 
					@ -1067,16 +1037,19 @@ PyObject_GetAttr(PyObject *v, PyObject *name)
 | 
				
			||||||
		if (name == NULL)
 | 
							if (name == NULL)
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PyString_Check(name)) {
 | 
						if (!PyString_Check(name)) {
 | 
				
			||||||
		PyErr_SetString(PyExc_TypeError,
 | 
							PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
				"attribute name must be string");
 | 
									"attribute name must be string");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (v->ob_type->tp_getattro != NULL)
 | 
						if (tp->tp_getattro != NULL)
 | 
				
			||||||
		return (*v->ob_type->tp_getattro)(v, name);
 | 
							return (*tp->tp_getattro)(v, name);
 | 
				
			||||||
	else
 | 
						if (tp->tp_getattr != NULL)
 | 
				
			||||||
		return PyObject_GetAttrString(v, PyString_AS_STRING(name));
 | 
							return (*tp->tp_getattr)(v, PyString_AS_STRING(name));
 | 
				
			||||||
 | 
						PyErr_Format(PyExc_AttributeError,
 | 
				
			||||||
 | 
							     "'%.50s' object has no attribute '%.400s'",
 | 
				
			||||||
 | 
							     tp->tp_name, PyString_AS_STRING(name));
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
| 
						 | 
					@ -1094,6 +1067,7 @@ PyObject_HasAttr(PyObject *v, PyObject *name)
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
 | 
					PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						PyTypeObject *tp = v->ob_type;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* The Unicode to string conversion is done here because the
 | 
						/* The Unicode to string conversion is done here because the
 | 
				
			||||||
| 
						 | 
					@ -1104,26 +1078,183 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
 | 
				
			||||||
		if (name == NULL)
 | 
							if (name == NULL)
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						else if (!PyString_Check(name)){
 | 
				
			||||||
 | 
							PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
 | 
									"attribute name must be string");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		Py_INCREF(name);
 | 
							Py_INCREF(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!PyString_Check(name)){
 | 
					 | 
				
			||||||
		PyErr_SetString(PyExc_TypeError,
 | 
					 | 
				
			||||||
				"attribute name must be string");
 | 
					 | 
				
			||||||
		err = -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
	PyString_InternInPlace(&name);
 | 
						PyString_InternInPlace(&name);
 | 
				
			||||||
		if (v->ob_type->tp_setattro != NULL)
 | 
						if (tp->tp_setattro != NULL) {
 | 
				
			||||||
			err = (*v->ob_type->tp_setattro)(v, name, value);
 | 
							err = (*tp->tp_setattro)(v, name, value);
 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			err = PyObject_SetAttrString(v, 
 | 
					 | 
				
			||||||
				        PyString_AS_STRING(name), value);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
		Py_DECREF(name);
 | 
							Py_DECREF(name);
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (tp->tp_setattr != NULL) {
 | 
				
			||||||
 | 
							err = (*tp->tp_setattr)(v, PyString_AS_STRING(name), value);
 | 
				
			||||||
 | 
							Py_DECREF(name);
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						Py_DECREF(name);
 | 
				
			||||||
 | 
						if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "'%.100s' object has no attributes "
 | 
				
			||||||
 | 
								     "(%s .%.100s)",
 | 
				
			||||||
 | 
								     tp->tp_name,
 | 
				
			||||||
 | 
								     value==NULL ? "del" : "assign to",
 | 
				
			||||||
 | 
								     PyString_AS_STRING(name));
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "'%.100s' object has only read-only attributes "
 | 
				
			||||||
 | 
								     "(%s .%.100s)",
 | 
				
			||||||
 | 
								     tp->tp_name,
 | 
				
			||||||
 | 
								     value==NULL ? "del" : "assign to",
 | 
				
			||||||
 | 
								     PyString_AS_STRING(name));
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Helper to get a pointer to an object's __dict__ slot, if any */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject **
 | 
				
			||||||
 | 
					_PyObject_GetDictPtr(PyObject *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#define PTRSIZE (sizeof(PyObject *))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						long dictoffset;
 | 
				
			||||||
 | 
						PyTypeObject *tp = obj->ob_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						dictoffset = tp->tp_dictoffset;
 | 
				
			||||||
 | 
						if (dictoffset == 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (dictoffset < 0) {
 | 
				
			||||||
 | 
							dictoffset += PyType_BASICSIZE(tp);
 | 
				
			||||||
 | 
							assert(dictoffset > 0); /* Sanity check */
 | 
				
			||||||
 | 
							if (tp->tp_itemsize > 0) {
 | 
				
			||||||
 | 
								int n = ((PyVarObject *)obj)->ob_size;
 | 
				
			||||||
 | 
								if (n > 0) {
 | 
				
			||||||
 | 
									dictoffset += tp->tp_itemsize * n;
 | 
				
			||||||
 | 
									/* Round up, if necessary */
 | 
				
			||||||
 | 
									if (tp->tp_itemsize % PTRSIZE != 0) {
 | 
				
			||||||
 | 
										dictoffset += PTRSIZE - 1;
 | 
				
			||||||
 | 
										dictoffset /= PTRSIZE;
 | 
				
			||||||
 | 
										dictoffset *= PTRSIZE;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (PyObject **) ((char *)obj + dictoffset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyObject *
 | 
				
			||||||
 | 
					PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyTypeObject *tp = obj->ob_type;
 | 
				
			||||||
 | 
						PyObject *descr;
 | 
				
			||||||
 | 
						descrgetfunc f;
 | 
				
			||||||
 | 
						PyObject **dictptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tp->tp_dict == NULL) {
 | 
				
			||||||
 | 
							if (PyType_InitDict(tp) < 0)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						descr = _PyType_Lookup(tp, name);
 | 
				
			||||||
 | 
						f = NULL;
 | 
				
			||||||
 | 
						if (descr != NULL) {
 | 
				
			||||||
 | 
							f = descr->ob_type->tp_descr_get;
 | 
				
			||||||
 | 
							if (f != NULL && PyDescr_IsData(descr))
 | 
				
			||||||
 | 
								return f(descr, obj, (PyObject *)obj->ob_type);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dictptr = _PyObject_GetDictPtr(obj);
 | 
				
			||||||
 | 
						if (dictptr != NULL) {
 | 
				
			||||||
 | 
							PyObject *dict = *dictptr;
 | 
				
			||||||
 | 
							if (dict != NULL) {
 | 
				
			||||||
 | 
								PyObject *res = PyDict_GetItem(dict, name);
 | 
				
			||||||
 | 
								if (res != NULL) {
 | 
				
			||||||
 | 
									Py_INCREF(res);
 | 
				
			||||||
 | 
									return res;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (f != NULL)
 | 
				
			||||||
 | 
							return f(descr, obj, (PyObject *)obj->ob_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (descr != NULL) {
 | 
				
			||||||
 | 
							Py_INCREF(descr);
 | 
				
			||||||
 | 
							return descr;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PyErr_Format(PyExc_AttributeError,
 | 
				
			||||||
 | 
							     "'%.50s' object has no attribute '%.400s'",
 | 
				
			||||||
 | 
							     tp->tp_name, PyString_AS_STRING(name));
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyTypeObject *tp = obj->ob_type;
 | 
				
			||||||
 | 
						PyObject *descr;
 | 
				
			||||||
 | 
						descrsetfunc f;
 | 
				
			||||||
 | 
						PyObject **dictptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tp->tp_dict == NULL) {
 | 
				
			||||||
 | 
							if (PyType_InitDict(tp) < 0)
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						descr = _PyType_Lookup(tp, name);
 | 
				
			||||||
 | 
						f = NULL;
 | 
				
			||||||
 | 
						if (descr != NULL) {
 | 
				
			||||||
 | 
							f = descr->ob_type->tp_descr_set;
 | 
				
			||||||
 | 
							if (f != NULL && PyDescr_IsData(descr))
 | 
				
			||||||
 | 
								return f(descr, obj, value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dictptr = _PyObject_GetDictPtr(obj);
 | 
				
			||||||
 | 
						if (dictptr != NULL) {
 | 
				
			||||||
 | 
							PyObject *dict = *dictptr;
 | 
				
			||||||
 | 
							if (dict == NULL && value != NULL) {
 | 
				
			||||||
 | 
								dict = PyDict_New();
 | 
				
			||||||
 | 
								if (dict == NULL)
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								*dictptr = dict;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (dict != NULL) {
 | 
				
			||||||
 | 
								int res;
 | 
				
			||||||
 | 
								if (value == NULL)
 | 
				
			||||||
 | 
									res = PyDict_DelItem(dict, name);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									res = PyDict_SetItem(dict, name, value);
 | 
				
			||||||
 | 
								if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
 | 
				
			||||||
 | 
									PyErr_SetObject(PyExc_AttributeError, name);
 | 
				
			||||||
 | 
								return res;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (f != NULL)
 | 
				
			||||||
 | 
							return f(descr, obj, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (descr == NULL) {
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_AttributeError,
 | 
				
			||||||
 | 
								     "'%.50s' object has no attribute '%.400s'",
 | 
				
			||||||
 | 
								     tp->tp_name, PyString_AS_STRING(name));
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PyErr_Format(PyExc_AttributeError,
 | 
				
			||||||
 | 
							     "'%.50s' object attribute '%.400s' is read-only",
 | 
				
			||||||
 | 
							     tp->tp_name, PyString_AS_STRING(name));
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Test a value used as condition, e.g., in a for or if statement.
 | 
					/* Test a value used as condition, e.g., in a for or if statement.
 | 
				
			||||||
   Return -1 if an error occurred */
 | 
					   Return -1 if an error occurred */
 | 
				
			||||||
| 
						 | 
					@ -1218,12 +1349,6 @@ PyCallable_Check(PyObject *x)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (x == NULL)
 | 
						if (x == NULL)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (x->ob_type->tp_call != NULL ||
 | 
					 | 
				
			||||||
	    PyFunction_Check(x) ||
 | 
					 | 
				
			||||||
	    PyMethod_Check(x) ||
 | 
					 | 
				
			||||||
	    PyCFunction_Check(x) ||
 | 
					 | 
				
			||||||
	    PyClass_Check(x))
 | 
					 | 
				
			||||||
		return 1;
 | 
					 | 
				
			||||||
	if (PyInstance_Check(x)) {
 | 
						if (PyInstance_Check(x)) {
 | 
				
			||||||
		PyObject *call = PyObject_GetAttrString(x, "__call__");
 | 
							PyObject *call = PyObject_GetAttrString(x, "__call__");
 | 
				
			||||||
		if (call == NULL) {
 | 
							if (call == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -1235,7 +1360,9 @@ PyCallable_Check(PyObject *x)
 | 
				
			||||||
		Py_DECREF(call);
 | 
							Py_DECREF(call);
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						else {
 | 
				
			||||||
 | 
							return x->ob_type->tp_call != NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1365,7 +1492,7 @@ _Py_ForgetReference(register PyObject *op)
 | 
				
			||||||
	op->_ob_prev->_ob_next = op->_ob_next;
 | 
						op->_ob_prev->_ob_next = op->_ob_next;
 | 
				
			||||||
	op->_ob_next = op->_ob_prev = NULL;
 | 
						op->_ob_next = op->_ob_prev = NULL;
 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
					#ifdef COUNT_ALLOCS
 | 
				
			||||||
	op->ob_type->tp_free++;
 | 
						op->ob_type->tp_frees++;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -322,10 +322,22 @@ PyTypeObject PyRange_Type = {
 | 
				
			||||||
	0,					/*tp_hash*/
 | 
						0,					/*tp_hash*/
 | 
				
			||||||
	0,					/*tp_call*/
 | 
						0,					/*tp_call*/
 | 
				
			||||||
	0,					/*tp_str*/
 | 
						0,					/*tp_str*/
 | 
				
			||||||
	0,			/*tp_getattro*/
 | 
						PyObject_GenericGetAttr,		/*tp_getattro*/
 | 
				
			||||||
	0,					/*tp_setattro*/
 | 
						0,					/*tp_setattro*/
 | 
				
			||||||
	0,					/*tp_as_buffer*/
 | 
						0,					/*tp_as_buffer*/
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT,			/*tp_flags*/
 | 
						Py_TPFLAGS_DEFAULT,			/*tp_flags*/
 | 
				
			||||||
 | 
						0,					/* 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 */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef WARN
 | 
					#undef WARN
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ this type and there is exactly one in existence.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Python.h"
 | 
					#include "Python.h"
 | 
				
			||||||
 | 
					#include "structmember.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
ellipsis_repr(PyObject *op)
 | 
					ellipsis_repr(PyObject *op)
 | 
				
			||||||
| 
						 | 
					@ -128,32 +129,12 @@ slice_repr(PySliceObject *r)
 | 
				
			||||||
	return s;
 | 
						return s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct memberlist slice_members[] = {
 | 
				
			||||||
static PyObject *slice_getattr(PySliceObject *self, char *name)
 | 
						{"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
 | 
				
			||||||
{
 | 
						{"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
 | 
				
			||||||
	PyObject *ret;
 | 
						{"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},
 | 
				
			||||||
  
 | 
						{0}
 | 
				
			||||||
	ret = NULL;
 | 
					};
 | 
				
			||||||
	if (strcmp(name, "start") == 0) {
 | 
					 | 
				
			||||||
		ret = self->start;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (strcmp(name, "stop") == 0) {
 | 
					 | 
				
			||||||
		ret = self->stop;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (strcmp(name, "step") == 0) {
 | 
					 | 
				
			||||||
		ret = self->step;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (strcmp(name, "__members__") == 0) {
 | 
					 | 
				
			||||||
		return Py_BuildValue("[sss]",
 | 
					 | 
				
			||||||
				     "start", "stop", "step");
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		PyErr_SetString(PyExc_AttributeError, name);
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	Py_INCREF(ret);
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
slice_compare(PySliceObject *v, PySliceObject *w)
 | 
					slice_compare(PySliceObject *v, PySliceObject *w)
 | 
				
			||||||
| 
						 | 
					@ -184,11 +165,30 @@ PyTypeObject PySlice_Type = {
 | 
				
			||||||
	0,			/* Item size for varobject */
 | 
						0,			/* Item size for varobject */
 | 
				
			||||||
	(destructor)slice_dealloc,		/* tp_dealloc */
 | 
						(destructor)slice_dealloc,		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	(getattrfunc)slice_getattr, /*tp_getattr*/
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	(cmpfunc)slice_compare, 		/* tp_compare */
 | 
						(cmpfunc)slice_compare, 		/* tp_compare */
 | 
				
			||||||
	(reprfunc)slice_repr,   		/* tp_repr */
 | 
						(reprfunc)slice_repr,   		/* tp_repr */
 | 
				
			||||||
	0,					/* tp_as_number */
 | 
						0,					/* tp_as_number */
 | 
				
			||||||
	0,	    				/* tp_as_sequence */
 | 
						0,	    				/* tp_as_sequence */
 | 
				
			||||||
	0,					/* tp_as_mapping */
 | 
						0,					/* tp_as_mapping */
 | 
				
			||||||
 | 
						0,					/* tp_hash */
 | 
				
			||||||
 | 
						0,					/* tp_call */
 | 
				
			||||||
 | 
						0,					/* tp_str */
 | 
				
			||||||
 | 
						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_richcompare */
 | 
				
			||||||
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
						0,					/* tp_iter */
 | 
				
			||||||
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						0,					/* tp_methods */
 | 
				
			||||||
 | 
						slice_members,				/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2522,21 +2522,34 @@ string_methods[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
string_getattr(PyStringObject *s, char *name)
 | 
					string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return Py_FindMethod(string_methods, (PyObject*)s, name);
 | 
						PyObject *x = NULL;
 | 
				
			||||||
 | 
						static char *kwlist[] = {"object", 0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(type == &PyString_Type);
 | 
				
			||||||
 | 
						if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:str", kwlist, &x))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (x == NULL)
 | 
				
			||||||
 | 
							return PyString_FromString("");
 | 
				
			||||||
 | 
						return PyObject_Str(x);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char string_doc[] =
 | 
				
			||||||
 | 
					"str(object) -> string\n\
 | 
				
			||||||
 | 
					\n\
 | 
				
			||||||
 | 
					Return a nice string representation of the object.\n\
 | 
				
			||||||
 | 
					If the argument is a string, the return value is the same object.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyTypeObject PyString_Type = {
 | 
					PyTypeObject PyString_Type = {
 | 
				
			||||||
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	"string",
 | 
						"str",
 | 
				
			||||||
	sizeof(PyStringObject),
 | 
						sizeof(PyStringObject),
 | 
				
			||||||
	sizeof(char),
 | 
						sizeof(char),
 | 
				
			||||||
 	(destructor)string_dealloc, 		/* tp_dealloc */
 | 
					 	(destructor)string_dealloc, 		/* tp_dealloc */
 | 
				
			||||||
	(printfunc)string_print, 		/* tp_print */
 | 
						(printfunc)string_print, 		/* tp_print */
 | 
				
			||||||
	(getattrfunc)string_getattr,		/*tp_getattr*/
 | 
						0,					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	(reprfunc)string_repr, 			/* tp_repr */
 | 
						(reprfunc)string_repr, 			/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -2546,17 +2559,28 @@ PyTypeObject PyString_Type = {
 | 
				
			||||||
	(hashfunc)string_hash, 			/* tp_hash */
 | 
						(hashfunc)string_hash, 			/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	(reprfunc)string_str,			/* tp_str */
 | 
						(reprfunc)string_str,			/* tp_str */
 | 
				
			||||||
	0,		/*tp_getattro*/
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	&string_as_buffer,			/* tp_as_buffer */
 | 
						&string_as_buffer,			/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
				
			||||||
	0,		/*tp_doc*/
 | 
						string_doc,				/* tp_doc */
 | 
				
			||||||
	0,					/* tp_traverse */
 | 
						0,					/* tp_traverse */
 | 
				
			||||||
	0,					/* tp_clear */
 | 
						0,					/* tp_clear */
 | 
				
			||||||
	(richcmpfunc)string_richcompare,	/* tp_richcompare */
 | 
						(richcmpfunc)string_richcompare,	/* tp_richcompare */
 | 
				
			||||||
	0,					/* tp_weaklistoffset */
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
	0,					/* tp_iter */
 | 
						0,					/* tp_iter */
 | 
				
			||||||
	0,					/* tp_iternext */
 | 
						0,					/* tp_iternext */
 | 
				
			||||||
 | 
						string_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 */
 | 
				
			||||||
 | 
						0,					/* tp_init */
 | 
				
			||||||
 | 
						0,					/* tp_alloc */
 | 
				
			||||||
 | 
						string_new,				/* tp_new */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -480,6 +480,28 @@ tuplerichcompare(PyObject *v, PyObject *w, int op)
 | 
				
			||||||
	return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
 | 
						return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PyObject *arg = NULL;
 | 
				
			||||||
 | 
						static char *kwlist[] = {"sequence", 0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(type == &PyTuple_Type);
 | 
				
			||||||
 | 
						if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg == NULL)
 | 
				
			||||||
 | 
							return PyTuple_New(0);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return PySequence_Tuple(arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char tuple_doc[] =
 | 
				
			||||||
 | 
					"tuple(sequence) -> list\n\
 | 
				
			||||||
 | 
					\n\
 | 
				
			||||||
 | 
					Return a tuple whose items are the same as those of the argument sequence.\n\
 | 
				
			||||||
 | 
					If the argument is a tuple, the return value is the same object.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PySequenceMethods tuple_as_sequence = {
 | 
					static PySequenceMethods tuple_as_sequence = {
 | 
				
			||||||
	(inquiry)tuplelength,			/* sq_length */
 | 
						(inquiry)tuplelength,			/* sq_length */
 | 
				
			||||||
	(binaryfunc)tupleconcat,		/* sq_concat */
 | 
						(binaryfunc)tupleconcat,		/* sq_concat */
 | 
				
			||||||
| 
						 | 
					@ -509,14 +531,28 @@ PyTypeObject PyTuple_Type = {
 | 
				
			||||||
	(hashfunc)tuplehash,			/* tp_hash */
 | 
						(hashfunc)tuplehash,			/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
	0,             				/* tp_doc */
 | 
						tuple_doc,				/* tp_doc */
 | 
				
			||||||
 	(traverseproc)tupletraverse,		/* tp_traverse */
 | 
					 	(traverseproc)tupletraverse,		/* tp_traverse */
 | 
				
			||||||
	0,					/* tp_clear */
 | 
						0,					/* tp_clear */
 | 
				
			||||||
	tuplerichcompare,			/* tp_richcompare */
 | 
						tuplerichcompare,			/* 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 */
 | 
				
			||||||
 | 
						tuple_new,				/* tp_new */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The following function breaks the notion that tuples are immutable:
 | 
					/* The following function breaks the notion that tuples are immutable:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2338
									
								
								Objects/typeobject.c
									
										
									
									
									
								
							
							
						
						
									
										2338
									
								
								Objects/typeobject.c
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -4667,12 +4667,6 @@ static PyMethodDef unicode_methods[] = {
 | 
				
			||||||
    {NULL, NULL}
 | 
					    {NULL, NULL}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject * 
 | 
					 | 
				
			||||||
unicode_getattr(PyUnicodeObject *self, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return Py_FindMethod(unicode_methods, (PyObject*) self, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PySequenceMethods unicode_as_sequence = {
 | 
					static PySequenceMethods unicode_as_sequence = {
 | 
				
			||||||
    (inquiry) unicode_length, 		/* sq_length */
 | 
					    (inquiry) unicode_length, 		/* sq_length */
 | 
				
			||||||
    (binaryfunc) PyUnicode_Concat, 	/* sq_concat */
 | 
					    (binaryfunc) PyUnicode_Concat, 	/* sq_concat */
 | 
				
			||||||
| 
						 | 
					@ -5346,6 +5340,30 @@ static PyBufferProcs unicode_as_buffer = {
 | 
				
			||||||
    (getcharbufferproc) unicode_buffer_getcharbuf,
 | 
					    (getcharbufferproc) unicode_buffer_getcharbuf,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					        PyObject *x = NULL;
 | 
				
			||||||
 | 
						static char *kwlist[] = {"string", "encoding", "errors", 0};
 | 
				
			||||||
 | 
						char *encoding = NULL;
 | 
				
			||||||
 | 
						char *errors = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(type == &PyUnicode_Type);
 | 
				
			||||||
 | 
						if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:unicode",
 | 
				
			||||||
 | 
										  kwlist, &x, &encoding, &errors))
 | 
				
			||||||
 | 
						    return NULL;
 | 
				
			||||||
 | 
						if (x == NULL)
 | 
				
			||||||
 | 
							return (PyObject *)_PyUnicode_New(0);
 | 
				
			||||||
 | 
						return PyUnicode_FromEncodedObject(x, encoding, errors);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char unicode_doc[] =
 | 
				
			||||||
 | 
					"unicode(string [, encoding[, errors]]) -> object\n\
 | 
				
			||||||
 | 
					\n\
 | 
				
			||||||
 | 
					Create a new Unicode object from the given encoded string.\n\
 | 
				
			||||||
 | 
					encoding defaults to the current default string encoding and \n\
 | 
				
			||||||
 | 
					errors, defining the error handling, to 'strict'.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyTypeObject PyUnicode_Type = {
 | 
					PyTypeObject PyUnicode_Type = {
 | 
				
			||||||
    PyObject_HEAD_INIT(&PyType_Type)
 | 
					    PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
    0, 					/* ob_size */
 | 
					    0, 					/* ob_size */
 | 
				
			||||||
| 
						 | 
					@ -5355,7 +5373,7 @@ PyTypeObject PyUnicode_Type = {
 | 
				
			||||||
    /* Slots */
 | 
					    /* Slots */
 | 
				
			||||||
    (destructor)_PyUnicode_Free, 	/* tp_dealloc */
 | 
					    (destructor)_PyUnicode_Free, 	/* tp_dealloc */
 | 
				
			||||||
    0, 					/* tp_print */
 | 
					    0, 					/* tp_print */
 | 
				
			||||||
    (getattrfunc)unicode_getattr, 	/* tp_getattr */
 | 
					    0,				 	/* tp_getattr */
 | 
				
			||||||
    0, 					/* tp_setattr */
 | 
					    0, 					/* tp_setattr */
 | 
				
			||||||
    (cmpfunc) unicode_compare, 		/* tp_compare */
 | 
					    (cmpfunc) unicode_compare, 		/* tp_compare */
 | 
				
			||||||
    (reprfunc) unicode_repr, 		/* tp_repr */
 | 
					    (reprfunc) unicode_repr, 		/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -5365,10 +5383,28 @@ PyTypeObject PyUnicode_Type = {
 | 
				
			||||||
    (hashfunc) unicode_hash, 		/* tp_hash*/
 | 
					    (hashfunc) unicode_hash, 		/* tp_hash*/
 | 
				
			||||||
    0, 					/* tp_call*/
 | 
					    0, 					/* tp_call*/
 | 
				
			||||||
    (reprfunc) unicode_str,	 	/* tp_str */
 | 
					    (reprfunc) unicode_str,	 	/* tp_str */
 | 
				
			||||||
    (getattrofunc) NULL, 		/* tp_getattro */
 | 
					    PyObject_GenericGetAttr, 		/* tp_getattro */
 | 
				
			||||||
    (setattrofunc) NULL, 		/* tp_setattro */
 | 
					    0,			 		/* tp_setattro */
 | 
				
			||||||
    &unicode_as_buffer,			/* tp_as_buffer */
 | 
					    &unicode_as_buffer,			/* tp_as_buffer */
 | 
				
			||||||
    Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
					    Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
				
			||||||
 | 
					    unicode_doc,			/* tp_doc */
 | 
				
			||||||
 | 
					    0,					/* tp_traverse */
 | 
				
			||||||
 | 
					    0,					/* tp_clear */
 | 
				
			||||||
 | 
					    0,					/* tp_richcompare */
 | 
				
			||||||
 | 
					    0,					/* tp_weaklistoffset */
 | 
				
			||||||
 | 
					    0,					/* tp_iter */
 | 
				
			||||||
 | 
					    0,					/* tp_iternext */
 | 
				
			||||||
 | 
					    unicode_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 */
 | 
				
			||||||
 | 
					    0,					/* tp_init */
 | 
				
			||||||
 | 
					    0,					/* tp_alloc */
 | 
				
			||||||
 | 
					    unicode_new,			/* tp_new */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Initialize the Unicode implementation */
 | 
					/* Initialize the Unicode implementation */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,7 @@ extern void init_locale(void);
 | 
				
			||||||
extern void init_codecs(void);
 | 
					extern void init_codecs(void);
 | 
				
			||||||
extern void initxreadlines(void);
 | 
					extern void initxreadlines(void);
 | 
				
			||||||
extern void init_weakref(void);
 | 
					extern void init_weakref(void);
 | 
				
			||||||
 | 
					extern void initxxsubtype(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* XXX tim: what's the purpose of ADDMODULE MARKER? */
 | 
					/* XXX tim: what's the purpose of ADDMODULE MARKER? */
 | 
				
			||||||
/* -- ADDMODULE MARKER 1 -- */
 | 
					/* -- ADDMODULE MARKER 1 -- */
 | 
				
			||||||
| 
						 | 
					@ -98,6 +99,8 @@ struct _inittab _PyImport_Inittab[] = {
 | 
				
			||||||
	{"xreadlines", initxreadlines},
 | 
						{"xreadlines", initxreadlines},
 | 
				
			||||||
	{"_weakref", init_weakref},
 | 
						{"_weakref", init_weakref},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{"xxsubtype", initxxsubtype},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* XXX tim: what's the purpose of ADDMODULE MARKER? */
 | 
					/* XXX tim: what's the purpose of ADDMODULE MARKER? */
 | 
				
			||||||
/* -- ADDMODULE MARKER 2 -- */
 | 
					/* -- ADDMODULE MARKER 2 -- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -495,6 +495,21 @@ SOURCE=..\Modules\cStringIO.c
 | 
				
			||||||
# End Source File
 | 
					# End Source File
 | 
				
			||||||
# Begin Source File
 | 
					# Begin Source File
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SOURCE=..\Objects\descrobject.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!IF  "$(CFG)" == "pythoncore - Win32 Release"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!ELSEIF  "$(CFG)" == "pythoncore - Win32 Debug"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!ELSEIF  "$(CFG)" == "pythoncore - Win32 Alpha Debug"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!ELSEIF  "$(CFG)" == "pythoncore - Win32 Alpha Release"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!ENDIF 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# End Source File
 | 
				
			||||||
 | 
					# Begin Source File
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SOURCE=..\Objects\dictobject.c
 | 
					SOURCE=..\Objects\dictobject.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
!IF  "$(CFG)" == "pythoncore - Win32 Release"
 | 
					!IF  "$(CFG)" == "pythoncore - Win32 Release"
 | 
				
			||||||
| 
						 | 
					@ -1737,6 +1752,21 @@ SOURCE=..\Modules\xreadlinesmodule.c
 | 
				
			||||||
# End Source File
 | 
					# End Source File
 | 
				
			||||||
# Begin Source File
 | 
					# Begin Source File
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SOURCE=..\Modules\xxsubtype.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!IF  "$(CFG)" == "pythoncore - Win32 Release"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!ELSEIF  "$(CFG)" == "pythoncore - Win32 Debug"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!ELSEIF  "$(CFG)" == "pythoncore - Win32 Alpha Debug"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!ELSEIF  "$(CFG)" == "pythoncore - Win32 Alpha Release"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!ENDIF 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# End Source File
 | 
				
			||||||
 | 
					# Begin Source File
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SOURCE=..\Modules\yuvconvert.c
 | 
					SOURCE=..\Modules\yuvconvert.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
!IF  "$(CFG)" == "pythoncore - Win32 Release"
 | 
					!IF  "$(CFG)" == "pythoncore - Win32 Release"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										431
									
								
								PLAN.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										431
									
								
								PLAN.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,431 @@
 | 
				
			||||||
 | 
					Project: core implementation
 | 
				
			||||||
 | 
					****************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Do binary operators properly.  nb_add should try to call self.__add__
 | 
				
			||||||
 | 
					and other.__radd__.  I think I'll exclude base types that define any
 | 
				
			||||||
 | 
					binary operator without setting the CHECKTYPES flag.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fix comparisons.  There's some nasty stuff here: when two types are
 | 
				
			||||||
 | 
					not the same, and they're not instances, the fallback code doesn't
 | 
				
			||||||
 | 
					account for the possibility that they might be subtypes of a common
 | 
				
			||||||
 | 
					base type that defines a comparison.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fix subtype_dealloc().  This currently searches through the list of
 | 
				
			||||||
 | 
					base types until it finds a type whose tp_dealloc is not
 | 
				
			||||||
 | 
					subtype_dealloc.  I think this is not safe.  I think the alloc/dealloc
 | 
				
			||||||
 | 
					policy needs to be rethought.  *** There's an idea here that I haven't
 | 
				
			||||||
 | 
					worked out yet: just as object creation now has separate API's tp_new,
 | 
				
			||||||
 | 
					tp_alloc, and tp_init, destruction has tp_dealloc and tp_free.  (Maybe
 | 
				
			||||||
 | 
					tp_fini should be added to correspond to tp_init?)  Something
 | 
				
			||||||
 | 
					could/should be done with this. ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Clean up isinstance(), issubclass() and their C equivalents.  There
 | 
				
			||||||
 | 
					are a bunch of different APIs here and not all of them do the right
 | 
				
			||||||
 | 
					thing yet.  There should be fewer APIs and their implementation should
 | 
				
			||||||
 | 
					be simpler.  The old "abstract subclass" test should probably
 | 
				
			||||||
 | 
					disappear (if we want to root out ExtensionClass).  *** I think I've
 | 
				
			||||||
 | 
					done 90% of this by creating PyType_IsSubtype() and using it
 | 
				
			||||||
 | 
					appropriately.  For now, the old "abstract subclass" test is still
 | 
				
			||||||
 | 
					there, and there may be some places where PyObject_IsSubclass() is
 | 
				
			||||||
 | 
					called where PyType_IsSubtype() would be more appropriate. ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Check for conflicts between base classes.  I fear that the rules used
 | 
				
			||||||
 | 
					to decide whether multiple bases have conflicting instance variables
 | 
				
			||||||
 | 
					aren't strict enough.  I think that sometimes two different classes
 | 
				
			||||||
 | 
					adding __dict__ may be incompatible after all.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Check for order conflicts.  Suppose there are two base classes X and
 | 
				
			||||||
 | 
					Y.  Suppose class B derives from X and Y, and class C from Y and X (in
 | 
				
			||||||
 | 
					that order).  Now suppose class D derives from B and C.  In which
 | 
				
			||||||
 | 
					order should the base classes X and Y be searched?  This is an order
 | 
				
			||||||
 | 
					conflict, and should be disallowed; currently the test for this is not
 | 
				
			||||||
 | 
					implemented.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Clean up the GC interface.  Currently, tp_basicsize includes the GC
 | 
				
			||||||
 | 
					head size iff tp_flags includes the GC flag bit.  This makes object
 | 
				
			||||||
 | 
					size math a pain (e.g. to see if two object types have the same
 | 
				
			||||||
 | 
					instance size, you can't just compare the tp_basicsize fields -- you
 | 
				
			||||||
 | 
					have to conditionally subtract the GC head size).  Neil has a patch
 | 
				
			||||||
 | 
					that improves the API in this area, but it's backwards incompatible.
 | 
				
			||||||
 | 
					(http://sf.net/tracker/?func=detail&aid=421893&group_id=5470&atid=305470)
 | 
				
			||||||
 | 
					I think I know of a way to fix the incompatibility (by switching to a
 | 
				
			||||||
 | 
					different flag bit).  *** Tim proposed a better idea: macros to access
 | 
				
			||||||
 | 
					tp_basicsize while hiding the nastiness.  This is done now, so I think
 | 
				
			||||||
 | 
					the rest of this task needn't be done. ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make the __dict__ of types declared with Python class statements
 | 
				
			||||||
 | 
					writable -- only statically declared types must have an immutable
 | 
				
			||||||
 | 
					dict, because they're shared between interpreter instances.  Possibly
 | 
				
			||||||
 | 
					trap writes to the __dict__ to update the corresponding tp_<slot> if
 | 
				
			||||||
 | 
					an __<slot>__ name is affected.  *** Done as part of the next task. ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It should be an option (maybe a different metaclass, maybe a flag) to
 | 
				
			||||||
 | 
					*not* merge __dict__ with all the bases, but instead search the
 | 
				
			||||||
 | 
					__dict__ (or __introduced__?) of all bases in __mro__ order.  (This is
 | 
				
			||||||
 | 
					needed anyway to unify classes completely.)  *** Partly done.
 | 
				
			||||||
 | 
					Inheritance of slots from bases is still icky: (1) MRO is not always
 | 
				
			||||||
 | 
					respected when inheriting slots; (2) dynamic classes can't add slot
 | 
				
			||||||
 | 
					implementations in Python after creation (e.g., setting C.__hash__
 | 
				
			||||||
 | 
					doesn't set the tp_hash slot).  ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Universal base class (object).  How can we make the object class
 | 
				
			||||||
 | 
					subclassable and define simple default methods for everything without
 | 
				
			||||||
 | 
					having these inherited by built-in types that don't want these
 | 
				
			||||||
 | 
					defaults?  *** Done, really. ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Add error checking to the MRO calculation.  *** Done. ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make __new__ overridable through a Python class method (!).  Make more
 | 
				
			||||||
 | 
					of the sub-algorithms of type construction available as methods.  ***
 | 
				
			||||||
 | 
					After I implemented class methods, I found that in order to be able
 | 
				
			||||||
 | 
					to make an upcall to Base.__new__() and have it create an instance of
 | 
				
			||||||
 | 
					your class (rather than a Base instance), you can't use class methods
 | 
				
			||||||
 | 
					-- you must use static methods.  So I've implemented those too.  I've
 | 
				
			||||||
 | 
					hooked up __new__ in the right places, so the first part of this is
 | 
				
			||||||
 | 
					now done.  I've also exported the MRO calculation and made it
 | 
				
			||||||
 | 
					overridable, as metamethod mro().  I believe that closes this topic
 | 
				
			||||||
 | 
					for now.  I expect that some warts will only be really debugged when
 | 
				
			||||||
 | 
					we try to use this for some, eh, interesting types such as tuples. ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More -- I'm sure new issues will crop up as we go.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project: loose ends and follow-through
 | 
				
			||||||
 | 
					**************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make more (most?) built-in types act as their own factory functions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make more (most?) built-in types subtypable -- with or without
 | 
				
			||||||
 | 
					overridable allocation.  *** This includes descriptors!  It should be
 | 
				
			||||||
 | 
					possible to write descriptors in Python, so metaclasses can do clever
 | 
				
			||||||
 | 
					things with them. ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Exceptions should be types.  This changes the rules, since now almost
 | 
				
			||||||
 | 
					anything can be raised (as maybe it should).  Or should we strive for
 | 
				
			||||||
 | 
					enforcement of the convention that all exceptions should be derived
 | 
				
			||||||
 | 
					from Exception?  String exceptions will be another hassle, to be
 | 
				
			||||||
 | 
					deprecated and eventually ruled out.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Standardize a module containing names for all built-in types, and
 | 
				
			||||||
 | 
					standardize on names.  E.g. should the official name of the string
 | 
				
			||||||
 | 
					type be 'str', 'string', or 'StringType'?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Create a hierarchy of types, so that e.g. int and long are both
 | 
				
			||||||
 | 
					subtypes of an abstract base type integer, which is itself a subtype
 | 
				
			||||||
 | 
					of number, etc.  A lot of thinking can go into this!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*** NEW TASK??? ***
 | 
				
			||||||
 | 
					Implement "signature" objects.  These are alluded to in PEP 252 but
 | 
				
			||||||
 | 
					not yet specified.  Supposedly they provide an easily usable API to
 | 
				
			||||||
 | 
					find out about function/method arguments.  Building these for Python
 | 
				
			||||||
 | 
					functions is simple.  Building these for built-in functions will
 | 
				
			||||||
 | 
					require a change to the PyMethodDef structure, so that a type can
 | 
				
			||||||
 | 
					provide signature information for its C methods.  (This would also
 | 
				
			||||||
 | 
					help in supporting keyword arguments for C methods with less work than
 | 
				
			||||||
 | 
					PyArg_ParseTupleAndKeywords() currently requires.)  But should we do
 | 
				
			||||||
 | 
					this?  It's additional work and not required for any of the other
 | 
				
			||||||
 | 
					parts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project: making classes use the new machinery
 | 
				
			||||||
 | 
					*********************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Try to get rid of all code in classobject.c by deferring to the new
 | 
				
			||||||
 | 
					mechanisms.  How far can we get without breaking backwards
 | 
				
			||||||
 | 
					compatibility?  This is underspecified because I haven't thought much
 | 
				
			||||||
 | 
					about it yet.  Can we lose the use of PyInstance_Check() everywhere?
 | 
				
			||||||
 | 
					I would hope so!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project: backwards compatibility
 | 
				
			||||||
 | 
					********************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make sure all code checks the proper tp_flags bit before accessing
 | 
				
			||||||
 | 
					type object fields.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Identify areas of incompatibility with Python 2.1.  Design solutions.
 | 
				
			||||||
 | 
					Implement and test.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Some specific areas: a fair amount of code probably depends on
 | 
				
			||||||
 | 
					specific types having __members__ and/or __methods__ attributes.
 | 
				
			||||||
 | 
					These are currently not present (conformant to PEP 252, which proposes
 | 
				
			||||||
 | 
					to drop them) but we may have to add them back.  This can be done in a
 | 
				
			||||||
 | 
					generic way with not too much effort.  Tim adds:  Perhaps that dir(object)
 | 
				
			||||||
 | 
					rarely returns anything but [] now is a consequence of this.  I'm very
 | 
				
			||||||
 | 
					used to doing, e.g., dir([]) or dir("") in an interactive shell to jog my
 | 
				
			||||||
 | 
					memory; also one of the reasons test_generators failed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Another area: going all the way with classes and instances means that
 | 
				
			||||||
 | 
					type(x) == types.InstanceType won't work any more to detect instances.
 | 
				
			||||||
 | 
					Should there be a mode where this still works?  Maybe this should be
 | 
				
			||||||
 | 
					the default mode, with a warning, and an explicit way to get the new
 | 
				
			||||||
 | 
					way to work?  (Instead of a __future__ statement, I'm thinking of a
 | 
				
			||||||
 | 
					module global __metaclass__ which would provide the default metaclass
 | 
				
			||||||
 | 
					for baseless class statements.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project: testing
 | 
				
			||||||
 | 
					****************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Identify new functionality that needs testing.  Conceive unit tests
 | 
				
			||||||
 | 
					for all new functionality.  Conceive stress tests for critical
 | 
				
			||||||
 | 
					features.  Run the tests.  Fix bugs.  Repeat until satisfied.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note: this may interact with the branch integration task.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project: integration with main branch
 | 
				
			||||||
 | 
					*************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merge changes in the HEAD branch into the descr-branch.  Then merge
 | 
				
			||||||
 | 
					the descr-branch back into the HEAD branch.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The longer we wait, the more effort this will be -- the descr-branch
 | 
				
			||||||
 | 
					forked off quite a long time ago, and there are changes everywhere in
 | 
				
			||||||
 | 
					the HEAD branch (e.g. the dict object has been radically rewritten).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					On the other hand, if we do this too early, we'll have to do it again
 | 
				
			||||||
 | 
					later.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note from Tim:  We should never again wait until literally 100s of files
 | 
				
			||||||
 | 
					are out of synch.  I don't care how often I need to do this, provided only
 | 
				
			||||||
 | 
					that it's a tractable task each time.  Once per week sounds like a good
 | 
				
			||||||
 | 
					idea.  As is, even the trunk change to rangeobject.c created more than its
 | 
				
			||||||
 | 
					proper share of merge headaches, because it confused all the other reasons
 | 
				
			||||||
 | 
					include file merges were getting conflicts (the more changes there are, the
 | 
				
			||||||
 | 
					worse diff does; indeed, I came up with the ndiff algorithm in the 80s
 | 
				
			||||||
 | 
					precisely because the source-control diff program Cray used at the time
 | 
				
			||||||
 | 
					produced minimal but *senseless* diffs, thus creating artificial conflicts;
 | 
				
			||||||
 | 
					paying unbounded attention to context does a much better job of putting
 | 
				
			||||||
 | 
					changes where they make semantic sense too; but we're stuck with Unix diff
 | 
				
			||||||
 | 
					here, and it isn't robust in this sense; if we don't keep its job simple,
 | 
				
			||||||
 | 
					it will make my job hell).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Done:
 | 
				
			||||||
 | 
					To undo or rename before final merge:  Modules/spam.c has worked its
 | 
				
			||||||
 | 
					way into the branch Unix and Windows builds (pythoncore.dsp and
 | 
				
			||||||
 | 
					PC/config.c); also imported by test_descr.py.  How about renaming to
 | 
				
			||||||
 | 
					xxsubtype.c (whatever) now?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project: performance tuning
 | 
				
			||||||
 | 
					***************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pick or create a general performance benchmark for Python.  Benchmark
 | 
				
			||||||
 | 
					the new system vs. the old system.  Profile the new system.  Improve
 | 
				
			||||||
 | 
					hotspots.  Repeat until satisfied.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note: this may interact with the branch integration task.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project: documentation
 | 
				
			||||||
 | 
					**********************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Update PEP 252 (descriptors).  Describe more of the prototype
 | 
				
			||||||
 | 
					implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Update PEP 253 (subtyping).  Complicated architectural wrangling with
 | 
				
			||||||
 | 
					metaclasses.  There is an interaction between implementation and
 | 
				
			||||||
 | 
					description.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Write PEP 254 (unification of classes).  This should discuss what
 | 
				
			||||||
 | 
					changes for ordinary classes, and how we can make it more b/w
 | 
				
			||||||
 | 
					compatible.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Other documentation.  There needs to be user documentation,
 | 
				
			||||||
 | 
					eventually.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project: community interaction
 | 
				
			||||||
 | 
					******************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tasks:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once the PEPs are written, solicit community feedback, and formulate
 | 
				
			||||||
 | 
					responses to the feedback.  Give the community enough time to think
 | 
				
			||||||
 | 
					over this complicated proposal.  Provide the community with a
 | 
				
			||||||
 | 
					prototype implementation to test.  Try to do this *before* casting
 | 
				
			||||||
 | 
					everything in stone!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MERGE BEGIN ****************************************************************
 | 
				
			||||||
 | 
					Merge details (this section is Tim's scratchpad, but should help a lot if
 | 
				
			||||||
 | 
					he dies of frustration while wrestling with CVS <0.9 wink>).
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-08-01  Merging descr-branch back into trunk.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 22:05:
 | 
				
			||||||
 | 
					    cvs tag date2001-08-01 python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged trunk delta into branch:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-30 -j date2001-08-01 descr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					No conflicts (! first time ever!) ... but problems with pythoncore.dsp.
 | 
				
			||||||
 | 
					Resolved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Rebuilt from scratch; ran all tests; checked into branch about 22:40.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged descr-branch back into trunk:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j descr-branch python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					34 conflicts.  Hmm!  OK, looks like every file in the project with an
 | 
				
			||||||
 | 
					embedded RCS Id is "a conflict".  Others make no sense, e.g., a dozen
 | 
				
			||||||
 | 
					conflicts in dictobject.c, sometimes enclosing identical(!) blobs of
 | 
				
			||||||
 | 
					source code.  And CVS remains utterly baffled by Python type object decls.
 | 
				
			||||||
 | 
					Every line of ceval.c's generator code si in conflict blocks ... OK,
 | 
				
			||||||
 | 
					there's no pattern or sense here, I'll just deal with it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Conflicts resolved; rebuilt from scratch; test_weakref fails.
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Doing this again while the expat and Windows installer changes are still
 | 
				
			||||||
 | 
					fresh on my mind.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 23:50 EDT on the 29th:
 | 
				
			||||||
 | 
					    cvs tag date2001-07-30 python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged trunk delta into branch:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-28 -j date2001-07-30 descr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2 conflicts, resolved.
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-28
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 00:31 EDT:
 | 
				
			||||||
 | 
					    cvs tag date2001-07-28 python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged trunk delta into branch:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-21 -j date2001-07-28 descr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4 conflicts, all RCS Ids.  Resolved.
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-21
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 01:00 EDT:
 | 
				
			||||||
 | 
					    cvs tag date2001-07-21 python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged trunk delta into branch:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-17b -j date2001-07-21 descr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4 conflicts, mostly RCS Id thingies.  Resolved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Legit failure in new test_repr, because repr.py dispatches on the exact
 | 
				
			||||||
 | 
					string returned by type(x).  type(1L) and type('s') differ in descr-branch
 | 
				
			||||||
 | 
					now, and repr.py didn't realize that, falling back to the "unknown type"
 | 
				
			||||||
 | 
					case for longs and strings.  Repaired descr-branch repr.py.
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Removed the r22a1-branch tag (see next entry).  Turns out Guido did add a
 | 
				
			||||||
 | 
					r22a1 tag, so the r22a1-branch tag served no point anymore.
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-18  2.2a1 releaase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Immediately after the merge just below, I tagged descr-branch via
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cvs tag r22a1-branch descr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Guido may or may not want to add another tag here (? maybe he wants to do
 | 
				
			||||||
 | 
					some more Unix fiddling first).
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-17  building 2.2a1 release, from descr-branch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 22:00 EDT, like so:
 | 
				
			||||||
 | 
					    cvs tag date2001-07-17b python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged trunk delta into branch via:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-17a -j date2001-07-17b descr
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-17
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 00:05 EDT, like so:
 | 
				
			||||||
 | 
					    cvs tag date2001-07-17a python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged trunk delta into branch via:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-16 -j date2001-07-17a descr
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 15:20 EDT, like so:
 | 
				
			||||||
 | 
					    cvs tag date2001-07-16 python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Guido then added all the other dist/ directories to descr-branch from that
 | 
				
			||||||
 | 
					trunk tag.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tim then merged trunk delta into the branch via:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-15 -j date2001-07-16 descr
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 15:44 EDT, like so:
 | 
				
			||||||
 | 
					    cvs tag date2001-07-15 python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged trunk delta into branch via:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-13 -j date2001-07-15 descr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Four files with conflicts, all artificial RCS Id & Revision thingies.
 | 
				
			||||||
 | 
					Resolved and committed.
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk about 22:13 EDT, like so:
 | 
				
			||||||
 | 
					    cvs tag date2001-07-13 python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merged trunk delta into branch via:
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-06 -j date2001-07-13 descr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Six(!) files with conflicts, mostly related to NeilS's generator gc patches.
 | 
				
			||||||
 | 
					Unsure why, but CVS seems always to think there are conflicts whenever a
 | 
				
			||||||
 | 
					line in a type object decl gets changed, and the conflict marking seems
 | 
				
			||||||
 | 
					maximally confused in these cases.  Anyway, since I reviewed those patches
 | 
				
			||||||
 | 
					on the trunk, good thing I'm merging them, and darned glad it's still fresh
 | 
				
			||||||
 | 
					on my mind.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Resolved the conflicts, and committed the changes in a few hours total.
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-07
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merge of trunk tag date2001-07-06 into descr-branch, via
 | 
				
			||||||
 | 
					    cvs -q -z3 up -j date2001-07-06 mergedescr
 | 
				
			||||||
 | 
					was committed on 2001-07-07.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Merge issues:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(all resolved -- GvR)
 | 
				
			||||||
 | 
					----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					2001-07-06
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tagged trunk a bit after midnight, like so:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					C:\Code>cvs tag date2001-07-06 python
 | 
				
			||||||
 | 
					cvs server: Tagging python
 | 
				
			||||||
 | 
					cvs server: Tagging python/dist
 | 
				
			||||||
 | 
					cvs server: Tagging python/dist/src
 | 
				
			||||||
 | 
					T python/dist/src/.cvsignore
 | 
				
			||||||
 | 
					T python/dist/src/LICENSE
 | 
				
			||||||
 | 
					T python/dist/src/Makefile.pre.in
 | 
				
			||||||
 | 
					T python/dist/src/README
 | 
				
			||||||
 | 
					... [& about 3000 lines more] ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is the first trunk snapshot to be merged into the descr-branch.
 | 
				
			||||||
 | 
					Gave it a date instead of a goofy name because there's going to be more
 | 
				
			||||||
 | 
					than one of these, and at least it's obvious which of two ISO dates comes
 | 
				
			||||||
 | 
					earlier.  These tags should go away after all merging is complete.
 | 
				
			||||||
 | 
					MERGE END ******************************************************************
 | 
				
			||||||
| 
						 | 
					@ -131,26 +131,6 @@ start of the object (or at the specified offset). The slice will\n\
 | 
				
			||||||
extend to the end of the target object (or with the specified size).";
 | 
					extend to the end of the target object (or with the specified size).";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
builtin_unicode(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
        PyObject *v;
 | 
					 | 
				
			||||||
	char *encoding = NULL;
 | 
					 | 
				
			||||||
	char *errors = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( !PyArg_ParseTuple(args, "O|ss:unicode", &v, &encoding, &errors) )
 | 
					 | 
				
			||||||
	    return NULL;
 | 
					 | 
				
			||||||
	return PyUnicode_FromEncodedObject(v, encoding, errors);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char unicode_doc[] =
 | 
					 | 
				
			||||||
"unicode(string [, encoding[, errors]]) -> object\n\
 | 
					 | 
				
			||||||
\n\
 | 
					 | 
				
			||||||
Create a new Unicode object from the given encoded string.\n\
 | 
					 | 
				
			||||||
encoding defaults to the current default string encoding and \n\
 | 
					 | 
				
			||||||
errors, defining the error handling, to 'strict'.";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
builtin_callable(PyObject *self, PyObject *args)
 | 
					builtin_callable(PyObject *self, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -435,257 +415,6 @@ The mode must be 'exec' to compile a module, 'single' to compile a\n\
 | 
				
			||||||
single (interactive) statement, or 'eval' to compile an expression.";
 | 
					single (interactive) statement, or 'eval' to compile an expression.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef WITHOUT_COMPLEX
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
complex_from_string(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 PyComplex_FromDoubles(x,y);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
builtin_complex(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *r, *i, *tmp;
 | 
					 | 
				
			||||||
	PyNumberMethods *nbr, *nbi = NULL;
 | 
					 | 
				
			||||||
	Py_complex cr, ci;
 | 
					 | 
				
			||||||
	int own_r = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i = NULL;
 | 
					 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	if (PyString_Check(r) || PyUnicode_Check(r))
 | 
					 | 
				
			||||||
		return complex_from_string(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 PyComplex_FromCComplex(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.";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
builtin_dir(PyObject *self, PyObject *args)
 | 
					builtin_dir(PyObject *self, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1300,91 +1029,6 @@ Return the string itself or the previously interned string object with the\n\
 | 
				
			||||||
same value.";
 | 
					same value.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
builtin_int(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *v;
 | 
					 | 
				
			||||||
	int base = -909;		     /* unlikely! */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O|i:int", &v, &base))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	if (base == -909)
 | 
					 | 
				
			||||||
		return PyNumber_Int(v);
 | 
					 | 
				
			||||||
	else if (PyString_Check(v))
 | 
					 | 
				
			||||||
		return PyInt_FromString(PyString_AS_STRING(v), NULL, base);
 | 
					 | 
				
			||||||
	else if (PyUnicode_Check(v))
 | 
					 | 
				
			||||||
		return PyInt_FromUnicode(PyUnicode_AS_UNICODE(v),
 | 
					 | 
				
			||||||
					 PyUnicode_GET_SIZE(v),
 | 
					 | 
				
			||||||
					 base);
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		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 PyObject *
 | 
					 | 
				
			||||||
builtin_long(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *v;
 | 
					 | 
				
			||||||
	int base = -909;		     /* unlikely! */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O|i:long", &v, &base))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	if (base == -909)
 | 
					 | 
				
			||||||
		return PyNumber_Long(v);
 | 
					 | 
				
			||||||
	else if (PyString_Check(v))
 | 
					 | 
				
			||||||
		return PyLong_FromString(PyString_AS_STRING(v), NULL, base);
 | 
					 | 
				
			||||||
	else if (PyUnicode_Check(v))
 | 
					 | 
				
			||||||
		return PyLong_FromUnicode(PyUnicode_AS_UNICODE(v),
 | 
					 | 
				
			||||||
					  PyUnicode_GET_SIZE(v),
 | 
					 | 
				
			||||||
					  base);
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		PyErr_SetString(PyExc_TypeError,
 | 
					 | 
				
			||||||
				"long() can't convert non-string with explicit base");
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char long_doc[] =
 | 
					 | 
				
			||||||
"long(x) -> long integer\n\
 | 
					 | 
				
			||||||
long(x, base) -> long 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 given base.  It is an error to supply a base when\n\
 | 
					 | 
				
			||||||
converting a non-string.";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
builtin_float(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O:float", &v))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	if (PyString_Check(v))
 | 
					 | 
				
			||||||
		return PyFloat_FromString(v, NULL);
 | 
					 | 
				
			||||||
	return PyNumber_Float(v);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char float_doc[] =
 | 
					 | 
				
			||||||
"float(x) -> floating point number\n\
 | 
					 | 
				
			||||||
\n\
 | 
					 | 
				
			||||||
Convert a string or number to a floating point number, if possible.";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
builtin_iter(PyObject *self, PyObject *args)
 | 
					builtin_iter(PyObject *self, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1431,22 +1075,6 @@ static char len_doc[] =
 | 
				
			||||||
Return the number of items of a sequence or mapping.";
 | 
					Return the number of items of a sequence or mapping.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
builtin_list(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O:list", &v))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	return PySequence_List(v);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char list_doc[] =
 | 
					 | 
				
			||||||
"list(sequence) -> list\n\
 | 
					 | 
				
			||||||
\n\
 | 
					 | 
				
			||||||
Return a new list whose items are the same as those of the argument sequence.";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
builtin_slice(PyObject *self, PyObject *args)
 | 
					builtin_slice(PyObject *self, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -2032,58 +1660,6 @@ Round a number to a given precision in decimal digits (default 0 digits).\n\
 | 
				
			||||||
This always returns a floating point number.  Precision may be negative.";
 | 
					This always returns a floating point number.  Precision may be negative.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
builtin_str(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O:str", &v))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	return PyObject_Str(v);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char str_doc[] =
 | 
					 | 
				
			||||||
"str(object) -> string\n\
 | 
					 | 
				
			||||||
\n\
 | 
					 | 
				
			||||||
Return a nice string representation of the object.\n\
 | 
					 | 
				
			||||||
If the argument is a string, the return value is the same object.";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
builtin_tuple(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O:tuple", &v))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	return PySequence_Tuple(v);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char tuple_doc[] =
 | 
					 | 
				
			||||||
"tuple(sequence) -> list\n\
 | 
					 | 
				
			||||||
\n\
 | 
					 | 
				
			||||||
Return a tuple whose items are the same as those of the argument sequence.\n\
 | 
					 | 
				
			||||||
If the argument is a tuple, the return value is the same object.";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
builtin_type(PyObject *self, PyObject *args)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PyObject *v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!PyArg_ParseTuple(args, "O:type", &v))
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	v = (PyObject *)v->ob_type;
 | 
					 | 
				
			||||||
	Py_INCREF(v);
 | 
					 | 
				
			||||||
	return v;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static char type_doc[] =
 | 
					 | 
				
			||||||
"type(object) -> type object\n\
 | 
					 | 
				
			||||||
\n\
 | 
					 | 
				
			||||||
Return the type of the object.";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
builtin_vars(PyObject *self, PyObject *args)
 | 
					builtin_vars(PyObject *self, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -2255,16 +1831,12 @@ static PyMethodDef builtin_methods[] = {
 | 
				
			||||||
	{"cmp",		builtin_cmp, 1, cmp_doc},
 | 
						{"cmp",		builtin_cmp, 1, cmp_doc},
 | 
				
			||||||
	{"coerce",	builtin_coerce, 1, coerce_doc},
 | 
						{"coerce",	builtin_coerce, 1, coerce_doc},
 | 
				
			||||||
	{"compile",	builtin_compile, 1, compile_doc},
 | 
						{"compile",	builtin_compile, 1, compile_doc},
 | 
				
			||||||
#ifndef WITHOUT_COMPLEX
 | 
					 | 
				
			||||||
	{"complex",	builtin_complex, 1, complex_doc},
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	{"delattr",	builtin_delattr, 1, delattr_doc},
 | 
						{"delattr",	builtin_delattr, 1, delattr_doc},
 | 
				
			||||||
	{"dir",		builtin_dir, 1, dir_doc},
 | 
						{"dir",		builtin_dir, 1, dir_doc},
 | 
				
			||||||
	{"divmod",	builtin_divmod, 1, divmod_doc},
 | 
						{"divmod",	builtin_divmod, 1, divmod_doc},
 | 
				
			||||||
	{"eval",	builtin_eval, 1, eval_doc},
 | 
						{"eval",	builtin_eval, 1, eval_doc},
 | 
				
			||||||
	{"execfile",	builtin_execfile, 1, execfile_doc},
 | 
						{"execfile",	builtin_execfile, 1, execfile_doc},
 | 
				
			||||||
	{"filter",	builtin_filter, 1, filter_doc},
 | 
						{"filter",	builtin_filter, 1, filter_doc},
 | 
				
			||||||
	{"float",	builtin_float, 1, float_doc},
 | 
					 | 
				
			||||||
	{"getattr",	builtin_getattr, 1, getattr_doc},
 | 
						{"getattr",	builtin_getattr, 1, getattr_doc},
 | 
				
			||||||
	{"globals",	builtin_globals, 1, globals_doc},
 | 
						{"globals",	builtin_globals, 1, globals_doc},
 | 
				
			||||||
	{"hasattr",	builtin_hasattr, 1, hasattr_doc},
 | 
						{"hasattr",	builtin_hasattr, 1, hasattr_doc},
 | 
				
			||||||
| 
						 | 
					@ -2273,14 +1845,11 @@ static PyMethodDef builtin_methods[] = {
 | 
				
			||||||
	{"id",		builtin_id, 1, id_doc},
 | 
						{"id",		builtin_id, 1, id_doc},
 | 
				
			||||||
	{"input",	builtin_input, 1, input_doc},
 | 
						{"input",	builtin_input, 1, input_doc},
 | 
				
			||||||
	{"intern",	builtin_intern, 1, intern_doc},
 | 
						{"intern",	builtin_intern, 1, intern_doc},
 | 
				
			||||||
	{"int",		builtin_int, 1, int_doc},
 | 
					 | 
				
			||||||
	{"isinstance",  builtin_isinstance, 1, isinstance_doc},
 | 
						{"isinstance",  builtin_isinstance, 1, isinstance_doc},
 | 
				
			||||||
	{"issubclass",  builtin_issubclass, 1, issubclass_doc},
 | 
						{"issubclass",  builtin_issubclass, 1, issubclass_doc},
 | 
				
			||||||
	{"iter",	builtin_iter, 1, iter_doc},
 | 
						{"iter",	builtin_iter, 1, iter_doc},
 | 
				
			||||||
	{"len",		builtin_len, 1, len_doc},
 | 
						{"len",		builtin_len, 1, len_doc},
 | 
				
			||||||
	{"list",	builtin_list, 1, list_doc},
 | 
					 | 
				
			||||||
	{"locals",	builtin_locals, 1, locals_doc},
 | 
						{"locals",	builtin_locals, 1, locals_doc},
 | 
				
			||||||
	{"long",	builtin_long, 1, long_doc},
 | 
					 | 
				
			||||||
	{"map",		builtin_map, 1, map_doc},
 | 
						{"map",		builtin_map, 1, map_doc},
 | 
				
			||||||
	{"max",		builtin_max, 1, max_doc},
 | 
						{"max",		builtin_max, 1, max_doc},
 | 
				
			||||||
	{"min",		builtin_min, 1, min_doc},
 | 
						{"min",		builtin_min, 1, min_doc},
 | 
				
			||||||
| 
						 | 
					@ -2296,10 +1865,6 @@ static PyMethodDef builtin_methods[] = {
 | 
				
			||||||
	{"round",	builtin_round, 1, round_doc},
 | 
						{"round",	builtin_round, 1, round_doc},
 | 
				
			||||||
	{"setattr",	builtin_setattr, 1, setattr_doc},
 | 
						{"setattr",	builtin_setattr, 1, setattr_doc},
 | 
				
			||||||
	{"slice",       builtin_slice, 1, slice_doc},
 | 
						{"slice",       builtin_slice, 1, slice_doc},
 | 
				
			||||||
	{"str",		builtin_str, 1, str_doc},
 | 
					 | 
				
			||||||
	{"tuple",	builtin_tuple, 1, tuple_doc},
 | 
					 | 
				
			||||||
	{"type",	builtin_type, 1, type_doc},
 | 
					 | 
				
			||||||
	{"unicode",	builtin_unicode, 1, unicode_doc},
 | 
					 | 
				
			||||||
	{"unichr",	builtin_unichr, 1, unichr_doc},
 | 
						{"unichr",	builtin_unichr, 1, unichr_doc},
 | 
				
			||||||
	{"vars",	builtin_vars, 1, vars_doc},
 | 
						{"vars",	builtin_vars, 1, vars_doc},
 | 
				
			||||||
	{"xrange",	builtin_xrange, 1, xrange_doc},
 | 
						{"xrange",	builtin_xrange, 1, xrange_doc},
 | 
				
			||||||
| 
						 | 
					@ -2329,6 +1894,42 @@ _PyBuiltin_Init(void)
 | 
				
			||||||
	if (PyDict_SetItemString(dict, "NotImplemented",
 | 
						if (PyDict_SetItemString(dict, "NotImplemented",
 | 
				
			||||||
				 Py_NotImplemented) < 0)
 | 
									 Py_NotImplemented) < 0)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "classmethod",
 | 
				
			||||||
 | 
									 (PyObject *) &PyClassMethod_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					#ifndef WITHOUT_COMPLEX
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "complex",
 | 
				
			||||||
 | 
									 (PyObject *) &PyComplex_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "dictionary",
 | 
				
			||||||
 | 
									 (PyObject *) &PyDict_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "float",
 | 
				
			||||||
 | 
									 (PyObject *) &PyFloat_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "int", (PyObject *) &PyInt_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "list", (PyObject *) &PyList_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "long", (PyObject *) &PyLong_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "object",
 | 
				
			||||||
 | 
									 (PyObject *) &PyBaseObject_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "staticmethod",
 | 
				
			||||||
 | 
									 (PyObject *) &PyStaticMethod_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "str", (PyObject *) &PyString_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "tuple",
 | 
				
			||||||
 | 
									 (PyObject *) &PyTuple_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "type", (PyObject *) &PyType_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (PyDict_SetItemString(dict, "unicode",
 | 
				
			||||||
 | 
									 (PyObject *) &PyUnicode_Type) < 0)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
	debug = PyInt_FromLong(Py_OptimizeFlag == 0);
 | 
						debug = PyInt_FromLong(Py_OptimizeFlag == 0);
 | 
				
			||||||
	if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
 | 
						if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
 | 
				
			||||||
		Py_XDECREF(debug);
 | 
							Py_XDECREF(debug);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										163
									
								
								Python/ceval.c
									
										
									
									
									
								
							
							
						
						
									
										163
									
								
								Python/ceval.c
									
										
									
									
									
								
							| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
#include "frameobject.h"
 | 
					#include "frameobject.h"
 | 
				
			||||||
#include "eval.h"
 | 
					#include "eval.h"
 | 
				
			||||||
#include "opcode.h"
 | 
					#include "opcode.h"
 | 
				
			||||||
 | 
					#include "structmember.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef macintosh
 | 
					#ifdef macintosh
 | 
				
			||||||
#include "macglue.h"
 | 
					#include "macglue.h"
 | 
				
			||||||
| 
						 | 
					@ -32,17 +33,7 @@
 | 
				
			||||||
typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
 | 
					typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Forward declarations */
 | 
					/* Forward declarations */
 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *eval_code2(PyCodeObject *,
 | 
					 | 
				
			||||||
			    PyObject *, PyObject *,
 | 
					 | 
				
			||||||
			    PyObject **, int,
 | 
					 | 
				
			||||||
			    PyObject **, int,
 | 
					 | 
				
			||||||
			    PyObject **, int,
 | 
					 | 
				
			||||||
			    PyObject *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *eval_frame(PyFrameObject *);
 | 
					static PyObject *eval_frame(PyFrameObject *);
 | 
				
			||||||
static char *get_func_name(PyObject *);
 | 
					 | 
				
			||||||
static char *get_func_desc(PyObject *);
 | 
					 | 
				
			||||||
static PyObject *call_object(PyObject *, PyObject *, PyObject *);
 | 
					static PyObject *call_object(PyObject *, PyObject *, PyObject *);
 | 
				
			||||||
static PyObject *call_cfunction(PyObject *, PyObject *, PyObject *);
 | 
					static PyObject *call_cfunction(PyObject *, PyObject *, PyObject *);
 | 
				
			||||||
static PyObject *call_instance(PyObject *, PyObject *, PyObject *);
 | 
					static PyObject *call_instance(PyObject *, PyObject *, PyObject *);
 | 
				
			||||||
| 
						 | 
					@ -98,7 +89,6 @@ static long dxp[256];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
staticforward PyTypeObject gentype;
 | 
					staticforward PyTypeObject gentype;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
| 
						 | 
					@ -211,24 +201,11 @@ static struct PyMethodDef gen_methods[] = {
 | 
				
			||||||
	{NULL,          NULL}   /* Sentinel */
 | 
						{NULL,          NULL}   /* Sentinel */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static struct memberlist gen_memberlist[] = {
 | 
				
			||||||
gen_getattr(genobject *gen, char *name)
 | 
						{"gi_frame",	T_OBJECT, offsetof(genobject, gi_frame),	RO},
 | 
				
			||||||
{
 | 
						{"gi_running",	T_INT,    offsetof(genobject, gi_running),	RO},
 | 
				
			||||||
	PyObject *result;
 | 
						{NULL}	/* Sentinel */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
	if (strcmp(name, "gi_frame") == 0) {
 | 
					 | 
				
			||||||
		result = (PyObject *)gen->gi_frame;
 | 
					 | 
				
			||||||
		assert(result != NULL);
 | 
					 | 
				
			||||||
		Py_INCREF(result);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (strcmp(name, "gi_running") == 0)
 | 
					 | 
				
			||||||
		result = (PyObject *)PyInt_FromLong((long)gen->gi_running);
 | 
					 | 
				
			||||||
	else if (strcmp(name, "__members__") == 0)
 | 
					 | 
				
			||||||
		result = Py_BuildValue("[ss]", "gi_frame", "gi_running");
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
 		result = Py_FindMethod(gen_methods, (PyObject *)gen, name);
 | 
					 | 
				
			||||||
 	return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
statichere PyTypeObject gentype = {
 | 
					statichere PyTypeObject gentype = {
 | 
				
			||||||
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						PyObject_HEAD_INIT(&PyType_Type)
 | 
				
			||||||
| 
						 | 
					@ -239,7 +216,7 @@ statichere PyTypeObject gentype = {
 | 
				
			||||||
	/* methods */
 | 
						/* methods */
 | 
				
			||||||
	(destructor)gen_dealloc, 		/* tp_dealloc */
 | 
						(destructor)gen_dealloc, 		/* tp_dealloc */
 | 
				
			||||||
	0,					/* tp_print */
 | 
						0,					/* tp_print */
 | 
				
			||||||
	(getattrfunc)gen_getattr,		/* tp_getattr */
 | 
						0, 					/* tp_getattr */
 | 
				
			||||||
	0,					/* tp_setattr */
 | 
						0,					/* tp_setattr */
 | 
				
			||||||
	0,					/* tp_compare */
 | 
						0,					/* tp_compare */
 | 
				
			||||||
	0,					/* tp_repr */
 | 
						0,					/* tp_repr */
 | 
				
			||||||
| 
						 | 
					@ -249,7 +226,7 @@ statichere PyTypeObject gentype = {
 | 
				
			||||||
	0,					/* tp_hash */
 | 
						0,					/* tp_hash */
 | 
				
			||||||
	0,					/* tp_call */
 | 
						0,					/* tp_call */
 | 
				
			||||||
	0,					/* tp_str */
 | 
						0,					/* tp_str */
 | 
				
			||||||
	0,					/* tp_getattro */
 | 
						PyObject_GenericGetAttr,		/* tp_getattro */
 | 
				
			||||||
	0,					/* tp_setattro */
 | 
						0,					/* tp_setattro */
 | 
				
			||||||
	0,					/* tp_as_buffer */
 | 
						0,					/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
 | 
				
			||||||
| 
						 | 
					@ -260,6 +237,11 @@ statichere PyTypeObject gentype = {
 | 
				
			||||||
	0,					/* tp_weaklistoffset */
 | 
						0,					/* tp_weaklistoffset */
 | 
				
			||||||
	(getiterfunc)gen_getiter,		/* tp_iter */
 | 
						(getiterfunc)gen_getiter,		/* tp_iter */
 | 
				
			||||||
	(iternextfunc)gen_iternext,		/* tp_iternext */
 | 
						(iternextfunc)gen_iternext,		/* tp_iternext */
 | 
				
			||||||
 | 
						gen_methods,				/* tp_methods */
 | 
				
			||||||
 | 
						gen_memberlist,				/* tp_members */
 | 
				
			||||||
 | 
						0,					/* tp_getset */
 | 
				
			||||||
 | 
						0,					/* tp_base */
 | 
				
			||||||
 | 
						0,					/* tp_dict */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -505,7 +487,7 @@ static int unpack_iterable(PyObject *, int, PyObject **);
 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
 | 
					PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return eval_code2(co,
 | 
						return PyEval_EvalCodeEx(co,
 | 
				
			||||||
			  globals, locals,
 | 
								  globals, locals,
 | 
				
			||||||
			  (PyObject **)NULL, 0,
 | 
								  (PyObject **)NULL, 0,
 | 
				
			||||||
			  (PyObject **)NULL, 0,
 | 
								  (PyObject **)NULL, 0,
 | 
				
			||||||
| 
						 | 
					@ -516,7 +498,7 @@ PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Interpreter main loop */
 | 
					/* Interpreter main loop */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyObject *
 | 
					static PyObject *
 | 
				
			||||||
eval_frame(PyFrameObject *f)
 | 
					eval_frame(PyFrameObject *f)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef DXPAIRS
 | 
					#ifdef DXPAIRS
 | 
				
			||||||
| 
						 | 
					@ -965,7 +947,7 @@ eval_frame(PyFrameObject *f)
 | 
				
			||||||
		case BINARY_SUBSCR:
 | 
							case BINARY_SUBSCR:
 | 
				
			||||||
			w = POP();
 | 
								w = POP();
 | 
				
			||||||
			v = POP();
 | 
								v = POP();
 | 
				
			||||||
			if (PyList_Check(v) && PyInt_Check(w)) {
 | 
								if (v->ob_type == &PyList_Type && PyInt_Check(w)) {
 | 
				
			||||||
				/* INLINE: list[int] */
 | 
									/* INLINE: list[int] */
 | 
				
			||||||
				long i = PyInt_AsLong(w);
 | 
									long i = PyInt_AsLong(w);
 | 
				
			||||||
				if (i < 0)
 | 
									if (i < 0)
 | 
				
			||||||
| 
						 | 
					@ -2273,8 +2255,8 @@ eval_frame(PyFrameObject *f)
 | 
				
			||||||
	return retval;
 | 
						return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					PyObject *
 | 
				
			||||||
eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
 | 
					PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
 | 
				
			||||||
	   PyObject **args, int argcount, PyObject **kws, int kwcount,
 | 
						   PyObject **args, int argcount, PyObject **kws, int kwcount,
 | 
				
			||||||
	   PyObject **defs, int defcount, PyObject *closure)
 | 
						   PyObject **defs, int defcount, PyObject *closure)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -2973,13 +2955,13 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = call_object(func, arg, kw);
 | 
						result = PyObject_Call(func, arg, kw);
 | 
				
			||||||
	Py_DECREF(arg);
 | 
						Py_DECREF(arg);
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* How often is each kind of object called?  The answer depends on the
 | 
					/* How often is each kind of object called?  The answer depends on the
 | 
				
			||||||
   program.  An instrumented call_object() was used to run the Python
 | 
					   program.  An instrumented PyObject_Call() was used to run the Python
 | 
				
			||||||
   regression test suite.  The results were:
 | 
					   regression test suite.  The results were:
 | 
				
			||||||
   4200000 PyCFunctions
 | 
					   4200000 PyCFunctions
 | 
				
			||||||
    390000 fast_function() calls
 | 
					    390000 fast_function() calls
 | 
				
			||||||
| 
						 | 
					@ -2992,11 +2974,11 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
 | 
				
			||||||
    most common, but not by such a large margin.
 | 
					    most common, but not by such a large margin.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *
 | 
					char *
 | 
				
			||||||
get_func_name(PyObject *func)
 | 
					PyEval_GetFuncName(PyObject *func)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (PyMethod_Check(func))
 | 
						if (PyMethod_Check(func))
 | 
				
			||||||
		return get_func_name(PyMethod_GET_FUNCTION(func));
 | 
							return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func));
 | 
				
			||||||
	else if (PyFunction_Check(func))
 | 
						else if (PyFunction_Check(func))
 | 
				
			||||||
		return PyString_AsString(((PyFunctionObject*)func)->func_name);
 | 
							return PyString_AsString(((PyFunctionObject*)func)->func_name);
 | 
				
			||||||
	else if (PyCFunction_Check(func))
 | 
						else if (PyCFunction_Check(func))
 | 
				
			||||||
| 
						 | 
					@ -3011,8 +2993,8 @@ get_func_name(PyObject *func)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *
 | 
					char *
 | 
				
			||||||
get_func_desc(PyObject *func)
 | 
					PyEval_GetFuncDesc(PyObject *func)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (PyMethod_Check(func))
 | 
						if (PyMethod_Check(func))
 | 
				
			||||||
		return "()";
 | 
							return "()";
 | 
				
			||||||
| 
						 | 
					@ -3136,7 +3118,8 @@ call_method(PyObject *func, PyObject *arg, PyObject *kw)
 | 
				
			||||||
			PyErr_Format(PyExc_TypeError,
 | 
								PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
				     "unbound method %s%s must be "
 | 
									     "unbound method %s%s must be "
 | 
				
			||||||
				     "called with instance as first argument",
 | 
									     "called with instance as first argument",
 | 
				
			||||||
				     get_func_name(func), get_func_desc(func));
 | 
									     PyEval_GetFuncName(func),
 | 
				
			||||||
 | 
									     PyEval_GetFuncDesc(func));
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Py_INCREF(arg);
 | 
							Py_INCREF(arg);
 | 
				
			||||||
| 
						 | 
					@ -3199,7 +3182,7 @@ call_eval_code2(PyObject *func, PyObject *arg, PyObject *kw)
 | 
				
			||||||
		nk = 0;
 | 
							nk = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = eval_code2(
 | 
						result = PyEval_EvalCodeEx(
 | 
				
			||||||
		(PyCodeObject *)PyFunction_GET_CODE(func),
 | 
							(PyCodeObject *)PyFunction_GET_CODE(func),
 | 
				
			||||||
		PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
 | 
							PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
 | 
				
			||||||
		&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
 | 
							&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
 | 
				
			||||||
| 
						 | 
					@ -3255,7 +3238,7 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
 | 
				
			||||||
		d = &PyTuple_GET_ITEM(argdefs, 0);
 | 
							d = &PyTuple_GET_ITEM(argdefs, 0);
 | 
				
			||||||
		nd = ((PyTupleObject *)argdefs)->ob_size;
 | 
							nd = ((PyTupleObject *)argdefs)->ob_size;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return eval_code2((PyCodeObject *)co, globals,
 | 
						return PyEval_EvalCodeEx((PyCodeObject *)co, globals,
 | 
				
			||||||
			  (PyObject *)NULL, (*pp_stack)-n, na,
 | 
								  (PyObject *)NULL, (*pp_stack)-n, na,
 | 
				
			||||||
			  (*pp_stack)-2*nk, nk, d, nd,
 | 
								  (*pp_stack)-2*nk, nk, d, nd,
 | 
				
			||||||
			  closure);
 | 
								  closure);
 | 
				
			||||||
| 
						 | 
					@ -3282,8 +3265,8 @@ update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
 | 
				
			||||||
                        PyErr_Format(PyExc_TypeError,
 | 
					                        PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
                                     "%.200s%s got multiple values "
 | 
					                                     "%.200s%s got multiple values "
 | 
				
			||||||
                                     "for keyword argument '%.200s'",
 | 
					                                     "for keyword argument '%.200s'",
 | 
				
			||||||
				     get_func_name(func),
 | 
									     PyEval_GetFuncName(func),
 | 
				
			||||||
				     get_func_desc(func),
 | 
									     PyEval_GetFuncDesc(func),
 | 
				
			||||||
				     PyString_AsString(key));
 | 
									     PyString_AsString(key));
 | 
				
			||||||
			Py_DECREF(key);
 | 
								Py_DECREF(key);
 | 
				
			||||||
			Py_DECREF(value);
 | 
								Py_DECREF(value);
 | 
				
			||||||
| 
						 | 
					@ -3356,7 +3339,7 @@ do_call(PyObject *func, PyObject ***pp_stack, int na, int nk)
 | 
				
			||||||
	callargs = load_args(pp_stack, na);
 | 
						callargs = load_args(pp_stack, na);
 | 
				
			||||||
	if (callargs == NULL)
 | 
						if (callargs == NULL)
 | 
				
			||||||
		goto call_fail;
 | 
							goto call_fail;
 | 
				
			||||||
	result = call_object(func, callargs, kwdict);
 | 
						result = PyObject_Call(func, callargs, kwdict);
 | 
				
			||||||
 call_fail:
 | 
					 call_fail:
 | 
				
			||||||
	Py_XDECREF(callargs);
 | 
						Py_XDECREF(callargs);
 | 
				
			||||||
	Py_XDECREF(kwdict);
 | 
						Py_XDECREF(kwdict);
 | 
				
			||||||
| 
						 | 
					@ -3378,8 +3361,8 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
 | 
				
			||||||
			PyErr_Format(PyExc_TypeError,
 | 
								PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
				     "%s%s argument after ** "
 | 
									     "%s%s argument after ** "
 | 
				
			||||||
				     "must be a dictionary",
 | 
									     "must be a dictionary",
 | 
				
			||||||
				     get_func_name(func),
 | 
									     PyEval_GetFuncName(func),
 | 
				
			||||||
				     get_func_desc(func));
 | 
									     PyEval_GetFuncDesc(func));
 | 
				
			||||||
			goto ext_call_fail;
 | 
								goto ext_call_fail;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -3393,8 +3376,8 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
 | 
				
			||||||
					PyErr_Format(PyExc_TypeError,
 | 
										PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
						     "%s%s argument after * "
 | 
											     "%s%s argument after * "
 | 
				
			||||||
						     "must be a sequence",
 | 
											     "must be a sequence",
 | 
				
			||||||
						     get_func_name(func),
 | 
											     PyEval_GetFuncName(func),
 | 
				
			||||||
						     get_func_desc(func));
 | 
											     PyEval_GetFuncDesc(func));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				goto ext_call_fail;
 | 
									goto ext_call_fail;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -3411,7 +3394,7 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
 | 
				
			||||||
	callargs = update_star_args(na, nstar, stararg, pp_stack);
 | 
						callargs = update_star_args(na, nstar, stararg, pp_stack);
 | 
				
			||||||
	if (callargs == NULL)
 | 
						if (callargs == NULL)
 | 
				
			||||||
		goto ext_call_fail;
 | 
							goto ext_call_fail;
 | 
				
			||||||
	result = call_object(func, callargs, kwdict);
 | 
						result = PyObject_Call(func, callargs, kwdict);
 | 
				
			||||||
      ext_call_fail:
 | 
					      ext_call_fail:
 | 
				
			||||||
	Py_XDECREF(callargs);
 | 
						Py_XDECREF(callargs);
 | 
				
			||||||
	Py_XDECREF(kwdict);
 | 
						Py_XDECREF(kwdict);
 | 
				
			||||||
| 
						 | 
					@ -3632,63 +3615,25 @@ import_all_from(PyObject *locals, PyObject *v)
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
build_class(PyObject *methods, PyObject *bases, PyObject *name)
 | 
					build_class(PyObject *methods, PyObject *bases, PyObject *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, n;
 | 
						PyObject *metaclass = NULL;
 | 
				
			||||||
	if (!PyTuple_Check(bases)) {
 | 
					
 | 
				
			||||||
		PyErr_SetString(PyExc_SystemError,
 | 
						if (PyDict_Check(methods))
 | 
				
			||||||
				"build_class with non-tuple bases");
 | 
							metaclass = PyDict_GetItemString(methods, "__metaclass__");
 | 
				
			||||||
		return NULL;
 | 
					
 | 
				
			||||||
	}
 | 
						if (metaclass == NULL) {
 | 
				
			||||||
	if (!PyDict_Check(methods)) {
 | 
							if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0)
 | 
				
			||||||
		PyErr_SetString(PyExc_SystemError,
 | 
								metaclass = (PyObject *)
 | 
				
			||||||
				"build_class with non-dictionary");
 | 
									PyTuple_GET_ITEM(bases, 0)->ob_type;
 | 
				
			||||||
		return NULL;
 | 
							else {
 | 
				
			||||||
	}
 | 
								PyObject *g = PyEval_GetGlobals();
 | 
				
			||||||
	if (!PyString_Check(name)) {
 | 
								if (g != NULL && PyDict_Check(g))
 | 
				
			||||||
		PyErr_SetString(PyExc_SystemError,
 | 
									metaclass = PyDict_GetItemString(
 | 
				
			||||||
				"build_class with non-string name");
 | 
										g, "__metaclass__");
 | 
				
			||||||
		return NULL;
 | 
								if (metaclass == NULL)
 | 
				
			||||||
	}
 | 
									metaclass = (PyObject *) &PyClass_Type;
 | 
				
			||||||
	n = PyTuple_Size(bases);
 | 
					 | 
				
			||||||
	for (i = 0; i < n; i++) {
 | 
					 | 
				
			||||||
		PyObject *base = PyTuple_GET_ITEM(bases, i);
 | 
					 | 
				
			||||||
		if (!PyClass_Check(base)) {
 | 
					 | 
				
			||||||
			/* Call the base's *type*, if it is callable.
 | 
					 | 
				
			||||||
			   This code is a hook for Donald Beaudry's
 | 
					 | 
				
			||||||
			   and Jim Fulton's type extensions.  In
 | 
					 | 
				
			||||||
			   unextended Python it will never be triggered
 | 
					 | 
				
			||||||
			   since its types are not callable.
 | 
					 | 
				
			||||||
			   Ditto: call the bases's *class*, if it has
 | 
					 | 
				
			||||||
			   one.  This makes the same thing possible
 | 
					 | 
				
			||||||
			   without writing C code.  A true meta-object
 | 
					 | 
				
			||||||
			   protocol! */
 | 
					 | 
				
			||||||
			PyObject *basetype = (PyObject *)base->ob_type;
 | 
					 | 
				
			||||||
			PyObject *callable = NULL;
 | 
					 | 
				
			||||||
			if (PyCallable_Check(basetype))
 | 
					 | 
				
			||||||
				callable = basetype;
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				callable = PyObject_GetAttrString(
 | 
					 | 
				
			||||||
					base, "__class__");
 | 
					 | 
				
			||||||
			if (callable) {
 | 
					 | 
				
			||||||
				PyObject *args;
 | 
					 | 
				
			||||||
				PyObject *newclass = NULL;
 | 
					 | 
				
			||||||
				args = Py_BuildValue(
 | 
					 | 
				
			||||||
					"(OOO)", name, bases, methods);
 | 
					 | 
				
			||||||
				if (args != NULL) {
 | 
					 | 
				
			||||||
					newclass = PyEval_CallObject(
 | 
					 | 
				
			||||||
						callable, args);
 | 
					 | 
				
			||||||
					Py_DECREF(args);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (callable != basetype) {
 | 
					 | 
				
			||||||
					Py_DECREF(callable);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return newclass;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			PyErr_SetString(PyExc_TypeError,
 | 
					 | 
				
			||||||
				"base is not a class object");
 | 
					 | 
				
			||||||
			return NULL;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return PyClass_New(bases, methods, name);
 | 
						return PyObject_CallFunction(metaclass, "OOO", name, bases, methods);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1056,23 +1056,36 @@ static struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DL_EXPORT(void)
 | 
					DL_EXPORT(void)
 | 
				
			||||||
init_exceptions(void)
 | 
					_PyExc_Init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *modulename = "exceptions";
 | 
					    char *modulename = "exceptions";
 | 
				
			||||||
    int modnamesz = strlen(modulename);
 | 
					    int modnamesz = strlen(modulename);
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
 | 
					    PyObject *me, *mydict, *bltinmod, *bdict, *doc, *args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PyObject *me = Py_InitModule(modulename, functions);
 | 
					    me = Py_InitModule(modulename, functions);
 | 
				
			||||||
    PyObject *mydict = PyModule_GetDict(me);
 | 
					    if (me == NULL)
 | 
				
			||||||
    PyObject *bltinmod = PyImport_ImportModule("__builtin__");
 | 
						goto err;
 | 
				
			||||||
    PyObject *bdict = PyModule_GetDict(bltinmod);
 | 
					    mydict = PyModule_GetDict(me);
 | 
				
			||||||
    PyObject *doc = PyString_FromString(module__doc__);
 | 
					    if (mydict == NULL)
 | 
				
			||||||
    PyObject *args;
 | 
						goto err;
 | 
				
			||||||
 | 
					    bltinmod = PyImport_ImportModule("__builtin__");
 | 
				
			||||||
 | 
					    if (bltinmod == NULL)
 | 
				
			||||||
 | 
						goto err;
 | 
				
			||||||
 | 
					    bdict = PyModule_GetDict(bltinmod);
 | 
				
			||||||
 | 
					    if (bdict == NULL)
 | 
				
			||||||
 | 
						goto err;
 | 
				
			||||||
 | 
					    doc = PyString_FromString(module__doc__);
 | 
				
			||||||
 | 
					    if (doc == NULL)
 | 
				
			||||||
 | 
						goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PyDict_SetItemString(mydict, "__doc__", doc);
 | 
					    i = PyDict_SetItemString(mydict, "__doc__", doc);
 | 
				
			||||||
    Py_DECREF(doc);
 | 
					    Py_DECREF(doc);
 | 
				
			||||||
    if (PyErr_Occurred())
 | 
					    if (i < 0) {
 | 
				
			||||||
 | 
					 err:
 | 
				
			||||||
	Py_FatalError("exceptions bootstrapping error.");
 | 
						Py_FatalError("exceptions bootstrapping error.");
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* This is the base class of all exceptions, so make it first. */
 | 
					    /* This is the base class of all exceptions, so make it first. */
 | 
				
			||||||
    if (make_Exception(modulename) ||
 | 
					    if (make_Exception(modulename) ||
 | 
				
			||||||
| 
						 | 
					@ -1139,7 +1152,7 @@ init_exceptions(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DL_EXPORT(void)
 | 
					DL_EXPORT(void)
 | 
				
			||||||
fini_exceptions(void)
 | 
					_PyExc_Fini(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
 | 
				
			||||||
/* XXX Perhaps the magic number should be frozen and a version field
 | 
					/* XXX Perhaps the magic number should be frozen and a version field
 | 
				
			||||||
   added to the .pyc file header? */
 | 
					   added to the .pyc file header? */
 | 
				
			||||||
/* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */
 | 
					/* 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
 | 
					/* Magic word as global; note that _PyImport_Init() can change the
 | 
				
			||||||
   value of this global to accommodate for alterations of how 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 */
 | 
						/* Get the __import__ function from the builtins */
 | 
				
			||||||
	if (PyDict_Check(builtins))
 | 
						if (PyDict_Check(builtins)) {
 | 
				
			||||||
		import = PyObject_GetItem(builtins, import_str);
 | 
							import = PyObject_GetItem(builtins, import_str);
 | 
				
			||||||
 | 
							if (import == NULL)
 | 
				
			||||||
 | 
								PyErr_SetObject(PyExc_KeyError, import_str);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		import = PyObject_GetAttr(builtins, import_str);
 | 
							import = PyObject_GetAttr(builtins, import_str);
 | 
				
			||||||
	if (import == NULL)
 | 
						if (import == NULL)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,6 +115,9 @@ Py_Initialize(void)
 | 
				
			||||||
		Py_FatalError("Py_Initialize: can't make first thread");
 | 
							Py_FatalError("Py_Initialize: can't make first thread");
 | 
				
			||||||
	(void) PyThreadState_Swap(tstate);
 | 
						(void) PyThreadState_Swap(tstate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (PyType_InitDict(&PyType_Type) < 0)
 | 
				
			||||||
 | 
							Py_FatalError("Py_Initialize: can't initialize 'type'");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	interp->modules = PyDict_New();
 | 
						interp->modules = PyDict_New();
 | 
				
			||||||
	if (interp->modules == NULL)
 | 
						if (interp->modules == NULL)
 | 
				
			||||||
		Py_FatalError("Py_Initialize: can't make modules dictionary");
 | 
							Py_FatalError("Py_Initialize: can't make modules dictionary");
 | 
				
			||||||
| 
						 | 
					@ -144,7 +147,7 @@ Py_Initialize(void)
 | 
				
			||||||
	_PyImport_Init();
 | 
						_PyImport_Init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* initialize builtin exceptions */
 | 
						/* initialize builtin exceptions */
 | 
				
			||||||
	init_exceptions();
 | 
						_PyExc_Init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* phase 2 of builtins */
 | 
						/* phase 2 of builtins */
 | 
				
			||||||
	_PyImport_FixupExtension("__builtin__", "__builtin__");
 | 
						_PyImport_FixupExtension("__builtin__", "__builtin__");
 | 
				
			||||||
| 
						 | 
					@ -238,7 +241,7 @@ Py_Finalize(void)
 | 
				
			||||||
	   below has been checked to make sure no exceptions are ever
 | 
						   below has been checked to make sure no exceptions are ever
 | 
				
			||||||
	   raised.
 | 
						   raised.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	fini_exceptions();
 | 
						_PyExc_Fini();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Delete current thread */
 | 
						/* Delete current thread */
 | 
				
			||||||
	PyInterpreterState_Clear(interp);
 | 
						PyInterpreterState_Clear(interp);
 | 
				
			||||||
| 
						 | 
					@ -1345,7 +1348,7 @@ _Py_AskYesNo(char *prompt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[256];
 | 
						char buf[256];
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	printf("%s [ny] ", prompt);
 | 
						fprintf(stderr, "%s [ny] ", prompt);
 | 
				
			||||||
	if (fgets(buf, sizeof buf, stdin) == NULL)
 | 
						if (fgets(buf, sizeof buf, stdin) == NULL)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	return buf[0] == 'y' || buf[0] == 'Y';
 | 
						return buf[0] == 'y' || buf[0] == 'Y';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue