mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
Backported PyCapsule from 3.1, and converted most uses of
CObject to PyCapsule.
This commit is contained in:
parent
53ff86ea5f
commit
402b73fb8d
40 changed files with 1048 additions and 127 deletions
|
@ -107,6 +107,7 @@
|
|||
#include "classobject.h"
|
||||
#include "fileobject.h"
|
||||
#include "cobject.h"
|
||||
#include "pycapsule.h"
|
||||
#include "traceback.h"
|
||||
#include "sliceobject.h"
|
||||
#include "cellobject.h"
|
||||
|
|
|
@ -18,9 +18,12 @@ extern "C" {
|
|||
This would typically be done in your init function.
|
||||
|
||||
*/
|
||||
|
||||
#define PycStringIO_CAPSULE_NAME "cStringIO.cStringIO_CAPI"
|
||||
|
||||
#define PycString_IMPORT \
|
||||
PycStringIO = (struct PycStringIO_CAPI*)PyCObject_Import("cStringIO", \
|
||||
"cStringIO_CAPI")
|
||||
PycStringIO = ((struct PycStringIO_CAPI*)PyCapsule_Import(\
|
||||
PycStringIO_CAPSULE_NAME, 0))
|
||||
|
||||
/* Basic functions to manipulate cStringIO objects from C */
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
to other extension modules, so that extension modules can use the
|
||||
Python import mechanism to link to one another.
|
||||
|
||||
DEPRECATED - Use PyCapsule objects instead.
|
||||
CObject will be removed in 2.8 (if there is one).
|
||||
*/
|
||||
|
||||
#ifndef Py_COBJECT_H
|
||||
|
|
|
@ -158,6 +158,8 @@ typedef struct {
|
|||
|
||||
} PyDateTime_CAPI;
|
||||
|
||||
#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI"
|
||||
|
||||
|
||||
/* "magic" constant used to partially protect against developer mistakes. */
|
||||
#define DATETIME_API_MAGIC 0x414548d5
|
||||
|
@ -186,15 +188,7 @@ typedef struct {
|
|||
static PyDateTime_CAPI *PyDateTimeAPI = NULL;
|
||||
|
||||
#define PyDateTime_IMPORT \
|
||||
PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import("datetime", \
|
||||
"datetime_CAPI")
|
||||
|
||||
/* This macro would be used if PyCObject_ImportEx() was created.
|
||||
#define PyDateTime_IMPORT \
|
||||
PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_ImportEx("datetime", \
|
||||
"datetime_CAPI", \
|
||||
DATETIME_API_MAGIC)
|
||||
*/
|
||||
PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0)
|
||||
|
||||
/* Macros for type checking when not building the Python core. */
|
||||
#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
|
||||
|
|
|
@ -80,6 +80,9 @@ typedef struct {
|
|||
|
||||
#define PyCursesWindow_Check(v) (Py_TYPE(v) == &PyCursesWindow_Type)
|
||||
|
||||
#define PyCurses_CAPSULE_NAME "_curses._C_API"
|
||||
|
||||
|
||||
#ifdef CURSES_MODULE
|
||||
/* This section is used when compiling _cursesmodule.c */
|
||||
|
||||
|
@ -94,16 +97,8 @@ static void **PyCurses_API;
|
|||
#define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;}
|
||||
|
||||
#define import_curses() \
|
||||
{ \
|
||||
PyObject *module = PyImport_ImportModuleNoBlock("_curses"); \
|
||||
if (module != NULL) { \
|
||||
PyObject *module_dict = PyModule_GetDict(module); \
|
||||
PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \
|
||||
if (PyCObject_Check(c_api_object)) { \
|
||||
PyCurses_API = (void **)PyCObject_AsVoidPtr(c_api_object); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
PyCurses_API = (void **)PyCapsule_Import(PyCurses_CAPSULE_NAME, 1);
|
||||
|
||||
#endif
|
||||
|
||||
/* general error messages */
|
||||
|
|
148
Include/pycapsule.h
Normal file
148
Include/pycapsule.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
|
||||
/* Capsule objects let you wrap a C "void *" pointer in a Python
|
||||
object. They're a way of passing data through the Python interpreter
|
||||
without creating your own custom type.
|
||||
|
||||
Capsules are used for communication between extension modules.
|
||||
They provide a way for an extension module to export a C interface
|
||||
to other extension modules, so that extension modules can use the
|
||||
Python import mechanism to link to one another.
|
||||
|
||||
For more information, please see "c-api/capsule.html" in the
|
||||
documentation.
|
||||
*/
|
||||
|
||||
#ifndef Py_CAPSULE_H
|
||||
#define Py_CAPSULE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyCapsule_Type;
|
||||
|
||||
typedef void (*PyCapsule_Destructor)(PyObject *);
|
||||
|
||||
#define PyCapsule_CheckExact(op) (Py_TYPE(op) == &PyCapsule_Type)
|
||||
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCapsule_New(
|
||||
void *pointer,
|
||||
const char *name,
|
||||
PyCapsule_Destructor destructor);
|
||||
|
||||
PyAPI_FUNC(void *) PyCapsule_GetPointer(PyObject *capsule, const char *name);
|
||||
|
||||
PyAPI_FUNC(PyCapsule_Destructor) PyCapsule_GetDestructor(PyObject *capsule);
|
||||
|
||||
PyAPI_FUNC(const char *) PyCapsule_GetName(PyObject *capsule);
|
||||
|
||||
PyAPI_FUNC(void *) PyCapsule_GetContext(PyObject *capsule);
|
||||
|
||||
PyAPI_FUNC(int) PyCapsule_IsValid(PyObject *capsule, const char *name);
|
||||
|
||||
PyAPI_FUNC(int) PyCapsule_SetPointer(PyObject *capsule, void *pointer);
|
||||
|
||||
PyAPI_FUNC(int) PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor);
|
||||
|
||||
PyAPI_FUNC(int) PyCapsule_SetName(PyObject *capsule, const char *name);
|
||||
|
||||
PyAPI_FUNC(int) PyCapsule_SetContext(PyObject *capsule, void *context);
|
||||
|
||||
PyAPI_FUNC(void *) PyCapsule_Import(const char *name, int no_block);
|
||||
|
||||
|
||||
#define PYTHON_USING_CAPSULE
|
||||
|
||||
#define PYCAPSULE_INSTANTIATE_DESTRUCTOR(name, destructor) \
|
||||
static void pycapsule_destructor_ ## name(PyObject *ptr) \
|
||||
{ \
|
||||
void *p = PyCapsule_GetPointer(ptr, name); \
|
||||
if (p) { \
|
||||
destructor(p); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define PYCAPSULE_NEW(pointer, name) \
|
||||
(PyCapsule_New(pointer, name, capsule_destructor_ ## name))
|
||||
|
||||
#define PYCAPSULE_ISVALID(capsule, name) \
|
||||
(PyCapsule_IsValid(capsule, name))
|
||||
|
||||
#define PYCAPSULE_DEREFERENCE(capsule, name) \
|
||||
(PyCapsule_GetPointer(capsule, name))
|
||||
|
||||
#define PYCAPSULE_SET(capsule, name, value) \
|
||||
(PyCapsule_IsValid(capsule, name) && PyCapsule_SetPointer(capsule, value))
|
||||
|
||||
/* module and attribute should be specified as string constants */
|
||||
#define PYCAPSULE_IMPORT(module, attribute) \
|
||||
(PyCapsule_Import(module "." attribute, 0))
|
||||
|
||||
|
||||
/* begin public-domain code */
|
||||
/*
|
||||
** This code was written by Larry Hastings,
|
||||
** and is dedicated to the public domain.
|
||||
** It's designed to make it easy to switch
|
||||
** from CObject to Capsule objects without losing
|
||||
** backwards compatibility with prior versions
|
||||
** of CPython. You're encouraged to copy this code
|
||||
** (including this documentation) into your
|
||||
** Python C extension.
|
||||
**
|
||||
** To use:
|
||||
** * #define a name for the pointer you store in
|
||||
** the CObject. If you make the CObject available
|
||||
** as part of your module's API, this name should
|
||||
** be "modulename.attributename", and it should be
|
||||
** considered part of your API (so put it in your
|
||||
** header file).
|
||||
** * Specify a PYCAPSULE_INSTANTIATE_DESTRUCTOR(), in
|
||||
** every C file that creates these CObjects. This
|
||||
** is where you specify your object's destructor.
|
||||
** * Change all calls to CObject_FromVoidPtr()
|
||||
** and CObject_FromVoidPointerAndDesc() into
|
||||
** PYCAPSULE_NEW() calls.
|
||||
** * Change all calls to PyCObject_AsVoidPtr()
|
||||
** into PYCAPSULE_DEREFERENCE() calls.
|
||||
** * Change all calls to PyCObject_SetVoidPtr()
|
||||
** into PYCAPSULE_SET() calls.
|
||||
** * Change all calls to PyCObject_Import()
|
||||
** into PYCAPSULE_IMPORT() calls. Note that
|
||||
** the two arguments to PYCAPSULE_IMPORT()
|
||||
** should both be string constants; that is,
|
||||
** you should call
|
||||
** PYCAPSULE_IMPORT("modulename", "attributename"),
|
||||
** not PYCAPSULE_IMPORT(charstar1, charstar2).
|
||||
*/
|
||||
#ifndef PYTHON_USING_CAPSULE
|
||||
|
||||
#define PYCAPSULE_INSTANTIATE_DESTRUCTOR(name, destructor) \
|
||||
static void pycapsule_destructor_ ## name(void *ptr) \
|
||||
{ \
|
||||
destructor(p); \
|
||||
} \
|
||||
|
||||
#define PYCAPSULE_NEW(pointer, name) \
|
||||
(PyCObject_FromVoidPtr(pointer, pycapsule_destructor_ ## name))
|
||||
|
||||
#define PYCAPSULE_ISVALID(capsule, name) \
|
||||
(PyCObject_Check(capsule))
|
||||
|
||||
#define PYCAPSULE_DEREFERENCE(capsule, name) \
|
||||
(PyCObject_AsVoidPtr(capsule))
|
||||
|
||||
#define PYCAPSULE_SET(capsule, name, value) \
|
||||
(PyCObject_SetVoidPtr(capsule, value))
|
||||
|
||||
/* module and attribute should be specified as string constants */
|
||||
#define PYCAPSULE_IMPORT(module, attribute) \
|
||||
(PyCObject_Import(module, attribute))
|
||||
|
||||
#endif /* PYTHON_USING_CAPSULE */
|
||||
/* end public-domain code */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_CAPSULE_H */
|
|
@ -4,6 +4,7 @@
|
|||
/* note: you must import expat.h before importing this module! */
|
||||
|
||||
#define PyExpat_CAPI_MAGIC "pyexpat.expat_CAPI 1.0"
|
||||
#define PyExpat_CAPSULE_NAME "pyexpat.expat_CAPI"
|
||||
|
||||
struct PyExpat_CAPI
|
||||
{
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* revised ucnhash CAPI interface (exported through a PyCObject) */
|
||||
/* revised ucnhash CAPI interface (exported through a "wrapper") */
|
||||
|
||||
#define PyUnicodeData_CAPSULE_NAME "unicodedata.ucnhash_CAPI"
|
||||
|
||||
typedef struct {
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue