⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 object.h

📁 python s60 1.4.5版本的源代码
💻 H
📖 第 1 页 / 共 2 页
字号:


/* PyObject_Dir(obj) acts like Python __builtin__.dir(obj), returning a
   list of strings.  PyObject_Dir(NULL) is like __builtin__.dir(),
   returning the names of the current locals.  In this case, if there are
   no current locals, NULL is returned, and PyErr_Occurred() is false.
*/
extern DL_IMPORT(PyObject *) PyObject_Dir(PyObject *);


/* Helpers for printing recursive container types */
extern DL_IMPORT(int) Py_ReprEnter(PyObject *);
extern DL_IMPORT(void) Py_ReprLeave(PyObject *);

/* Helpers for hash functions */
extern DL_IMPORT(long) _Py_HashDouble(double);
extern DL_IMPORT(long) _Py_HashPointer(void*);

/* Helper for passing objects to printf and the like */
#define PyObject_REPR(obj) PyString_AS_STRING(PyObject_Repr(obj))

/* Flag bits for printing: */
#define Py_PRINT_RAW	1	/* No string quotes etc. */

/*

Type flags (tp_flags)

These flags are used to extend the type structure in a backwards-compatible
fashion. Extensions can use the flags to indicate (and test) when a given
type structure contains a new feature. The Python core will use these when
introducing new functionality between major revisions (to avoid mid-version
changes in the PYTHON_API_VERSION).

Arbitration of the flag bit positions will need to be coordinated among
all extension writers who publically release their extensions (this will
be fewer than you might expect!)..

Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs.

Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value.

Code can use PyType_HasFeature(type_ob, flag_value) to test whether the
given type object has a specified feature.

*/

/* PyBufferProcs contains bf_getcharbuffer */
#define Py_TPFLAGS_HAVE_GETCHARBUFFER  (1L<<0)

/* PySequenceMethods contains sq_contains */
#define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1)

/* This is here for backwards compatibility.  Extensions that use the old GC
 * API will still compile but the objects will not be tracked by the GC. */
#define Py_TPFLAGS_GC 0 /* used to be (1L<<2) */

/* PySequenceMethods and PyNumberMethods contain in-place operators */
#define Py_TPFLAGS_HAVE_INPLACEOPS (1L<<3)

/* PyNumberMethods do their own coercion */
#define Py_TPFLAGS_CHECKTYPES (1L<<4)

/* tp_richcompare is defined */
#define Py_TPFLAGS_HAVE_RICHCOMPARE (1L<<5)

/* Objects which are weakly referencable if their tp_weaklistoffset is >0 */
#define Py_TPFLAGS_HAVE_WEAKREFS (1L<<6)

/* tp_iter is defined */
#define Py_TPFLAGS_HAVE_ITER (1L<<7)

/* New members introduced by Python 2.2 exist */
#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 is 'ready' -- fully initialized */
#define Py_TPFLAGS_READY (1L<<12)

/* Set while the type is being 'readied', to prevent recursive ready calls */
#define Py_TPFLAGS_READYING (1L<<13)

/* Objects support garbage collection (see objimp.h) */
#ifdef WITH_CYCLE_GC
#define Py_TPFLAGS_HAVE_GC (1L<<14)
#else
#define Py_TPFLAGS_HAVE_GC 0
#endif

#define Py_TPFLAGS_DEFAULT  ( \
                             Py_TPFLAGS_HAVE_GETCHARBUFFER | \
                             Py_TPFLAGS_HAVE_SEQUENCE_IN | \
                             Py_TPFLAGS_HAVE_INPLACEOPS | \
                             Py_TPFLAGS_HAVE_RICHCOMPARE | \
                             Py_TPFLAGS_HAVE_WEAKREFS | \
                             Py_TPFLAGS_HAVE_ITER | \
                             Py_TPFLAGS_HAVE_CLASS | \
                            0)

#define PyType_HasFeature(t,f)  (((t)->tp_flags & (f)) != 0)


/*
The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement
reference counts.  Py_DECREF calls the object's deallocator function; for
objects that don't contain references to other objects or heap memory
this can be the standard function free().  Both macros can be used
wherever a void expression is allowed.  The argument shouldn't be a
NIL pointer.  The macro _Py_NewReference(op) is used only to initialize
reference counts to 1; it is defined here for convenience.

We assume that the reference count field can never overflow; this can
be proven when the size of the field is the same as the pointer size
but even with a 16-bit reference count field it is pretty unlikely so
we ignore the possibility.  (If you are paranoid, make it a long.)

Type objects should never be deallocated; the type pointer in an object
is not considered to be a reference to the type object, to save
complications in the deallocation function.  (This is actually a
decision that's up to the implementer of each new type so if you want,
you can count such references to the type object.)

*** WARNING*** The Py_DECREF macro must have a side-effect-free argument
since it may evaluate its argument multiple times.  (The alternative
would be to mace it a proper function or assign it to a global temporary
variable first, both of which are slower; and in a multi-threaded
environment the global variable trick is not safe.)
*/

#ifdef Py_TRACE_REFS
#ifndef Py_REF_DEBUG
#define Py_REF_DEBUG
#endif
#endif

#ifdef Py_TRACE_REFS
extern DL_IMPORT(void) _Py_Dealloc(PyObject *);
extern DL_IMPORT(void) _Py_NewReference(PyObject *);
extern DL_IMPORT(void) _Py_ForgetReference(PyObject *);
extern DL_IMPORT(void) _Py_PrintReferences(FILE *);
extern DL_IMPORT(void) _Py_ResetReferences(void);
#endif

#ifndef Py_TRACE_REFS
#ifdef COUNT_ALLOCS
#define _Py_Dealloc(op) ((op)->ob_type->tp_frees++, (*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
#define _Py_ForgetReference(op) ((op)->ob_type->tp_frees++)
#else /* !COUNT_ALLOCS */
#define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op))
#define _Py_ForgetReference(op) /*empty*/
#endif /* !COUNT_ALLOCS */
#endif /* !Py_TRACE_REFS */

#ifdef COUNT_ALLOCS
extern DL_IMPORT(void) inc_count(PyTypeObject *);
#endif

#ifdef Py_REF_DEBUG

extern DL_IMPORT(long) _Py_RefTotal;

#ifndef Py_TRACE_REFS
#ifdef COUNT_ALLOCS
#define _Py_NewReference(op) (inc_count((op)->ob_type), _Py_RefTotal++, (op)->ob_refcnt = 1)
#else
#define _Py_NewReference(op) (_Py_RefTotal++, (op)->ob_refcnt = 1)
#endif
#endif /* !Py_TRACE_REFS */

#define Py_INCREF(op) (_Py_RefTotal++, (op)->ob_refcnt++)
  /* under Py_REF_DEBUG: also log negative ref counts after Py_DECREF() !! */
#define Py_DECREF(op)							\
       if (--_Py_RefTotal, 0 < (--((op)->ob_refcnt))) ;			\
       else if (0 == (op)->ob_refcnt) _Py_Dealloc( (PyObject*)(op));	\
       else (void)fprintf( stderr, "%s:%i negative ref count %i\n",	\
		           __FILE__, __LINE__, (op)->ob_refcnt)
#else /* !Py_REF_DEBUG */

#ifdef COUNT_ALLOCS
#define _Py_NewReference(op) (inc_count((op)->ob_type), (op)->ob_refcnt = 1)
#else
#define _Py_NewReference(op) ((op)->ob_refcnt = 1)
#endif

#define Py_INCREF(op) ((op)->ob_refcnt++)
#define Py_DECREF(op) \
	if (--(op)->ob_refcnt != 0) \
		; \
	else \
		_Py_Dealloc((PyObject *)(op))
#endif /* !Py_REF_DEBUG */

/* Macros to use in case the object pointer may be NULL: */

#define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op)
#define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op)

/*
_Py_NoneStruct is an object of undefined type which can be used in contexts
where NULL (nil) is not suitable (since NULL often means 'error').

Don't forget to apply Py_INCREF() when returning this value!!!
*/

  /* extern DL_IMPORT(const PyObject) _Py_NoneStruct; *//* Don't use this directly */

#define Py_None (&(PYTHON_GLOBALS->_Py_NoneStruct))

#define PyNone_Type ((PYTHON_GLOBALS->tobj).t_PyNone)
#define PyNotImplemented_Type ((PYTHON_GLOBALS->tobj).t_PyNotImplemented)

/*
Py_NotImplemented is a singleton used to signal that an operation is
not implemented for a given type combination.
*/

  /* extern DL_IMPORT(const PyObject) _Py_NotImplementedStruct; *//* Don't use this directly */

#define Py_NotImplemented (&(PYTHON_GLOBALS->_Py_NotImplementedStruct))

/* Rich comparison opcodes */
#define Py_LT 0
#define Py_LE 1
#define Py_EQ 2
#define Py_NE 3
#define Py_GT 4
#define Py_GE 5

/*
A common programming style in Python requires the forward declaration
of static, initialized structures, e.g. for a type object that is used
by the functions whose address must be used in the initializer.
Some compilers (notably SCO ODT 3.0, I seem to remember early AIX as
well) botch this if you use the static keyword for both declarations
(they allocate two objects, and use the first, uninitialized one until
the second declaration is encountered).  Therefore, the forward
declaration should use the 'forwardstatic' keyword.  This expands to
static on most systems, but to extern on a few.  The actual storage
and name will still be static because the second declaration is
static, so no linker visible symbols will be generated.  (Standard C
compilers take offense to the extern forward declaration of a static
object, so I can't just put extern in all cases. :-( )
*/

#ifdef BAD_STATIC_FORWARD
#define staticforward extern
#define statichere static
#else /* !BAD_STATIC_FORWARD */
#define staticforward static
#define statichere static
#endif /* !BAD_STATIC_FORWARD */


/*
More conventions
================

Argument Checking
-----------------

Functions that take objects as arguments normally don't check for nil
arguments, but they do check the type of the argument, and return an
error if the function doesn't apply to the type.

Failure Modes
-------------

Functions may fail for a variety of reasons, including running out of
memory.  This is communicated to the caller in two ways: an error string
is set (see errors.h), and the function result differs: functions that
normally return a pointer return NULL for failure, functions returning
an integer return -1 (which could be a legal return value too!), and
other functions return 0 for success and -1 for failure.
Callers should always check for errors before using the result.

Reference Counts
----------------

It takes a while to get used to the proper usage of reference counts.

Functions that create an object set the reference count to 1; such new
objects must be stored somewhere or destroyed again with Py_DECREF().
Functions that 'store' objects such as PyTuple_SetItem() and
PyDict_SetItemString()
don't increment the reference count of the object, since the most
frequent use is to store a fresh object.  Functions that 'retrieve'
objects such as PyTuple_GetItem() and PyDict_GetItemString() also
don't increment
the reference count, since most frequently the object is only looked at
quickly.  Thus, to retrieve an object and store it again, the caller
must call Py_INCREF() explicitly.

NOTE: functions that 'consume' a reference count like
PyList_SetItemString() even consume the reference if the object wasn't
stored, to simplify error handling.

It seems attractive to make other functions that take an object as
argument consume a reference count; however this may quickly get
confusing (even the current practice is already confusing).  Consider
it carefully, it may save lots of calls to Py_INCREF() and Py_DECREF() at
times.
*/

/*
  trashcan
  CT 2k0130
  non-recursively destroy nested objects

  CT 2k0223
  redefinition for better locality and less overhead.

  Objects that want to be recursion safe need to use
  the macro's
		Py_TRASHCAN_SAFE_BEGIN(name)
  and
		Py_TRASHCAN_SAFE_END(name)
  surrounding their actual deallocation code.

  It would be nice to do this using the thread state.
  Also, we could do an exact stack measure then.
  Unfortunately, deallocations also take place when
  the thread state is undefined.

  CT 2k0422 complete rewrite.
  There is no need to allocate new objects.
  Everything is done vialob_refcnt and ob_type now.
  Adding support for free-threading should be easy, too.
*/

#define PyTrash_UNWIND_LEVEL 50

#define Py_TRASHCAN_SAFE_BEGIN(op) \
	{ \
		++(PYTHON_GLOBALS->_PyTrash_delete_nesting); \
		if ((PYTHON_GLOBALS->_PyTrash_delete_nesting) < PyTrash_UNWIND_LEVEL) { \

#define Py_TRASHCAN_SAFE_END(op) \
		;} \
		else \
			_PyTrash_deposit_object((PyObject*)op);\
		--(PYTHON_GLOBALS->_PyTrash_delete_nesting); \
		if ((PYTHON_GLOBALS->_PyTrash_delete_later) && \
                  (PYTHON_GLOBALS->_PyTrash_delete_nesting) <= 0) \
			_PyTrash_destroy_chain(); \
	} \

extern DL_IMPORT(void) _PyTrash_deposit_object(PyObject*);
extern DL_IMPORT(void) _PyTrash_destroy_chain(void);

  /* extern DL_IMPORT(int) _PyTrash_delete_nesting; */
  /* extern DL_IMPORT(PyObject *) _PyTrash_delete_later; */

/* swap the "xx" to check the speed loss */

#define xxPy_TRASHCAN_SAFE_BEGIN(op)
#define xxPy_TRASHCAN_SAFE_END(op) ;

#ifdef __cplusplus
}
#endif
#endif /* !Py_OBJECT_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -