Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 29bf4e4

Browse files
committed
Now that internal dialect type is immutable, and the dialect registry
only contains instances of the dialect type, we can refer directly to the dialect instances rather than creating new ones. In other words, if the dialect comes from the registry, and we apply no further modifications, the reader/writer can use the dialect object directly.
1 parent a422c34 commit 29bf4e4

1 file changed

Lines changed: 40 additions & 29 deletions

File tree

Modules/_csv.c

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,12 @@ static char *dialect_kws[] = {
301301
NULL
302302
};
303303

304-
static int
305-
dialect_init(DialectObj * self, PyObject * args, PyObject * kwargs)
304+
static PyObject *
305+
dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
306306
{
307-
int ret = -1;
308-
PyObject *dialect = NULL;
307+
DialectObj *self;
308+
PyObject *ret = NULL;
309+
PyObject *dialect = NULL;
309310
PyObject *delimiter = NULL;
310311
PyObject *doublequote = NULL;
311312
PyObject *escapechar = NULL;
@@ -326,7 +327,35 @@ dialect_init(DialectObj * self, PyObject * args, PyObject * kwargs)
326327
&quoting,
327328
&skipinitialspace,
328329
&strict))
329-
return -1;
330+
return NULL;
331+
332+
if (dialect != NULL) {
333+
if (IS_BASESTRING(dialect)) {
334+
dialect = get_dialect_from_registry(dialect);
335+
if (dialect == NULL)
336+
return NULL;
337+
}
338+
else
339+
Py_INCREF(dialect);
340+
/* Can we reuse this instance? */
341+
if (PyObject_TypeCheck(dialect, &Dialect_Type) &&
342+
delimiter == 0 &&
343+
doublequote == 0 &&
344+
escapechar == 0 &&
345+
lineterminator == 0 &&
346+
quotechar == 0 &&
347+
quoting == 0 &&
348+
skipinitialspace == 0 &&
349+
strict == 0)
350+
return dialect;
351+
}
352+
353+
self = (DialectObj *)type->tp_alloc(type, 0);
354+
if (self == NULL) {
355+
Py_XDECREF(dialect);
356+
return NULL;
357+
}
358+
self->lineterminator = NULL;
330359

331360
Py_XINCREF(delimiter);
332361
Py_XINCREF(doublequote);
@@ -337,16 +366,9 @@ dialect_init(DialectObj * self, PyObject * args, PyObject * kwargs)
337366
Py_XINCREF(skipinitialspace);
338367
Py_XINCREF(strict);
339368
if (dialect != NULL) {
340-
if (IS_BASESTRING(dialect)) {
341-
dialect = get_dialect_from_registry(dialect);
342-
if (dialect == NULL)
343-
goto err;
344-
} else
345-
Py_INCREF(dialect);
346369
#define DIALECT_GETATTR(v, n) \
347370
if (v == NULL) \
348371
v = PyObject_GetAttrString(dialect, n)
349-
350372
DIALECT_GETATTR(delimiter, "delimiter");
351373
DIALECT_GETATTR(doublequote, "doublequote");
352374
DIALECT_GETATTR(escapechar, "escapechar");
@@ -356,7 +378,6 @@ dialect_init(DialectObj * self, PyObject * args, PyObject * kwargs)
356378
DIALECT_GETATTR(skipinitialspace, "skipinitialspace");
357379
DIALECT_GETATTR(strict, "strict");
358380
PyErr_Clear();
359-
Py_DECREF(dialect);
360381
}
361382

362383
/* check types and convert to C values */
@@ -387,12 +408,13 @@ dialect_init(DialectObj * self, PyObject * args, PyObject * kwargs)
387408
goto err;
388409
}
389410
if (self->lineterminator == 0) {
390-
PyErr_SetString(PyExc_TypeError, "lineterminator must be set");
411+
PyErr_SetString(PyExc_TypeError, "lineterminator must be set");
391412
goto err;
392413
}
393414

394-
ret = 0;
415+
ret = (PyObject *)self;
395416
err:
417+
Py_XDECREF(dialect);
396418
Py_XDECREF(delimiter);
397419
Py_XDECREF(doublequote);
398420
Py_XDECREF(escapechar);
@@ -401,18 +423,7 @@ dialect_init(DialectObj * self, PyObject * args, PyObject * kwargs)
401423
Py_XDECREF(quoting);
402424
Py_XDECREF(skipinitialspace);
403425
Py_XDECREF(strict);
404-
return ret;
405-
}
406-
407-
static PyObject *
408-
dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
409-
{
410-
DialectObj *self;
411-
self = (DialectObj *)type->tp_alloc(type, 0);
412-
if (self != NULL) {
413-
self->lineterminator = NULL;
414-
}
415-
return (PyObject *)self;
426+
return ret;
416427
}
417428

418429

@@ -459,8 +470,8 @@ static PyTypeObject Dialect_Type = {
459470
0, /* tp_descr_get */
460471
0, /* tp_descr_set */
461472
0, /* tp_dictoffset */
462-
(initproc)dialect_init, /* tp_init */
463-
PyType_GenericAlloc, /* tp_alloc */
473+
0, /* tp_init */
474+
0, /* tp_alloc */
464475
dialect_new, /* tp_new */
465476
0, /* tp_free */
466477
};

0 commit comments

Comments
 (0)