/* csv module */

/*

This module provides the low-level underpinnings of a CSV reading/writing
module.  Users should not use this module directly, but import the csv.py
module instead.

*/

// clinic/_csv.c.h uses internal pycore_modsupport.h API
#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "Python.h"
#include "pycore_pyatomic_ft_wrappers.h"

#include <stddef.h>               // offsetof()
#include <stdbool.h>

/*[clinic input]
module _csv
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=385118b71aa43706]*/

#include "clinic/_csv.c.h"
#define NOT_SET ((Py_UCS4)-1)
#define EOL ((Py_UCS4)-2)


typedef struct {
    PyObject *error_obj;   /* CSV exception */
    PyObject *dialects;   /* Dialect registry */
    PyTypeObject *dialect_type;
    PyTypeObject *reader_type;
    PyTypeObject *writer_type;
    Py_ssize_t field_limit;   /* max parsed field size */
    PyObject *str_write;
} _csvstate;

static struct PyModuleDef _csvmodule;

static inline _csvstate*
get_csv_state(PyObject *module)
{
    void *state = PyModule_GetState(module);
    assert(state != NULL);
    return (_csvstate *)state;
}

static int
_csv_clear(PyObject *module)
{
    _csvstate *module_state = PyModule_GetState(module);
    Py_CLEAR(module_state->error_obj);
    Py_CLEAR(module_state->dialects);
    Py_CLEAR(module_state->dialect_type);
    Py_CLEAR(module_state->reader_type);
    Py_CLEAR(module_state->writer_type);
    Py_CLEAR(module_state->str_write);
    return 0;
}

static int
_csv_traverse(PyObject *module, visitproc visit, void *arg)
{
    _csvstate *module_state = PyModule_GetState(module);
    Py_VISIT(module_state->error_obj);
    Py_VISIT(module_state->dialects);
    Py_VISIT(module_state->dialect_type);
    Py_VISIT(module_state->reader_type);
    Py_VISIT(module_state->writer_type);
    return 0;
}

static void
_csv_free(void *module)
{
    (void)_csv_clear((PyObject *)module);
}

typedef enum {
    START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,
    IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,
    EAT_CRNL,AFTER_ESCAPED_CRNL
} ParserState;

typedef enum {
    QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE,
    QUOTE_STRINGS, QUOTE_NOTNULL
} QuoteStyle;

typedef struct {
    QuoteStyle style;
    const char *name;
} StyleDesc;

static const StyleDesc quote_styles[] = {
    { QUOTE_MINIMAL,    "QUOTE_MINIMAL" },
    { QUOTE_ALL,        "QUOTE_ALL" },
    { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
    { QUOTE_NONE,       "QUOTE_NONE" },
    { QUOTE_STRINGS,    "QUOTE_STRINGS" },
    { QUOTE_NOTNULL,    "QUOTE_NOTNULL" },
    { 0 }
};

typedef struct {
    PyObject_HEAD

    char doublequote;           /* is " represented by ""? */
    char skipinitialspace;      /* ignore spaces following delimiter? */
    char strict;                /* raise exception on bad CSV */
    int quoting;                /* style of quoting to write */
    Py_UCS4 delimiter;          /* field separator */
    Py_UCS4 quotechar;          /* quote character */
    Py_UCS4 escapechar;         /* escape character */
    PyObject *lineterminator;   /* string to write between records */

} DialectObj;

typedef struct {
    PyObject_HEAD

    PyObject *input_iter;   /* iterate over this for input lines */

    DialectObj *dialect;    /* parsing dialect */

    PyObject *fields;           /* field list for current record */
    ParserState state;          /* current CSV parse state */
    Py_UCS4 *field;             /* temporary buffer */
    Py_ssize_t field_size;      /* size of allocated buffer */
    Py_ssize_t field_len;       /* length of current field */
    bool unquoted_field;        /* true if no quotes around the current field */
    unsigned long line_num;     /* Source-file line number */
} ReaderObj;

typedef struct {
    PyObject_HEAD

    PyObject *write;    /* write output lines to this file */

    DialectObj *dialect;    /* parsing dialect */

    Py_UCS4 *rec;            /* buffer for parser.join */
    Py_ssize_t rec_size;        /* size of allocated record */
    Py_ssize_t rec_len;         /* length of record */
    int num_fields;             /* number of fields in record */

    PyObject *error_obj;       /* cached error object */
} WriterObj;

#define _DialectObj_CAST(op)    ((DialectObj *)(op))
#define _ReaderObj_CAST(op)     ((ReaderObj *)(op))
#define _WriterObj_CAST(op)     ((WriterObj *)(op))

/*
 * DIALECT class
 */

static PyObject *
get_dialect_from_registry(PyObject *name_obj, _csvstate *module_state)
{
    PyObject *dialect_obj;
    if (PyDict_GetItemRef(module_state->dialects, name_obj, &dialect_obj) == 0) {
        PyErr_SetString(module_state->error_obj, "unknown dialect");
    }
    return dialect_obj;
}

static PyObject *
get_char_or_None(Py_UCS4 c)
{
    if (c == NOT_SET) {
        Py_RETURN_NONE;
    }
    else
        return PyUnicode_FromOrdinal(c);
}

static PyObject *
Dialect_get_lineterminator(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return Py_XNewRef(self->lineterminator);
}

static PyObject *
Dialect_get_delimiter(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return get_char_or_None(self->delimiter);
}

static PyObject *
Dialect_get_escapechar(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return get_char_or_None(self->escapechar);
}

static PyObject *
Dialect_get_quotechar(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return get_char_or_None(self->quotechar);
}

static PyObject *
Dialect_get_quoting(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return PyLong_FromLong(self->quoting);
}

static int
_set_bool(const char *name, char *target, PyObject *src, bool dflt)
{
    if (src == NULL)
        *target = dflt;
    else {
        int b = PyObject_IsTrue(src);
        if (b < 0)
            return -1;
        *target = (char)b;
    }
    return 0;
}

static int
_set_int(const char *name, int *target, PyObject *src, int dflt)
{
    if (src == NULL)
        *target = dflt;
    else {
        int value;
        if (!PyLong_CheckExact(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be an integer, not %T", name, src);
            return -1;
        }
        value = PyLong_AsInt(src);
        if (value == -1 && PyErr_Occurred()) {
            return -1;
        }
        *target = value;
    }
    return 0;
}

static int
_set_char_or_none(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt)
{
    if (src == NULL) {
        *target = dflt;
    }
    else if (src == Py_None) {
        *target = NOT_SET;
    }
    else {
        // similar to PyArg_Parse("C?")
        if (!PyUnicode_Check(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a unicode character or None, not %T",
                         name, src);
            return -1;
        }
        Py_ssize_t len = PyUnicode_GetLength(src);
        if (len < 0) {
            return -1;
        }
        if (len != 1) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a unicode character or None, "
                         "not a string of length %zd",
                         name, len);
            return -1;
        }
        *target = PyUnicode_READ_CHAR(src, 0);
    }
    return 0;
}

static int
_set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt)
{
    if (src == NULL) {
        *target = dflt;
    }
    else {
        // similar to PyArg_Parse("C")
        if (!PyUnicode_Check(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a unicode character, not %T",
                         name, src);
            return -1;
        }
        Py_ssize_t len = PyUnicode_GetLength(src);
        if (len < 0) {
            return -1;
        }
        if (len != 1) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a unicode character, "
                         "not a string of length %zd",
                         name, len);
            return -1;
        }
        *target = PyUnicode_READ_CHAR(src, 0);
    }
    return 0;
}

static int
_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
{
    if (src == NULL)
        *target = PyUnicode_DecodeASCII(dflt, strlen(dflt), NULL);
    else {
        if (!PyUnicode_Check(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a string, not %T", name, src);
            return -1;
        }
        Py_XSETREF(*target, Py_NewRef(src));
    }
    return 0;
}

static int
dialect_check_quoting(int quoting)
{
    const StyleDesc *qs;

    for (qs = quote_styles; qs->name; qs++) {
        if ((int)qs->style == quoting)
            return 0;
    }
    PyErr_Format(PyExc_TypeError, "bad \"quoting\" value");
    return -1;
}

static int
dialect_check_char(const char *name, Py_UCS4 c, DialectObj *dialect, bool allowspace)
{
    if (c == '\r' || c == '\n' || (c == ' ' && !allowspace)) {
        PyErr_Format(PyExc_ValueError, "bad %s value", name);
        return -1;
    }
    if (PyUnicode_FindChar(
        dialect->lineterminator, c, 0,
        PyUnicode_GET_LENGTH(dialect->lineterminator), 1) >= 0)
    {
        PyErr_Format(PyExc_ValueError, "bad %s or lineterminator value", name);
        return -1;
    }
    return 0;
}

 static int
dialect_check_chars(const char *name1, const char *name2, Py_UCS4 c1, Py_UCS4 c2)
{
    if (c1 == c2 && c1 != NOT_SET) {
        PyErr_Format(PyExc_ValueError, "bad %s or %s value", name1, name2);
        return -1;
    }
    return 0;
}

#define D_OFF(x) offsetof(DialectObj, x)

static struct PyMemberDef Dialect_memberlist[] = {
    { "skipinitialspace",   Py_T_BOOL, D_OFF(skipinitialspace), Py_READONLY },
    { "doublequote",        Py_T_BOOL, D_OFF(doublequote), Py_READONLY },
    { "strict",             Py_T_BOOL, D_OFF(strict), Py_READONLY },
    { NULL }
};

#undef D_OFF

static PyGetSetDef Dialect_getsetlist[] = {
    {"delimiter",          Dialect_get_delimiter},
    {"escapechar",         Dialect_get_escapechar},
    {"lineterminator",     Dialect_get_lineterminator},
    {"quotechar",          Dialect_get_quotechar},
    {"quoting",            Dialect_get_quoting},
    {NULL},
};

static void
Dialect_dealloc(PyObject *self)
{
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    tp->tp_clear((PyObject *)self);
    PyObject_GC_Del(self);
    Py_DECREF(tp);
}

static char *dialect_kws[] = {
    "dialect",
    "delimiter",
    "doublequote",
    "escapechar",
    "lineterminator",
    "quotechar",
    "quoting",
    "skipinitialspace",
    "strict",
    NULL
};

static _csvstate *
_csv_state_from_type(PyTypeObject *type, const char *name)
{
    PyObject *module = PyType_GetModuleByDef(type, &_csvmodule);
    if (module == NULL) {
        return NULL;
    }
    _csvstate *module_state = PyModule_GetState(module);
    if (module_state == NULL) {
        PyErr_Format(PyExc_SystemError,
                     "%s: No _csv module state found", name);
        return NULL;
    }
    return module_state;
}

static PyObject *
dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    DialectObj *self;
    PyObject *ret = NULL;
    PyObject *dialect = NULL;
    PyObject *delimiter = NULL;
    PyObject *doublequote = NULL;
    PyObject *escapechar = NULL;
    PyObject *lineterminator = NULL;
    PyObject *quotechar = NULL;
    PyObject *quoting = NULL;
    PyObject *skipinitialspace = NULL;
    PyObject *strict = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "|OOOOOOOOO", dialect_kws,
                                     &dialect,
                                     &delimiter,
                                     &doublequote,
                                     &escapechar,
                                     &lineterminator,
                                     &quotechar,
                                     &quoting,
                                     &skipinitialspace,
                                     &strict))
        return NULL;

    _csvstate *module_state = _csv_state_from_type(type, "dialect_new");
    if (module_state == NULL) {
        return NULL;
    }

    if (dialect != NULL) {
        if (PyUnicode_Check(dialect)) {
            dialect = get_dialect_from_registry(dialect, module_state);
            if (dialect == NULL)
                return NULL;
        }
        else
            Py_INCREF(dialect);
        /* Can we reuse this instance? */
        if (PyObject_TypeCheck(dialect, module_state->dialect_type) &&
            delimiter == NULL &&
            doublequote == NULL &&
            escapechar == NULL &&
            lineterminator == NULL &&
            quotechar == NULL &&
            quoting == NULL &&
            skipinitialspace == NULL &&
            strict == NULL)
            return dialect;
    }

    self = (DialectObj *)type->tp_alloc(type, 0);
    if (self == NULL) {
        Py_CLEAR(dialect);
        return NULL;
    }
    self->lineterminator = NULL;

    Py_XINCREF(delimiter);
    Py_XINCREF(doublequote);
    Py_XINCREF(escapechar);
    Py_XINCREF(lineterminator);
    Py_XINCREF(quotechar);
    Py_XINCREF(quoting);
    Py_XINCREF(skipinitialspace);
    Py_XINCREF(strict);
    if (dialect != NULL) {
#define DIALECT_GETATTR(v, n)                            \
        do {                                             \
            if (v == NULL) {                             \
                v = PyObject_GetAttrString(dialect, n);  \
                if (v == NULL)                           \
                    PyErr_Clear();                       \
            }                                            \
        } while (0)
        DIALECT_GETATTR(delimiter, "delimiter");
        DIALECT_GETATTR(doublequote, "doublequote");
        DIALECT_GETATTR(escapechar, "escapechar");
        DIALECT_GETATTR(lineterminator, "lineterminator");
        DIALECT_GETATTR(quotechar, "quotechar");
        DIALECT_GETATTR(quoting, "quoting");
        DIALECT_GETATTR(skipinitialspace, "skipinitialspace");
        DIALECT_GETATTR(strict, "strict");
    }
#undef DIALECT_GETATTR

    /* check types and convert to C values */
#define DIASET(meth, name, target, src, dflt) \
    if (meth(name, target, src, dflt)) \
        goto err
    DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ',');
    DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, true);
    DIASET(_set_char_or_none, "escapechar", &self->escapechar, escapechar, NOT_SET);
    DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");
    DIASET(_set_char_or_none, "quotechar", &self->quotechar, quotechar, '"');
    DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL);
    DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, false);
    DIASET(_set_bool, "strict", &self->strict, strict, false);
#undef DIASET

    /* validate options */
    if (dialect_check_quoting(self->quoting))
        goto err;
    if (quotechar == Py_None && quoting == NULL)
        self->quoting = QUOTE_NONE;
    if (self->quoting != QUOTE_NONE && self->quotechar == NOT_SET) {
        PyErr_SetString(PyExc_TypeError,
                        "quotechar must be set if quoting enabled");
        goto err;
    }
    if (dialect_check_char("delimiter", self->delimiter, self, true) ||
        dialect_check_char("escapechar", self->escapechar, self,
                           !self->skipinitialspace) ||
        dialect_check_char("quotechar", self->quotechar, self,
                           !self->skipinitialspace) ||
        dialect_check_chars("delimiter", "escapechar",
                            self->delimiter, self->escapechar) ||
        dialect_check_chars("delimiter", "quotechar",
                            self->delimiter, self->quotechar) ||
        dialect_check_chars("escapechar", "quotechar",
                            self->escapechar, self->quotechar))
    {
        goto err;
    }

    ret = Py_NewRef(self);
err:
    Py_CLEAR(self);
    Py_CLEAR(dialect);
    Py_CLEAR(delimiter);
    Py_CLEAR(doublequote);
    Py_CLEAR(escapechar);
    Py_CLEAR(lineterminator);
    Py_CLEAR(quotechar);
    Py_CLEAR(quoting);
    Py_CLEAR(skipinitialspace);
    Py_CLEAR(strict);
    return ret;
}

/* Since dialect is now a heap type, it inherits pickling method for
 * protocol 0 and 1 from object, therefore it needs to be overridden */

PyDoc_STRVAR(dialect_reduce_doc, "raises an exception to avoid pickling");

static PyObject *
Dialect_reduce(PyObject *self, PyObject *args) {
    PyErr_Format(PyExc_TypeError,
        "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self)));
    return NULL;
}

static struct PyMethodDef dialect_methods[] = {
    {"__reduce__", Dialect_reduce, METH_VARARGS, dialect_reduce_doc},
    {"__reduce_ex__", Dialect_reduce, METH_VARARGS, dialect_reduce_doc},
    {NULL, NULL}
};

PyDoc_STRVAR(Dialect_Type_doc,
"CSV dialect\n"
"\n"
"The Dialect type records CSV parsing and generation options.\n");

static int
Dialect_clear(PyObject *op)
{
    DialectObj *self = _DialectObj_CAST(op);
    Py_CLEAR(self->lineterminator);
    return 0;
}

static int
Dialect_traverse(PyObject *op, visitproc visit, void *arg)
{
    DialectObj *self = _DialectObj_CAST(op);
    Py_VISIT(self->lineterminator);
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static PyType_Slot Dialect_Type_slots[] = {
    {Py_tp_doc, (char*)Dialect_Type_doc},
    {Py_tp_members, Dialect_memberlist},
    {Py_tp_getset, Dialect_getsetlist},
    {Py_tp_new, dialect_new},
    {Py_tp_methods, dialect_methods},
    {Py_tp_dealloc, Dialect_dealloc},
    {Py_tp_clear, Dialect_clear},
    {Py_tp_traverse, Dialect_traverse},
    {0, NULL}
};

PyType_Spec Dialect_Type_spec = {
    .name = "_csv.Dialect",
    .basicsize = sizeof(DialectObj),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
              Py_TPFLAGS_IMMUTABLETYPE),
    .slots = Dialect_Type_slots,
};


/*
 * Return an instance of the dialect type, given a Python instance or kwarg
 * description of the dialect
 */
static PyObject *
_call_dialect(_csvstate *module_state, PyObject *dialect_inst, PyObject *kwargs)
{
    PyObject *type = (PyObject *)module_state->dialect_type;
    if (dialect_inst) {
        return PyObject_VectorcallDict(type, &dialect_inst, 1, kwargs);
    }
    else {
        return PyObject_VectorcallDict(type, NULL, 0, kwargs);
    }
}

/*
 * READER
 */
static int
parse_save_field(ReaderObj *self)
{
    int quoting = self->dialect->quoting;
    PyObject *field;

    if (self->unquoted_field &&
        self->field_len == 0 &&
        (quoting == QUOTE_NOTNULL || quoting == QUOTE_STRINGS))
    {
        field = Py_NewRef(Py_None);
    }
    else {
        field = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
                                        (void *) self->field, self->field_len);
        if (field == NULL) {
            return -1;
        }
        if (self->unquoted_field &&
            self->field_len != 0 &&
            (quoting == QUOTE_NONNUMERIC || quoting == QUOTE_STRINGS))
        {
            PyObject *tmp = PyNumber_Float(field);
            Py_DECREF(field);
            if (tmp == NULL) {
                return -1;
            }
            field = tmp;
        }
        self->field_len = 0;
    }
    if (PyList_Append(self->fields, field) < 0) {
        Py_DECREF(field);
        return -1;
    }
    Py_DECREF(field);
    return 0;
}

static int
parse_grow_buff(ReaderObj *self)
{
    assert((size_t)self->field_size <= PY_SSIZE_T_MAX / sizeof(Py_UCS4));

    Py_ssize_t field_size_new = self->field_size ? 2 * self->field_size : 4096;
    Py_UCS4 *field_new = self->field;
    PyMem_Resize(field_new, Py_UCS4, field_size_new);
    if (field_new == NULL) {
        PyErr_NoMemory();
        return 0;
    }
    self->field = field_new;
    self->field_size = field_size_new;
    return 1;
}

static int
parse_add_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
{
    Py_ssize_t field_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit);
    if (self->field_len >= field_limit) {
        PyErr_Format(module_state->error_obj,
                     "field larger than field limit (%zd)",
                     field_limit);
        return -1;
    }
    if (self->field_len == self->field_size && !parse_grow_buff(self))
        return -1;
    self->field[self->field_len++] = c;
    return 0;
}

static int
parse_process_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
{
    DialectObj *dialect = self->dialect;

    switch (self->state) {
    case START_RECORD:
        /* start of record */
        if (c == EOL)
            /* empty line - return [] */
            break;
        else if (c == '\n' || c == '\r') {
            self->state = EAT_CRNL;
            break;
        }
        /* normal character - handle as START_FIELD */
        self->state = START_FIELD;
        _Py_FALLTHROUGH;
    case START_FIELD:
        /* expecting field */
        self->unquoted_field = true;
        if (c == '\n' || c == '\r' || c == EOL) {
            /* save empty field - return [fields] */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = (c == EOL ? START_RECORD : EAT_CRNL);
        }
        else if (c == dialect->quotechar &&
                 dialect->quoting != QUOTE_NONE) {
            /* start quoted field */
            self->unquoted_field = false;
            self->state = IN_QUOTED_FIELD;
        }
        else if (c == dialect->escapechar) {
            /* possible escaped character */
            self->state = ESCAPED_CHAR;
        }
        else if (c == ' ' && dialect->skipinitialspace)
            /* ignore spaces at start of field */
            ;
        else if (c == dialect->delimiter) {
            /* save empty field */
            if (parse_save_field(self) < 0)
                return -1;
        }
        else {
            /* begin new unquoted field */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
            self->state = IN_FIELD;
        }
        break;

    case ESCAPED_CHAR:
        if (c == '\n' || c=='\r') {
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
            self->state = AFTER_ESCAPED_CRNL;
            break;
        }
        if (c == EOL)
            c = '\n';
        if (parse_add_char(self, module_state, c) < 0)
            return -1;
        self->state = IN_FIELD;
        break;

    case AFTER_ESCAPED_CRNL:
        if (c == EOL)
            break;
        _Py_FALLTHROUGH;

    case IN_FIELD:
        /* in unquoted field */
        if (c == '\n' || c == '\r' || c == EOL) {
            /* end of line - return [fields] */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = (c == EOL ? START_RECORD : EAT_CRNL);
        }
        else if (c == dialect->escapechar) {
            /* possible escaped character */
            self->state = ESCAPED_CHAR;
        }
        else if (c == dialect->delimiter) {
            /* save field - wait for new field */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = START_FIELD;
        }
        else {
            /* normal character - save in field */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
        }
        break;

    case IN_QUOTED_FIELD:
        /* in quoted field */
        if (c == EOL)
            ;
        else if (c == dialect->escapechar) {
            /* Possible escape character */
            self->state = ESCAPE_IN_QUOTED_FIELD;
        }
        else if (c == dialect->quotechar &&
                 dialect->quoting != QUOTE_NONE) {
            if (dialect->doublequote) {
                /* doublequote; " represented by "" */
                self->state = QUOTE_IN_QUOTED_FIELD;
            }
            else {
                /* end of quote part of field */
                self->state = IN_FIELD;
            }
        }
        else {
            /* normal character - save in field */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
        }
        break;

    case ESCAPE_IN_QUOTED_FIELD:
        if (c == EOL)
            c = '\n';
        if (parse_add_char(self, module_state, c) < 0)
            return -1;
        self->state = IN_QUOTED_FIELD;
        break;

    case QUOTE_IN_QUOTED_FIELD:
        /* doublequote - seen a quote in a quoted field */
        if (dialect->quoting != QUOTE_NONE &&
            c == dialect->quotechar) {
            /* save "" as " */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
            self->state = IN_QUOTED_FIELD;
        }
        else if (c == dialect->delimiter) {
            /* save field - wait for new field */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = START_FIELD;
        }
        else if (c == '\n' || c == '\r' || c == EOL) {
            /* end of line - return [fields] */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = (c == EOL ? START_RECORD : EAT_CRNL);
        }
        else if (!dialect->strict) {
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
            self->state = IN_FIELD;
        }
        else {
            /* illegal */
            PyErr_Format(module_state->error_obj, "'%c' expected after '%c'",
                            dialect->delimiter,
                            dialect->quotechar);
            return -1;
        }
        break;

    case EAT_CRNL:
        if (c == '\n' || c == '\r')
            ;
        else if (c == EOL)
            self->state = START_RECORD;
        else {
            PyErr_Format(module_state->error_obj,
                         "new-line character seen in unquoted field - "
                         "do you need to open the file with newline=''?");
            return -1;
        }
        break;

    }
    return 0;
}

static int
parse_reset(ReaderObj *self)
{
    Py_XSETREF(self->fields, PyList_New(0));
    if (self->fields == NULL)
        return -1;
    self->field_len = 0;
    self->state = START_RECORD;
    self->unquoted_field = false;
    return 0;
}

static PyObject *
Reader_iternext_lock_held(PyObject *op)
{
    ReaderObj *self = _ReaderObj_CAST(op);

    PyObject *fields = NULL;
    Py_UCS4 c;
    Py_ssize_t pos, linelen;
    int kind;
    const void *data;
    PyObject *lineobj;

    _csvstate *module_state = _csv_state_from_type(Py_TYPE(self),
                                                   "Reader.__next__");
    if (module_state == NULL) {
        return NULL;
    }

    if (parse_reset(self) < 0)
        return NULL;
    do {
        lineobj = PyIter_Next(self->input_iter);
        if (lineobj == NULL) {
            /* End of input OR exception */
            if (!PyErr_Occurred() && (self->field_len != 0 ||
                                      self->state == IN_QUOTED_FIELD)) {
                if (self->dialect->strict)
                    PyErr_SetString(module_state->error_obj,
                                    "unexpected end of data");
                else if (parse_save_field(self) >= 0)
                    break;
            }
            return NULL;
        }
        if (!PyUnicode_Check(lineobj)) {
            PyErr_Format(module_state->error_obj,
                         "iterator should return strings, "
                         "not %.200s "
                         "(the file should be opened in text mode)",
                         Py_TYPE(lineobj)->tp_name
                );
            Py_DECREF(lineobj);
            return NULL;
        }
        ++self->line_num;
        kind = PyUnicode_KIND(lineobj);
        data = PyUnicode_DATA(lineobj);
        pos = 0;
        linelen = PyUnicode_GET_LENGTH(lineobj);
        while (linelen--) {
            c = PyUnicode_READ(kind, data, pos);
            if (parse_process_char(self, module_state, c) < 0) {
                Py_DECREF(lineobj);
                goto err;
            }
            pos++;
        }
        Py_DECREF(lineobj);
        if (parse_process_char(self, module_state, EOL) < 0)
            goto err;
    } while (self->state != START_RECORD);

    fields = self->fields;
    self->fields = NULL;
err:
    return fields;
}

static PyObject *
Reader_iternext(PyObject *op)
{
    PyObject *result;
    Py_BEGIN_CRITICAL_SECTION(op);
    result = Reader_iternext_lock_held(op);
    Py_END_CRITICAL_SECTION();
    return result;
}

static void
Reader_dealloc(PyObject *op)
{
    ReaderObj *self = _ReaderObj_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    (void)tp->tp_clear(op);
    if (self->field != NULL) {
        PyMem_Free(self->field);
        self->field = NULL;
    }
    PyObject_GC_Del(self);
    Py_DECREF(tp);
}

static int
Reader_traverse(PyObject *op, visitproc visit, void *arg)
{
    ReaderObj *self = _ReaderObj_CAST(op);
    Py_VISIT(self->dialect);
    Py_VISIT(self->input_iter);
    Py_VISIT(self->fields);
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static int
Reader_clear(PyObject *op)
{
    ReaderObj *self = _ReaderObj_CAST(op);
    Py_CLEAR(self->dialect);
    Py_CLEAR(self->input_iter);
    Py_CLEAR(self->fields);
    return 0;
}

PyDoc_STRVAR(Reader_Type_doc,
"CSV reader\n"
"\n"
"Reader objects are responsible for reading and parsing tabular data\n"
"in CSV format.\n"
);

static struct PyMethodDef Reader_methods[] = {
    { NULL, NULL }
};
#define R_OFF(x) offsetof(ReaderObj, x)

static struct PyMemberDef Reader_memberlist[] = {
    { "dialect", _Py_T_OBJECT, R_OFF(dialect), Py_READONLY },
    { "line_num", Py_T_ULONG, R_OFF(line_num), Py_READONLY },
    { NULL }
};

#undef R_OFF


static PyType_Slot Reader_Type_slots[] = {
    {Py_tp_doc, (char*)Reader_Type_doc},
    {Py_tp_traverse, Reader_traverse},
    {Py_tp_iter, PyObject_SelfIter},
    {Py_tp_iternext, Reader_iternext},
    {Py_tp_methods, Reader_methods},
    {Py_tp_members, Reader_memberlist},
    {Py_tp_clear, Reader_clear},
    {Py_tp_dealloc, Reader_dealloc},
    {0, NULL}
};

PyType_Spec Reader_Type_spec = {
    .name = "_csv.reader",
    .basicsize = sizeof(ReaderObj),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
              Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
    .slots = Reader_Type_slots
};


static PyObject *
csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
{
    PyObject * iterator, * dialect = NULL;
    _csvstate *module_state = get_csv_state(module);
    ReaderObj * self = PyObject_GC_New(
        ReaderObj,
        module_state->reader_type);

    if (!self)
        return NULL;

    self->dialect = NULL;
    self->fields = NULL;
    self->input_iter = NULL;
    self->field = NULL;
    self->field_size = 0;
    self->line_num = 0;

    if (parse_reset(self) < 0) {
        Py_DECREF(self);
        return NULL;
    }

    if (!PyArg_UnpackTuple(args, "reader", 1, 2, &iterator, &dialect)) {
        Py_DECREF(self);
        return NULL;
    }
    self->input_iter = PyObject_GetIter(iterator);
    if (self->input_iter == NULL) {
        Py_DECREF(self);
        return NULL;
    }
    self->dialect = (DialectObj *)_call_dialect(module_state, dialect,
                                                keyword_args);
    if (self->dialect == NULL) {
        Py_DECREF(self);
        return NULL;
    }

    PyObject_GC_Track(self);
    return (PyObject *)self;
}

/*
 * WRITER
 */
/* ---------------------------------------------------------------- */
static void
join_reset(WriterObj *self)
{
    self->rec_len = 0;
    self->num_fields = 0;
}

#define MEM_INCR 32768

/* Calculate new record length or append field to record.  Return new
 * record length.
 */
static Py_ssize_t
join_append_data(WriterObj *self, int field_kind, const void *field_data,
                 Py_ssize_t field_len, int *quoted,
                 int copy_phase)
{
    DialectObj *dialect = self->dialect;
    Py_ssize_t i;
    Py_ssize_t rec_len;

#define INCLEN \
    do {\
        if (!copy_phase && rec_len == PY_SSIZE_T_MAX) {    \
            goto overflow; \
        } \
        rec_len++; \
    } while(0)

#define ADDCH(c)                                \
    do {\
        if (copy_phase) \
            self->rec[rec_len] = c;\
        INCLEN;\
    } while(0)

    rec_len = self->rec_len;

    /* If this is not the first field we need a field separator */
    if (self->num_fields > 0)
        ADDCH(dialect->delimiter);

    /* Handle preceding quote */
    if (copy_phase && *quoted)
        ADDCH(dialect->quotechar);

    /* Copy/count field data */
    /* If field is null just pass over */
    for (i = 0; field_data && (i < field_len); i++) {
        Py_UCS4 c = PyUnicode_READ(field_kind, field_data, i);
        int want_escape = 0;

        if (c == dialect->delimiter ||
            c == dialect->escapechar ||
            c == dialect->quotechar  ||
            c == '\n'  ||
            c == '\r'  ||
            PyUnicode_FindChar(
                dialect->lineterminator, c, 0,
                PyUnicode_GET_LENGTH(dialect->lineterminator), 1) >= 0) {
            if (dialect->quoting == QUOTE_NONE)
                want_escape = 1;
            else {
                if (c == dialect->quotechar) {
                    if (dialect->doublequote)
                        ADDCH(dialect->quotechar);
                    else
                        want_escape = 1;
                }
                else if (c == dialect->escapechar) {
                    want_escape = 1;
                }
                if (!want_escape)
                    *quoted = 1;
            }
            if (want_escape) {
                if (dialect->escapechar == NOT_SET) {
                    PyErr_Format(self->error_obj,
                                 "need to escape, but no escapechar set");
                    return -1;
                }
                ADDCH(dialect->escapechar);
            }
        }
        /* Copy field character into record buffer.
         */
        ADDCH(c);
    }

    if (*quoted) {
        if (copy_phase)
            ADDCH(dialect->quotechar);
        else {
            INCLEN; /* starting quote */
            INCLEN; /* ending quote */
        }
    }
    return rec_len;

  overflow:
    PyErr_NoMemory();
    return -1;
#undef ADDCH
#undef INCLEN
}

static int
join_check_rec_size(WriterObj *self, Py_ssize_t rec_len)
{
    assert(rec_len >= 0);

    if (rec_len > self->rec_size) {
        size_t rec_size_new = (size_t)(rec_len / MEM_INCR + 1) * MEM_INCR;
        Py_UCS4 *rec_new = self->rec;
        PyMem_Resize(rec_new, Py_UCS4, rec_size_new);
        if (rec_new == NULL) {
            PyErr_NoMemory();
            return 0;
        }
        self->rec = rec_new;
        self->rec_size = (Py_ssize_t)rec_size_new;
    }
    return 1;
}

static int
join_append(WriterObj *self, PyObject *field, int quoted)
{
    DialectObj *dialect = self->dialect;
    int field_kind = -1;
    const void *field_data = NULL;
    Py_ssize_t field_len = 0;
    Py_ssize_t rec_len;

    if (field != NULL) {
        field_kind = PyUnicode_KIND(field);
        field_data = PyUnicode_DATA(field);
        field_len = PyUnicode_GET_LENGTH(field);
    }
    if (!field_len && dialect->delimiter == ' ' && dialect->skipinitialspace) {
        if (dialect->quoting == QUOTE_NONE ||
            (field == NULL &&
             (dialect->quoting == QUOTE_STRINGS ||
              dialect->quoting == QUOTE_NOTNULL)))
        {
            PyErr_Format(self->error_obj,
                         "empty field must be quoted if delimiter is a space "
                         "and skipinitialspace is true");
            return 0;
        }
        quoted = 1;
    }
    rec_len = join_append_data(self, field_kind, field_data, field_len,
                               &quoted, 0);
    if (rec_len < 0)
        return 0;

    /* grow record buffer if necessary */
    if (!join_check_rec_size(self, rec_len))
        return 0;

    self->rec_len = join_append_data(self, field_kind, field_data, field_len,
                                     &quoted, 1);
    self->num_fields++;

    return 1;
}

static int
join_append_lineterminator(WriterObj *self)
{
    Py_ssize_t terminator_len, i;
    int term_kind;
    const void *term_data;

    terminator_len = PyUnicode_GET_LENGTH(self->dialect->lineterminator);
    if (terminator_len == -1)
        return 0;

    /* grow record buffer if necessary */
    if (!join_check_rec_size(self, self->rec_len + terminator_len))
        return 0;

    term_kind = PyUnicode_KIND(self->dialect->lineterminator);
    term_data = PyUnicode_DATA(self->dialect->lineterminator);
    for (i = 0; i < terminator_len; i++)
        self->rec[self->rec_len + i] = PyUnicode_READ(term_kind, term_data, i);
    self->rec_len += terminator_len;

    return 1;
}

static PyObject *
csv_writerow_lock_held(PyObject *op, PyObject *seq)
{
    WriterObj *self = _WriterObj_CAST(op);
    DialectObj *dialect = self->dialect;
    PyObject *iter, *field, *line, *result;
    bool null_field = false;

    iter = PyObject_GetIter(seq);
    if (iter == NULL) {
        if (PyErr_ExceptionMatches(PyExc_TypeError)) {
            PyErr_Format(self->error_obj,
                         "iterable expected, not %.200s",
                         Py_TYPE(seq)->tp_name);
        }
        return NULL;
    }

    /* Join all fields in internal buffer.
     */
    join_reset(self);
    while ((field = PyIter_Next(iter))) {
        int append_ok;
        int quoted;

        switch (dialect->quoting) {
        case QUOTE_NONNUMERIC:
            quoted = !PyNumber_Check(field);
            break;
        case QUOTE_ALL:
            quoted = 1;
            break;
        case QUOTE_STRINGS:
            quoted = PyUnicode_Check(field);
            break;
        case QUOTE_NOTNULL:
            quoted = field != Py_None;
            break;
        default:
            quoted = 0;
            break;
        }

        null_field = (field == Py_None);
        if (PyUnicode_Check(field)) {
            append_ok = join_append(self, field, quoted);
            Py_DECREF(field);
        }
        else if (null_field) {
            append_ok = join_append(self, NULL, quoted);
            Py_DECREF(field);
        }
        else {
            PyObject *str;

            str = PyObject_Str(field);
            Py_DECREF(field);
            if (str == NULL) {
                Py_DECREF(iter);
                return NULL;
            }
            append_ok = join_append(self, str, quoted);
            Py_DECREF(str);
        }
        if (!append_ok) {
            Py_DECREF(iter);
            return NULL;
        }
    }
    Py_DECREF(iter);
    if (PyErr_Occurred())
        return NULL;

    if (self->num_fields > 0 && self->rec_len == 0) {
        if (dialect->quoting == QUOTE_NONE ||
            (null_field &&
             (dialect->quoting == QUOTE_STRINGS ||
              dialect->quoting == QUOTE_NOTNULL)))
        {
            PyErr_Format(self->error_obj,
                "single empty field record must be quoted");
            return NULL;
        }
        self->num_fields--;
        if (!join_append(self, NULL, 1))
            return NULL;
    }

    /* Add line terminator.
     */
    if (!join_append_lineterminator(self)) {
        return NULL;
    }

    line = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
                                     (void *) self->rec, self->rec_len);
    if (line == NULL) {
        return NULL;
    }
    result = PyObject_CallOneArg(self->write, line);
    Py_DECREF(line);
    return result;
}

PyDoc_STRVAR(csv_writerow_doc,
"writerow($self, row, /)\n"
"--\n\n"
"Construct and write a CSV record from an iterable of fields.\n"
"\n"
"Non-string elements will be converted to string.");

static PyObject *
csv_writerow(PyObject *op, PyObject *seq)
{
    PyObject *result;
    Py_BEGIN_CRITICAL_SECTION(op);
    result = csv_writerow_lock_held(op, seq);
    Py_END_CRITICAL_SECTION();
    return result;
}

PyDoc_STRVAR(csv_writerows_doc,
"writerows($self, rows, /)\n"
"--\n\n"
"Construct and write a series of iterables to a csv file.\n"
"\n"
"Non-string elements will be converted to string.");

static PyObject *
csv_writerows(PyObject *self, PyObject *seqseq)
{
    PyObject *row_iter, *row_obj, *result;

    row_iter = PyObject_GetIter(seqseq);
    if (row_iter == NULL) {
        return NULL;
    }
    while ((row_obj = PyIter_Next(row_iter))) {
        result = csv_writerow(self, row_obj);
        Py_DECREF(row_obj);
        if (!result) {
            Py_DECREF(row_iter);
            return NULL;
        }
        else
             Py_DECREF(result);
    }
    Py_DECREF(row_iter);
    if (PyErr_Occurred())
        return NULL;
    Py_RETURN_NONE;
}

static struct PyMethodDef Writer_methods[] = {
    {"writerow", csv_writerow, METH_O, csv_writerow_doc},
    {"writerows", csv_writerows, METH_O, csv_writerows_doc},
    {NULL, NULL, 0, NULL}  /* sentinel */
};

#define W_OFF(x) offsetof(WriterObj, x)

static struct PyMemberDef Writer_memberlist[] = {
    { "dialect", _Py_T_OBJECT, W_OFF(dialect), Py_READONLY },
    { NULL }
};

#undef W_OFF

static int
Writer_traverse(PyObject *op, visitproc visit, void *arg)
{
    WriterObj *self = _WriterObj_CAST(op);
    Py_VISIT(self->dialect);
    Py_VISIT(self->write);
    Py_VISIT(self->error_obj);
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static int
Writer_clear(PyObject *op)
{
    WriterObj *self = _WriterObj_CAST(op);
    Py_CLEAR(self->dialect);
    Py_CLEAR(self->write);
    Py_CLEAR(self->error_obj);
    return 0;
}

static void
Writer_dealloc(PyObject *op)
{
    WriterObj *self = _WriterObj_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    tp->tp_clear(op);
    if (self->rec != NULL) {
        PyMem_Free(self->rec);
    }
    PyObject_GC_Del(self);
    Py_DECREF(tp);
}

PyDoc_STRVAR(Writer_Type_doc,
"CSV writer\n"
"\n"
"Writer objects are responsible for generating tabular data\n"
"in CSV format from sequence input.\n"
);

static PyType_Slot Writer_Type_slots[] = {
    {Py_tp_doc, (char*)Writer_Type_doc},
    {Py_tp_traverse, Writer_traverse},
    {Py_tp_clear, Writer_clear},
    {Py_tp_dealloc, Writer_dealloc},
    {Py_tp_methods, Writer_methods},
    {Py_tp_members, Writer_memberlist},
    {0, NULL}
};

PyType_Spec Writer_Type_spec = {
    .name = "_csv.writer",
    .basicsize = sizeof(WriterObj),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
              Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
    .slots = Writer_Type_slots,
};


static PyObject *
csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
{
    PyObject * output_file, * dialect = NULL;
    _csvstate *module_state = get_csv_state(module);
    WriterObj * self = PyObject_GC_New(WriterObj, module_state->writer_type);

    if (!self)
        return NULL;

    self->dialect = NULL;
    self->write = NULL;

    self->rec = NULL;
    self->rec_size = 0;
    self->rec_len = 0;
    self->num_fields = 0;

    self->error_obj = Py_NewRef(module_state->error_obj);

    if (!PyArg_UnpackTuple(args, "writer", 1, 2, &output_file, &dialect)) {
        Py_DECREF(self);
        return NULL;
    }
    if (PyObject_GetOptionalAttr(output_file,
                             module_state->str_write,
                             &self->write) < 0) {
        Py_DECREF(self);
        return NULL;
    }
    if (self->write == NULL || !PyCallable_Check(self->write)) {
        PyErr_SetString(PyExc_TypeError,
                        "argument 1 must have a \"write\" method");
        Py_DECREF(self);
        return NULL;
    }
    self->dialect = (DialectObj *)_call_dialect(module_state, dialect,
                                                keyword_args);
    if (self->dialect == NULL) {
        Py_DECREF(self);
        return NULL;
    }
    PyObject_GC_Track(self);
    return (PyObject *)self;
}

/*
 * DIALECT REGISTRY
 */

/*[clinic input]
_csv.list_dialects

Return a list of all known dialect names.
[clinic start generated code]*/

static PyObject *
_csv_list_dialects_impl(PyObject *module)
/*[clinic end generated code: output=a5b92b215b006a6d input=ec58040aafd6a20a]*/
{
    return PyDict_Keys(get_csv_state(module)->dialects);
}

static PyObject *
csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
{
    PyObject *name_obj, *dialect_obj = NULL;
    _csvstate *module_state = get_csv_state(module);
    PyObject *dialect;

    if (!PyArg_UnpackTuple(args, "register_dialect", 1, 2, &name_obj, &dialect_obj))
        return NULL;
    if (!PyUnicode_Check(name_obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "dialect name must be a string");
        return NULL;
    }
    dialect = _call_dialect(module_state, dialect_obj, kwargs);
    if (dialect == NULL)
        return NULL;
    if (PyDict_SetItem(module_state->dialects, name_obj, dialect) < 0) {
        Py_DECREF(dialect);
        return NULL;
    }
    Py_DECREF(dialect);
    Py_RETURN_NONE;
}


/*[clinic input]
_csv.unregister_dialect

    name: object

Delete the name/dialect mapping associated with a string name.
[clinic start generated code]*/

static PyObject *
_csv_unregister_dialect_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=0813ebca6c058df4 input=e1cf81bfe3ba0f62]*/
{
    _csvstate *module_state = get_csv_state(module);
    int rc = PyDict_Pop(module_state->dialects, name, NULL);
    if (rc < 0) {
        return NULL;
    }
    if (rc == 0) {
        PyErr_Format(module_state->error_obj, "unknown dialect");
        return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
_csv.get_dialect

    name: object

Return the dialect instance associated with name.
[clinic start generated code]*/

static PyObject *
_csv_get_dialect_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=aa988cd573bebebb input=74865c659dcb441f]*/
{
    return get_dialect_from_registry(name, get_csv_state(module));
}

/*[clinic input]
_csv.field_size_limit

    new_limit: object = NULL

Sets an upper limit on parsed fields.

Returns old limit. If limit is not given, no new limit is set and
the old limit is returned
[clinic start generated code]*/

static PyObject *
_csv_field_size_limit_impl(PyObject *module, PyObject *new_limit)
/*[clinic end generated code: output=f2799ecd908e250b input=77db7485ee3ae90a]*/
{
    _csvstate *module_state = get_csv_state(module);
    Py_ssize_t old_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit);
    if (new_limit != NULL) {
        if (!PyLong_CheckExact(new_limit)) {
            PyErr_Format(PyExc_TypeError,
                         "limit must be an integer");
            return NULL;
        }
        Py_ssize_t new_limit_value = PyLong_AsSsize_t(new_limit);
        if (new_limit_value == -1 && PyErr_Occurred()) {
            return NULL;
        }
        FT_ATOMIC_STORE_SSIZE_RELAXED(module_state->field_limit, new_limit_value);
    }
    return PyLong_FromSsize_t(old_limit);
}

static PyType_Slot error_slots[] = {
    {0, NULL},
};

PyType_Spec error_spec = {
    .name = "_csv.Error",
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
    .slots = error_slots,
};

/*
 * MODULE
 */

PyDoc_STRVAR(csv_module_doc, "CSV parsing and writing.\n");

PyDoc_STRVAR(csv_reader_doc,
"reader($module, iterable, /, dialect='excel', **fmtparams)\n"
"--\n\n"
"Return a reader object that will process lines from the given iterable.\n"
"\n"
"The \"iterable\" argument can be any object that returns a line\n"
"of input for each iteration, such as a file object or a list.  The\n"
"optional \"dialect\" argument defines a CSV dialect.  The function\n"
"also accepts optional keyword arguments which override settings\n"
"provided by the dialect.\n"
"\n"
"The returned object is an iterator.  Each iteration returns a row\n"
"of the CSV file (which can span multiple input lines).\n");

PyDoc_STRVAR(csv_writer_doc,
"writer($module, fileobj, /, dialect='excel', **fmtparams)\n"
"--\n\n"
"Return a writer object that will write user data on the given file object.\n"
"\n"
"The \"fileobj\" argument can be any object that supports the file API.\n"
"The optional \"dialect\" argument defines a CSV dialect.  The function\n"
"also accepts optional keyword arguments which override settings\n"
"provided by the dialect.\n");

PyDoc_STRVAR(csv_register_dialect_doc,
"register_dialect($module, name, /, dialect='excel', **fmtparams)\n"
"--\n\n"
"Create a mapping from a string name to a CVS dialect.\n"
"\n"
"The optional \"dialect\" argument specifies the base dialect instance\n"
"or the name of the registered dialect.  The function also accepts\n"
"optional keyword arguments which override settings provided by the\n"
"dialect.\n");

static struct PyMethodDef csv_methods[] = {
    { "reader", _PyCFunction_CAST(csv_reader),
        METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
    { "writer", _PyCFunction_CAST(csv_writer),
        METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
    { "register_dialect", _PyCFunction_CAST(csv_register_dialect),
        METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
    _CSV_LIST_DIALECTS_METHODDEF
    _CSV_UNREGISTER_DIALECT_METHODDEF
    _CSV_GET_DIALECT_METHODDEF
    _CSV_FIELD_SIZE_LIMIT_METHODDEF
    { NULL, NULL }
};

static int
csv_exec(PyObject *module) {
    const StyleDesc *style;
    PyObject *temp;
    _csvstate *module_state = get_csv_state(module);

    temp = PyType_FromModuleAndSpec(module, &Dialect_Type_spec, NULL);
    module_state->dialect_type = (PyTypeObject *)temp;
    if (PyModule_AddObjectRef(module, "Dialect", temp) < 0) {
        return -1;
    }

    temp = PyType_FromModuleAndSpec(module, &Reader_Type_spec, NULL);
    module_state->reader_type = (PyTypeObject *)temp;
    if (PyModule_AddObjectRef(module, "Reader", temp) < 0) {
        return -1;
    }

    temp = PyType_FromModuleAndSpec(module, &Writer_Type_spec, NULL);
    module_state->writer_type = (PyTypeObject *)temp;
    if (PyModule_AddObjectRef(module, "Writer", temp) < 0) {
        return -1;
    }

    /* Set the field limit */
    module_state->field_limit = 128 * 1024;

    /* Add _dialects dictionary */
    module_state->dialects = PyDict_New();
    if (PyModule_AddObjectRef(module, "_dialects", module_state->dialects) < 0) {
        return -1;
    }

    /* Add quote styles into dictionary */
    for (style = quote_styles; style->name; style++) {
        if (PyModule_AddIntConstant(module, style->name,
                                    style->style) == -1)
            return -1;
    }

    /* Add the CSV exception object to the module. */
    PyObject *bases = PyTuple_Pack(1, PyExc_Exception);
    if (bases == NULL) {
        return -1;
    }
    module_state->error_obj = PyType_FromModuleAndSpec(module, &error_spec,
                                                       bases);
    Py_DECREF(bases);
    if (module_state->error_obj == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, (PyTypeObject *)module_state->error_obj) != 0) {
        return -1;
    }

    module_state->str_write = PyUnicode_InternFromString("write");
    if (module_state->str_write == NULL) {
        return -1;
    }
    return 0;
}

static PyModuleDef_Slot csv_slots[] = {
    {Py_mod_exec, csv_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static struct PyModuleDef _csvmodule = {
    PyModuleDef_HEAD_INIT,
    "_csv",
    csv_module_doc,
    sizeof(_csvstate),
    csv_methods,
    csv_slots,
    _csv_traverse,
    _csv_clear,
    _csv_free
};

PyMODINIT_FUNC
PyInit__csv(void)
{
    return PyModuleDef_Init(&_csvmodule);
}
