mirror of https://github.com/python/cpython.git
gh-103583: Add ref. dependency between multibytecodec modules (#103589)
This commit is contained in:
parent
bd2ed066c8
commit
a6b07b5a34
|
@ -284,18 +284,45 @@ getmultibytecodec(void)
|
||||||
return _PyImport_GetModuleAttrString("_multibytecodec", "__create_codec");
|
return _PyImport_GetModuleAttrString("_multibytecodec", "__create_codec");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_codec_capsule(PyObject *capsule)
|
||||||
|
{
|
||||||
|
void *ptr = PyCapsule_GetPointer(capsule, CODEC_CAPSULE);
|
||||||
|
codec_capsule *data = (codec_capsule *)ptr;
|
||||||
|
Py_DECREF(data->cjk_module);
|
||||||
|
PyMem_Free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static codec_capsule *
|
||||||
|
capsulate_codec(PyObject *mod, const MultibyteCodec *codec)
|
||||||
|
{
|
||||||
|
codec_capsule *data = PyMem_Malloc(sizeof(codec_capsule));
|
||||||
|
if (data == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
data->codec = codec;
|
||||||
|
data->cjk_module = Py_NewRef(mod);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_getcodec(const MultibyteCodec *codec)
|
_getcodec(PyObject *self, const MultibyteCodec *codec)
|
||||||
{
|
{
|
||||||
PyObject *cofunc = getmultibytecodec();
|
PyObject *cofunc = getmultibytecodec();
|
||||||
if (cofunc == NULL) {
|
if (cofunc == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *codecobj = PyCapsule_New((void *)codec,
|
codec_capsule *data = capsulate_codec(self, codec);
|
||||||
PyMultibyteCodec_CAPSULE_NAME,
|
if (data == NULL) {
|
||||||
NULL);
|
Py_DECREF(cofunc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyObject *codecobj = PyCapsule_New(data, CODEC_CAPSULE,
|
||||||
|
destroy_codec_capsule);
|
||||||
if (codecobj == NULL) {
|
if (codecobj == NULL) {
|
||||||
|
PyMem_Free(data);
|
||||||
Py_DECREF(cofunc);
|
Py_DECREF(cofunc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -323,7 +350,7 @@ getcodec(PyObject *self, PyObject *encoding)
|
||||||
for (int i = 0; i < st->num_codecs; i++) {
|
for (int i = 0; i < st->num_codecs; i++) {
|
||||||
const MultibyteCodec *codec = &st->codec_list[i];
|
const MultibyteCodec *codec = &st->codec_list[i];
|
||||||
if (strcmp(codec->encoding, enc) == 0) {
|
if (strcmp(codec->encoding, enc) == 0) {
|
||||||
return _getcodec(codec);
|
return _getcodec(self, codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,8 +379,7 @@ register_maps(PyObject *module)
|
||||||
char mhname[256] = "__map_";
|
char mhname[256] = "__map_";
|
||||||
strcpy(mhname + sizeof("__map_") - 1, h->charset);
|
strcpy(mhname + sizeof("__map_") - 1, h->charset);
|
||||||
|
|
||||||
PyObject *capsule = PyCapsule_New((void *)h,
|
PyObject *capsule = PyCapsule_New((void *)h, MAP_CAPSULE, NULL);
|
||||||
PyMultibyteCodec_CAPSULE_NAME, NULL);
|
|
||||||
if (capsule == NULL) {
|
if (capsule == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -417,14 +443,14 @@ importmap(const char *modname, const char *symbol,
|
||||||
o = PyObject_GetAttrString(mod, symbol);
|
o = PyObject_GetAttrString(mod, symbol);
|
||||||
if (o == NULL)
|
if (o == NULL)
|
||||||
goto errorexit;
|
goto errorexit;
|
||||||
else if (!PyCapsule_IsValid(o, PyMultibyteCodec_CAPSULE_NAME)) {
|
else if (!PyCapsule_IsValid(o, MAP_CAPSULE)) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"map data must be a Capsule.");
|
"map data must be a Capsule.");
|
||||||
goto errorexit;
|
goto errorexit;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
struct dbcs_map *map;
|
struct dbcs_map *map;
|
||||||
map = PyCapsule_GetPointer(o, PyMultibyteCodec_CAPSULE_NAME);
|
map = PyCapsule_GetPointer(o, MAP_CAPSULE);
|
||||||
if (encmap != NULL)
|
if (encmap != NULL)
|
||||||
*encmap = map->encmap;
|
*encmap = map->encmap;
|
||||||
if (decmap != NULL)
|
if (decmap != NULL)
|
||||||
|
|
|
@ -720,9 +720,17 @@ static struct PyMethodDef multibytecodec_methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
multibytecodec_traverse(PyObject *self, visitproc visit, void *arg)
|
multibytecodec_clear(MultibyteCodecObject *self)
|
||||||
|
{
|
||||||
|
Py_CLEAR(self->cjk_module);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
multibytecodec_traverse(MultibyteCodecObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT(Py_TYPE(self));
|
Py_VISIT(Py_TYPE(self));
|
||||||
|
Py_VISIT(self->cjk_module);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,6 +739,7 @@ multibytecodec_dealloc(MultibyteCodecObject *self)
|
||||||
{
|
{
|
||||||
PyObject_GC_UnTrack(self);
|
PyObject_GC_UnTrack(self);
|
||||||
PyTypeObject *tp = Py_TYPE(self);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
|
(void)multibytecodec_clear(self);
|
||||||
tp->tp_free(self);
|
tp->tp_free(self);
|
||||||
Py_DECREF(tp);
|
Py_DECREF(tp);
|
||||||
}
|
}
|
||||||
|
@ -740,6 +749,7 @@ static PyType_Slot multibytecodec_slots[] = {
|
||||||
{Py_tp_getattro, PyObject_GenericGetAttr},
|
{Py_tp_getattro, PyObject_GenericGetAttr},
|
||||||
{Py_tp_methods, multibytecodec_methods},
|
{Py_tp_methods, multibytecodec_methods},
|
||||||
{Py_tp_traverse, multibytecodec_traverse},
|
{Py_tp_traverse, multibytecodec_traverse},
|
||||||
|
{Py_tp_clear, multibytecodec_clear},
|
||||||
{0, NULL},
|
{0, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1953,14 +1963,14 @@ _multibytecodec___create_codec(PyObject *module, PyObject *arg)
|
||||||
/*[clinic end generated code: output=cfa3dce8260e809d input=6840b2a6b183fcfa]*/
|
/*[clinic end generated code: output=cfa3dce8260e809d input=6840b2a6b183fcfa]*/
|
||||||
{
|
{
|
||||||
MultibyteCodecObject *self;
|
MultibyteCodecObject *self;
|
||||||
const MultibyteCodec *codec;
|
|
||||||
|
|
||||||
if (!PyCapsule_IsValid(arg, PyMultibyteCodec_CAPSULE_NAME)) {
|
if (!PyCapsule_IsValid(arg, CODEC_CAPSULE)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "argument type invalid");
|
PyErr_SetString(PyExc_ValueError, "argument type invalid");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
codec = PyCapsule_GetPointer(arg, PyMultibyteCodec_CAPSULE_NAME);
|
codec_capsule *data = PyCapsule_GetPointer(arg, CODEC_CAPSULE);
|
||||||
|
const MultibyteCodec *codec = data->codec;
|
||||||
if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0)
|
if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -1969,6 +1979,7 @@ _multibytecodec___create_codec(PyObject *module, PyObject *arg)
|
||||||
if (self == NULL)
|
if (self == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
self->codec = codec;
|
self->codec = codec;
|
||||||
|
self->cjk_module = Py_NewRef(data->cjk_module);
|
||||||
|
|
||||||
PyObject_GC_Track(self);
|
PyObject_GC_Track(self);
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
|
|
|
@ -63,6 +63,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
const MultibyteCodec *codec;
|
const MultibyteCodec *codec;
|
||||||
|
PyObject *cjk_module;
|
||||||
} MultibyteCodecObject;
|
} MultibyteCodecObject;
|
||||||
|
|
||||||
#define MultibyteCodec_Check(state, op) Py_IS_TYPE((op), state->multibytecodec_type)
|
#define MultibyteCodec_Check(state, op) Py_IS_TYPE((op), state->multibytecodec_type)
|
||||||
|
@ -130,7 +131,13 @@ typedef struct {
|
||||||
#define MBENC_FLUSH 0x0001 /* encode all characters encodable */
|
#define MBENC_FLUSH 0x0001 /* encode all characters encodable */
|
||||||
#define MBENC_MAX MBENC_FLUSH
|
#define MBENC_MAX MBENC_FLUSH
|
||||||
|
|
||||||
#define PyMultibyteCodec_CAPSULE_NAME "multibytecodec.__map_*"
|
typedef struct {
|
||||||
|
const MultibyteCodec *codec;
|
||||||
|
PyObject *cjk_module;
|
||||||
|
} codec_capsule;
|
||||||
|
|
||||||
|
#define MAP_CAPSULE "multibytecodec.map"
|
||||||
|
#define CODEC_CAPSULE "multibytecodec.codec"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue