diff -r 1638360eea41 Modules/_csv.c --- a/Modules/_csv.c Sat Jan 11 22:22:21 2014 -0800 +++ b/Modules/_csv.c Sun Jan 12 09:31:05 2014 +0100 @@ -13,6 +13,11 @@ module instead. #include "Python.h" #include "structmember.h" +/*[clinic input] +module _csv +class _csv.Dialect +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ typedef struct { PyObject *error_obj; /* CSV exception */ @@ -322,24 +327,32 @@ Dialect_dealloc(DialectObj *self) Py_TYPE(self)->tp_free((PyObject *)self); } -static char *dialect_kws[] = { - "dialect", - "delimiter", - "doublequote", - "escapechar", - "lineterminator", - "quotechar", - "quoting", - "skipinitialspace", - "strict", - NULL -}; + +/*[clinic input] +@new +_csv.Dialect.__new__ + + dialect: 'O' = NULL + delimiter: 'O' = NULL + doublequote: 'O' = NULL + escapechar: 'O' = NULL + lineterminator: 'O' = NULL + quotechar: 'O' = NULL + quoting: 'O' = NULL + skipinitialspace: 'O' = NULL + strict: 'O' = NULL + +Construct a new dialect. +[clinic start generated code]*/ static PyObject * -dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +_csv_Dialect___new___impl(PyTypeObject *type, PyObject *dialect, PyObject *delimiter, PyObject *doublequote, PyObject *escapechar, PyObject *lineterminator, PyObject *quotechar, PyObject *quoting, PyObject *skipinitialspace, PyObject *strict); + +static PyObject * +_csv_Dialect___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - DialectObj *self; - PyObject *ret = NULL; + PyObject *return_value = NULL; + static char *_keywords[] = {"dialect", "delimiter", "doublequote", "escapechar", "lineterminator", "quotechar", "quoting", "skipinitialspace", "strict", NULL}; PyObject *dialect = NULL; PyObject *delimiter = NULL; PyObject *doublequote = NULL; @@ -351,17 +364,21 @@ dialect_new(PyTypeObject *type, PyObject PyObject *strict = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|OOOOOOOOO", dialect_kws, - &dialect, - &delimiter, - &doublequote, - &escapechar, - &lineterminator, - "echar, - "ing, - &skipinitialspace, - &strict)) - return NULL; + "|OOOOOOOOO:Dialect", _keywords, + &dialect, &delimiter, &doublequote, &escapechar, &lineterminator, "echar, "ing, &skipinitialspace, &strict)) + goto exit; + return_value = _csv_Dialect___new___impl(type, dialect, delimiter, doublequote, escapechar, lineterminator, quotechar, quoting, skipinitialspace, strict); + +exit: + return return_value; +} + +static PyObject * +_csv_Dialect___new___impl(PyTypeObject *type, PyObject *dialect, PyObject *delimiter, PyObject *doublequote, PyObject *escapechar, PyObject *lineterminator, PyObject *quotechar, PyObject *quoting, PyObject *skipinitialspace, PyObject *strict) +/*[clinic end generated code: checksum=8b85a2cfc93648f9a7d135c93bdea01f12b4fd3c]*/ +{ + DialectObj *self; + PyObject *ret = NULL; if (dialect != NULL) { if (PyUnicode_Check(dialect)) { @@ -508,7 +525,7 @@ static PyTypeObject Dialect_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - dialect_new, /* tp_new */ + _csv_Dialect___new__, /* tp_new */ 0, /* tp_free */ }; @@ -1417,12 +1434,41 @@ csv_writer(PyObject *module, PyObject *a /* * DIALECT REGISTRY */ + +/*[clinic input] +_csv.list_dialects + +Return a list of all know dialect names. +[clinic start generated code]*/ + +PyDoc_STRVAR(_csv_list_dialects__doc__, +"list_dialects()\n" +"Return a list of all know dialect names."); + +#define _CSV_LIST_DIALECTS_METHODDEF \ + {"list_dialects", (PyCFunction)_csv_list_dialects, METH_NOARGS, _csv_list_dialects__doc__}, + static PyObject * -csv_list_dialects(PyObject *module, PyObject *args) +_csv_list_dialects_impl(PyModuleDef *module); + +static PyObject * +_csv_list_dialects(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _csv_list_dialects_impl(module); + + return return_value; +} + +static PyObject * +_csv_list_dialects_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=2f92b96cc3faf7d0de1cc5399712510b6d043fdb]*/ { return PyDict_Keys(_csvstate_global->dialects); } + static PyObject * csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) { @@ -1450,36 +1496,110 @@ csv_register_dialect(PyObject *module, P return Py_None; } +/*[clinic input] +_csv.unregister_dialect + + name: 'O' + / + +Delete the name/dialect mapping associated with a string name. +[clinic start generated code]*/ + +PyDoc_STRVAR(_csv_unregister_dialect__doc__, +"unregister_dialect(name)\n" +"Delete the name/dialect mapping associated with a string name."); + +#define _CSV_UNREGISTER_DIALECT_METHODDEF \ + {"unregister_dialect", (PyCFunction)_csv_unregister_dialect, METH_O, _csv_unregister_dialect__doc__}, + static PyObject * -csv_unregister_dialect(PyObject *module, PyObject *name_obj) +_csv_unregister_dialect(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=9c33ef47c236073b4c874918b99715d9031e16c6]*/ { - if (PyDict_DelItem(_csvstate_global->dialects, name_obj) < 0) + if (PyDict_DelItem(_csvstate_global->dialects, name) < 0) return PyErr_Format(_csvstate_global->error_obj, "unknown dialect"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; +} + + +/*[clinic input] +_csv.get_dialect + + name: 'O' + / + +Return the dialect instance associated with name. +[clinic start generated code]*/ + +PyDoc_STRVAR(_csv_get_dialect__doc__, +"get_dialect(name)\n" +"Return the dialect instance associated with name."); + +#define _CSV_GET_DIALECT_METHODDEF \ + {"get_dialect", (PyCFunction)_csv_get_dialect, METH_O, _csv_get_dialect__doc__}, + +static PyObject * +_csv_get_dialect(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: checksum=239de66cde53129870e2aab2cb95daeba233ea54]*/ +{ + return get_dialect_from_registry(name); +} + + +/*[clinic input] +_csv.field_size_limit + + limit: 'O' = 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]*/ + +PyDoc_STRVAR(_csv_field_size_limit__doc__, +"field_size_limit(limit=None)\n" +"Sets an upper limit on parsed fields.\n" +"\n" +"Returns old limit. If limit is not given, no new limit is set and\n" +"the old limit is returned."); + +#define _CSV_FIELD_SIZE_LIMIT_METHODDEF \ + {"field_size_limit", (PyCFunction)_csv_field_size_limit, METH_VARARGS, _csv_field_size_limit__doc__}, + +static PyObject * +_csv_field_size_limit_impl(PyModuleDef *module, PyObject *limit); + +static PyObject * +_csv_field_size_limit(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *limit = NULL; + + if (!PyArg_ParseTuple(args, + "|O:field_size_limit", + &limit)) + goto exit; + return_value = _csv_field_size_limit_impl(module, limit); + +exit: + return return_value; } static PyObject * -csv_get_dialect(PyObject *module, PyObject *name_obj) +_csv_field_size_limit_impl(PyModuleDef *module, PyObject *limit) +/*[clinic end generated code: checksum=af1e08ed116500db157149f2c9dc991a6d6c9483]*/ { - return get_dialect_from_registry(name_obj); -} - -static PyObject * -csv_field_size_limit(PyObject *module, PyObject *args) -{ - PyObject *new_limit = NULL; long old_limit = _csvstate_global->field_limit; - if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit)) - return NULL; - if (new_limit != NULL) { - if (!PyLong_CheckExact(new_limit)) { + if (limit != NULL) { + if (!PyLong_CheckExact(limit)) { PyErr_Format(PyExc_TypeError, "limit must be an integer"); return NULL; } - _csvstate_global->field_limit = PyLong_AsLong(new_limit); + _csvstate_global->field_limit = PyLong_AsLong(limit); if (_csvstate_global->field_limit == -1 && PyErr_Occurred()) { _csvstate_global->field_limit = old_limit; return NULL; @@ -1579,44 +1699,22 @@ PyDoc_STRVAR(csv_writer_doc, "\n" "The \"fileobj\" argument can be any object that supports the file API.\n"); -PyDoc_STRVAR(csv_list_dialects_doc, -"Return a list of all know dialect names.\n" -" names = csv.list_dialects()"); - -PyDoc_STRVAR(csv_get_dialect_doc, -"Return the dialect instance associated with name.\n" -" dialect = csv.get_dialect(name)"); - PyDoc_STRVAR(csv_register_dialect_doc, "Create a mapping from a string name to a dialect class.\n" " dialect = csv.register_dialect(name, dialect)"); -PyDoc_STRVAR(csv_unregister_dialect_doc, -"Delete the name/dialect mapping associated with a string name.\n" -" csv.unregister_dialect(name)"); - -PyDoc_STRVAR(csv_field_size_limit_doc, -"Sets an upper limit on parsed fields.\n" -" csv.field_size_limit([limit])\n" -"\n" -"Returns old limit. If limit is not given, no new limit is set and\n" -"the old limit is returned"); static struct PyMethodDef csv_methods[] = { { "reader", (PyCFunction)csv_reader, METH_VARARGS | METH_KEYWORDS, csv_reader_doc}, { "writer", (PyCFunction)csv_writer, METH_VARARGS | METH_KEYWORDS, csv_writer_doc}, - { "list_dialects", (PyCFunction)csv_list_dialects, - METH_NOARGS, csv_list_dialects_doc}, { "register_dialect", (PyCFunction)csv_register_dialect, - METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc}, - { "unregister_dialect", (PyCFunction)csv_unregister_dialect, - METH_O, csv_unregister_dialect_doc}, - { "get_dialect", (PyCFunction)csv_get_dialect, - METH_O, csv_get_dialect_doc}, - { "field_size_limit", (PyCFunction)csv_field_size_limit, - METH_VARARGS, csv_field_size_limit_doc}, + 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 } }; diff -r 1638360eea41 Tools/clinic/clinic.py --- a/Tools/clinic/clinic.py Sat Jan 11 22:22:21 2014 -0800 +++ b/Tools/clinic/clinic.py Sun Jan 12 09:31:05 2014 +0100 @@ -391,6 +391,8 @@ class CLanguage(Language): @staticmethod def template_base(*args): + if '__suppress__' in args: + return '' flags = '|'.join(f for f in args if f) return """ PyDoc_STRVAR({c_basename}__doc__, @@ -640,7 +642,11 @@ static {impl_return_type} full_name = f.full_name template_dict['full_name'] = full_name - name = full_name.rpartition('.')[2] + # __new__ methods get the class name as their name + if f.kind == NEW_METHOD: + name = full_name.split('.')[-2] + else: + name = full_name.rpartition('.')[2] template_dict['name'] = name c_basename = f.c_basename or full_name.replace(".", "_") @@ -1165,7 +1171,7 @@ class Class: return "" -DATA, CALLABLE, METHOD, STATIC_METHOD, CLASS_METHOD = range(5) +DATA, CALLABLE, METHOD, STATIC_METHOD, CLASS_METHOD, NEW_METHOD = range(6) class Function: """ @@ -1201,7 +1207,11 @@ class Function: @property def methoddef_flags(self): flags = [] - if self.kind == CLASS_METHOD: + # __new__ methods don't have a MethodDef entry, so we take this + # special value to suppress both it and the docstring. + if self.kind == NEW_METHOD: + flags.append('__suppress__') + elif self.kind == CLASS_METHOD: flags.append('METH_CLASS') elif self.kind == STATIC_METHOD: flags.append('METH_STATIC') @@ -1809,6 +1819,9 @@ class self_converter(CConverter): elif f.kind == CLASS_METHOD: self.name = "cls" self.type = "PyTypeObject *" + elif f.kind == NEW_METHOD: + self.name = "type" + self.type = "PyTypeObject *" if type: self.type = type @@ -2080,6 +2093,10 @@ class DSLParser: assert self.coexist == False self.coexist = True + def at_new(self): + assert self.kind is CALLABLE + self.kind = NEW_METHOD + def parse(self, block): self.reset()