From dbfdc380df615fe7e85107ff3954b8fff3ce7741 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Mon, 4 May 2015 06:59:46 -0700 Subject: [PATCH] Issue #24001: Argument Clinic converters now use accept={type} instead of types={'type'} to specify the types the converter accepts. --- Misc/NEWS | 3 + Modules/_dbmmodule.c | 8 +- Modules/_elementtree.c | 4 +- Modules/_gdbmmodule.c | 4 +- Modules/_io/_iomodule.c | 8 +- Modules/_io/bufferedio.c | 16 ++-- Modules/_io/bytesio.c | 4 +- Modules/_io/fileio.c | 4 +- Modules/_io/textio.c | 8 +- Modules/_ssl.c | 8 +- Modules/_tkinter.c | 6 +- Modules/arraymodule.c | 8 +- Modules/cjkcodecs/multibytecodec.c | 8 +- Modules/pyexpat.c | 10 +- Modules/unicodedata.c | 44 ++++----- Tools/clinic/clinic.py | 142 ++++++++++++++++++----------- 16 files changed, 163 insertions(+), 122 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index d8f1dc4018e..f6b574371f1 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -68,6 +68,9 @@ Documentation Tools/Demos ----------- +- Issue #24001: Argument Clinic converters now use accept={type} + instead of types={'type'} to specify the types the converter accepts. + - Issue #23330: h2py now supports arbitrary filenames in #include. - Issue #24031: make patchcheck now supports git checkouts, too. diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 6c605eacc9a..191cdd60888 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -274,7 +274,7 @@ static PySequenceMethods dbm_as_sequence = { /*[clinic input] _dbm.dbm.get - key: str(types={'str', 'robuffer'}, length=True) + key: str(accept={str, robuffer}, length=True) default: object(c_default="NULL") = b'' / @@ -284,7 +284,7 @@ Return the value for key if present, otherwise default. static PyObject * _dbm_dbm_get_impl(dbmobject *self, const char *key, Py_ssize_clean_t key_length, PyObject *default_value) -/*[clinic end generated code: output=b44f95eba8203d93 input=fee97bbe85e84822]*/ +/*[clinic end generated code: output=b44f95eba8203d93 input=3c7c1afd9c508457]*/ { datum dbm_key, val; @@ -301,7 +301,7 @@ _dbm_dbm_get_impl(dbmobject *self, const char *key, /*[clinic input] _dbm.dbm.setdefault - key: str(types={'str', 'robuffer'}, length=True) + key: str(accept={str, robuffer}, length=True) default: object(c_default="NULL") = b'' / @@ -314,7 +314,7 @@ static PyObject * _dbm_dbm_setdefault_impl(dbmobject *self, const char *key, Py_ssize_clean_t key_length, PyObject *default_value) -/*[clinic end generated code: output=52545886cf272161 input=6a3b99ae91f20203]*/ +/*[clinic end generated code: output=52545886cf272161 input=a66fcb7f18ee2f50]*/ { datum dbm_key, val; Py_ssize_t tmp_size; diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 342bcc68f97..ebdb95b05ec 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -3206,14 +3206,14 @@ _elementtree.XMLParser.__init__ html: object = NULL target: object = NULL - encoding: str(nullable=True) = NULL + encoding: str(accept={str, NoneType}) = NULL [clinic start generated code]*/ static int _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *html, PyObject *target, const char *encoding) -/*[clinic end generated code: output=d6a16c63dda54441 input=a870da39c80d7d68]*/ +/*[clinic end generated code: output=d6a16c63dda54441 input=155bc5695baafffd]*/ { self->entity = PyDict_New(); if (!self->entity) diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index eb6da8e1751..cce5c7e0086 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -383,7 +383,7 @@ _gdbm_gdbm_firstkey_impl(dbmobject *self) /*[clinic input] _gdbm.gdbm.nextkey - key: str(types={'str', 'robuffer'}, length=True) + key: str(accept={str, robuffer}, length=True) / Returns the key that follows key in the traversal. @@ -400,7 +400,7 @@ to create a list in memory that contains them all: static PyObject * _gdbm_gdbm_nextkey_impl(dbmobject *self, const char *key, Py_ssize_clean_t key_length) -/*[clinic end generated code: output=192ab892de6eb2f6 input=df8e8828201214a6]*/ +/*[clinic end generated code: output=192ab892de6eb2f6 input=1eb2ff9b4b0e6ffd]*/ { PyObject *v; datum dbm_key, nextkey; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index ea727f25c5e..528bcd4ac10 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -100,9 +100,9 @@ _io.open file: object mode: str = "r" buffering: int = -1 - encoding: str(nullable=True) = NULL - errors: str(nullable=True) = NULL - newline: str(nullable=True) = NULL + encoding: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = NULL + newline: str(accept={str, NoneType}) = NULL closefd: int(c_default="1") = True opener: object = None @@ -230,7 +230,7 @@ static PyObject * _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd, PyObject *opener) -/*[clinic end generated code: output=7615d0d746eb14d2 input=0541ce15691a82f2]*/ +/*[clinic end generated code: output=7615d0d746eb14d2 input=f4e1ca75223987bc]*/ { unsigned i; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 916353bdf78..2c9064855a6 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -101,26 +101,26 @@ _bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readint /*[clinic input] _io._BufferedIOBase.readinto - buffer: Py_buffer(types={'rwbuffer'}) + buffer: Py_buffer(accept={rwbuffer}) / [clinic start generated code]*/ static PyObject * _io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer) -/*[clinic end generated code: output=8c8cda6684af8038 input=f8242a06c21763a0]*/ +/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/ { return _bufferediobase_readinto_generic(self, buffer, 0); } /*[clinic input] _io._BufferedIOBase.readinto1 - buffer: Py_buffer(types={'rwbuffer'}) + buffer: Py_buffer(accept={rwbuffer}) / [clinic start generated code]*/ static PyObject * _io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer) -/*[clinic end generated code: output=358623e4fd2b69d3 input=2003e706c730bd21]*/ +/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/ { return _bufferediobase_readinto_generic(self, buffer, 1); } @@ -1065,26 +1065,26 @@ end: /*[clinic input] _io._Buffered.readinto - buffer: Py_buffer(types={'rwbuffer'}) + buffer: Py_buffer(accept={rwbuffer}) / [clinic start generated code]*/ static PyObject * _io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer) -/*[clinic end generated code: output=bcb376580b1d8170 input=962b7496eac38b3a]*/ +/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/ { return _buffered_readinto_generic(self, buffer, 0); } /*[clinic input] _io._Buffered.readinto1 - buffer: Py_buffer(types={'rwbuffer'}) + buffer: Py_buffer(accept={rwbuffer}) / [clinic start generated code]*/ static PyObject * _io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer) -/*[clinic end generated code: output=6e5c6ac5868205d6 input=834614d93f0adeb5]*/ +/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/ { return _buffered_readinto_generic(self, buffer, 1); } diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 42dfe2404a6..d46430dca5d 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -541,7 +541,7 @@ _io_BytesIO_readlines_impl(bytesio *self, PyObject *arg) /*[clinic input] _io.BytesIO.readinto - buffer: Py_buffer(types={'rwbuffer'}) + buffer: Py_buffer(accept={rwbuffer}) / Read up to len(buffer) bytes into buffer. @@ -552,7 +552,7 @@ is set not to block as has no data to read. static PyObject * _io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer) -/*[clinic end generated code: output=a5d407217dcf0639 input=d289da851c7c4159]*/ +/*[clinic end generated code: output=a5d407217dcf0639 input=71581f32635c3a31]*/ { Py_ssize_t len, n; diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 0894ca45c89..12e37bbbbe1 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -603,7 +603,7 @@ _io_FileIO_seekable_impl(fileio *self) /*[clinic input] _io.FileIO.readinto - buffer: Py_buffer(types={'rwbuffer'}) + buffer: Py_buffer(accept={rwbuffer}) / Same as RawIOBase.readinto(). @@ -611,7 +611,7 @@ Same as RawIOBase.readinto(). static PyObject * _io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer) -/*[clinic end generated code: output=b01a5a22c8415cb4 input=5edd8327498d468c]*/ +/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/ { Py_ssize_t n; int err; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index f61b2818f3d..c45f70dc21e 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -789,9 +789,9 @@ static encodefuncentry encodefuncs[] = { /*[clinic input] _io.TextIOWrapper.__init__ buffer: object - encoding: str(nullable=True) = NULL - errors: str(nullable=True) = NULL - newline: str(nullable=True) = NULL + encoding: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = NULL + newline: str(accept={str, NoneType}) = NULL line_buffering: int(c_default="0") = False write_through: int(c_default="0") = False @@ -830,7 +830,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, const char *encoding, const char *errors, const char *newline, int line_buffering, int write_through) -/*[clinic end generated code: output=56a83402ce2a8381 input=1f20decb8d54a4ec]*/ +/*[clinic end generated code: output=56a83402ce2a8381 input=3126cb3101a2c99b]*/ { PyObject *raw, *codec_info = NULL; _PyIO_State *state = NULL; diff --git a/Modules/_ssl.c b/Modules/_ssl.c index e758da6c4fa..7a9e0665cf5 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1877,7 +1877,7 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) _ssl._SSLSocket.read size as len: int [ - buffer: Py_buffer(types={'rwbuffer'}) + buffer: Py_buffer(accept={rwbuffer}) ] / @@ -1887,7 +1887,7 @@ Read up to size bytes from the SSL socket. static PyObject * _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, Py_buffer *buffer) -/*[clinic end generated code: output=00097776cec2a0af input=4a0bbd2859e817b0]*/ +/*[clinic end generated code: output=00097776cec2a0af input=ff157eb918d0905b]*/ { PyObject *dest = NULL; char *mem; @@ -3799,7 +3799,7 @@ static PyTypeObject PySSLMemoryBIO_Type = { /* helper routines for seeding the SSL PRNG */ /*[clinic input] _ssl.RAND_add - string as view: Py_buffer(types={'str', 'buffer'}) + string as view: Py_buffer(accept={str, buffer}) entropy: double / @@ -3811,7 +3811,7 @@ string. See RFC 1750. static PyObject * _ssl_RAND_add_impl(PyModuleDef *module, Py_buffer *view, double entropy) -/*[clinic end generated code: output=0f8d5c8cce328958 input=c98b11d606b354bc]*/ +/*[clinic end generated code: output=0f8d5c8cce328958 input=580c85e6a3a4fe29]*/ { const char *buf; Py_ssize_t len, written; diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 1f21c039837..208ec47092e 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3101,7 +3101,7 @@ _tkinter__flatten(PyModuleDef *module, PyObject *item) /*[clinic input] _tkinter.create - screenName: str(nullable=True) = NULL + screenName: str(accept={str, NoneType}) = NULL baseName: str = NULL className: str = "Tk" interactive: int(c_default="0") = False @@ -3110,7 +3110,7 @@ _tkinter.create if false, then Tk_Init() doesn't get called sync: int(c_default="0") = False if true, then pass -sync to wish - use: str(nullable=True) = NULL + use: str(accept={str, NoneType}) = NULL if not None, then pass -use to wish / @@ -3121,7 +3121,7 @@ _tkinter_create_impl(PyModuleDef *module, const char *screenName, const char *baseName, const char *className, int interactive, int wantobjects, int wantTk, int sync, const char *use) -/*[clinic end generated code: output=b8847800fc3b27eb input=c133c59a99dd0086]*/ +/*[clinic end generated code: output=b8847800fc3b27eb input=0d522aad1cb0ca0e]*/ { /* XXX baseName is not used anymore; * try getting rid of it. */ diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 47044905582..45e27eb1b37 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1600,7 +1600,7 @@ frombytes(arrayobject *self, Py_buffer *buffer) /*[clinic input] array.array.fromstring - buffer: Py_buffer(types={'str', 'buffer'}) + buffer: Py_buffer(accept={str, buffer}) / Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method). @@ -1610,7 +1610,7 @@ This method is deprecated. Use frombytes instead. static PyObject * array_array_fromstring_impl(arrayobject *self, Py_buffer *buffer) -/*[clinic end generated code: output=31c4baa779df84ce input=fdde1a56cbe2b05b]*/ +/*[clinic end generated code: output=31c4baa779df84ce input=a3341a512e11d773]*/ { if (PyErr_WarnEx(PyExc_DeprecationWarning, "fromstring() is deprecated. Use frombytes() instead.", 2) != 0) @@ -1929,7 +1929,7 @@ make_array(PyTypeObject *arraytype, char typecode, PyObject *items) array._array_reconstructor arraytype: object(type="PyTypeObject *") - typecode: int(types={'str'}) + typecode: int(accept={str}) mformat_code: int(type="enum machine_format_code") items: object / @@ -1942,7 +1942,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, enum machine_format_code mformat_code, PyObject *items) -/*[clinic end generated code: output=6ecbf0e8e4d92ab9 input=a9ae223306d7b262]*/ +/*[clinic end generated code: output=6ecbf0e8e4d92ab9 input=2464dc8f4c7736b5]*/ { PyObject *converted_items; PyObject *result; diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 70f7a21080f..c4dff412ef0 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -544,7 +544,7 @@ errorexit: _multibytecodec.MultibyteCodec.encode input: object - errors: str(nullable=True) = NULL + errors: str(accept={str, NoneType}) = NULL Return an encoded string version of `input'. @@ -558,7 +558,7 @@ static PyObject * _multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, PyObject *input, const char *errors) -/*[clinic end generated code: output=7b26652045ba56a9 input=252e7ee695867b2d]*/ +/*[clinic end generated code: output=7b26652045ba56a9 input=05f6ced3c8dd0582]*/ { MultibyteCodec_State state; PyObject *errorcb, *r, *ucvt; @@ -613,7 +613,7 @@ errorexit: _multibytecodec.MultibyteCodec.decode input: Py_buffer - errors: str(nullable=True) = NULL + errors: str(accept={str, NoneType}) = NULL Decodes 'input'. @@ -627,7 +627,7 @@ static PyObject * _multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, Py_buffer *input, const char *errors) -/*[clinic end generated code: output=ff419f65bad6cc77 input=37e1d9236e3ce8f3]*/ +/*[clinic end generated code: output=ff419f65bad6cc77 input=a7d45f87f75e5e02]*/ { MultibyteCodec_State state; MultibyteDecodeBuffer buf; diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 706319ec00c..7a8e96a2d9a 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -911,7 +911,7 @@ pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self) /*[clinic input] pyexpat.xmlparser.ExternalEntityParserCreate - context: str(nullable=True) + context: str(accept={str, NoneType}) encoding: str = NULL / @@ -922,7 +922,7 @@ static PyObject * pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, const char *context, const char *encoding) -/*[clinic end generated code: output=535cda9d7a0fbcd6 input=283206575d960272]*/ +/*[clinic end generated code: output=535cda9d7a0fbcd6 input=b906714cc122c322]*/ { xmlparseobject *new_parser; int i; @@ -1546,8 +1546,8 @@ static PyTypeObject Xmlparsetype = { /*[clinic input] pyexpat.ParserCreate - encoding: str(nullable=True) = NULL - namespace_separator: str(nullable=True) = NULL + encoding: str(accept={str, NoneType}) = NULL + namespace_separator: str(accept={str, NoneType}) = NULL intern: object = NULL Return a new XML parser object. @@ -1556,7 +1556,7 @@ Return a new XML parser object. static PyObject * pyexpat_ParserCreate_impl(PyModuleDef *module, const char *encoding, const char *namespace_separator, PyObject *intern) -/*[clinic end generated code: output=81fccd233e1743a8 input=71b9f471aa6f8f86]*/ +/*[clinic end generated code: output=81fccd233e1743a8 input=23d29704acad385d]*/ { PyObject *result; int intern_decref = 0; diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 47ada378182..b4336f2d46d 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -107,7 +107,7 @@ new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4) unicodedata.UCD.decimal self: self - chr: int(types={'str'}) + chr: int(accept={str}) default: object=NULL / @@ -121,7 +121,7 @@ ValueError is raised. static PyObject * unicodedata_UCD_decimal_impl(PyObject *self, int chr, PyObject *default_value) -/*[clinic end generated code: output=be23376e1a185231 input=3acf7f2238874a49]*/ +/*[clinic end generated code: output=be23376e1a185231 input=933f8107993f23d0]*/ { int have_old = 0; long rc; @@ -160,7 +160,7 @@ unicodedata_UCD_decimal_impl(PyObject *self, int chr, unicodedata.UCD.digit self: self - chr: int(types={'str'}) + chr: int(accept={str}) default: object=NULL / @@ -173,7 +173,7 @@ ValueError is raised. static PyObject * unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value) -/*[clinic end generated code: output=96e18c950171fd2f input=733f093b399f5ab6]*/ +/*[clinic end generated code: output=96e18c950171fd2f input=e27d6e4565cd29f2]*/ { long rc; Py_UCS4 c = (Py_UCS4)chr; @@ -195,7 +195,7 @@ unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value) unicodedata.UCD.numeric self: self - chr: int(types={'str'}) + chr: int(accept={str}) default: object=NULL / @@ -209,7 +209,7 @@ ValueError is raised. static PyObject * unicodedata_UCD_numeric_impl(PyObject *self, int chr, PyObject *default_value) -/*[clinic end generated code: output=53ce281fe85b10c4 input=c5875fa7cc768fb2]*/ +/*[clinic end generated code: output=53ce281fe85b10c4 input=fdf5871a5542893c]*/ { int have_old = 0; double rc; @@ -247,7 +247,7 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr, unicodedata.UCD.category self: self - chr: int(types={'str'}) + chr: int(accept={str}) / Returns the general category assigned to the character chr as string. @@ -255,7 +255,7 @@ Returns the general category assigned to the character chr as string. static PyObject * unicodedata_UCD_category_impl(PyObject *self, int chr) -/*[clinic end generated code: output=8571539ee2e6783a input=f5edd6fd04bd455d]*/ +/*[clinic end generated code: output=8571539ee2e6783a input=27d6f3d85050bc06]*/ { int index; Py_UCS4 c = (Py_UCS4)chr; @@ -272,7 +272,7 @@ unicodedata_UCD_category_impl(PyObject *self, int chr) unicodedata.UCD.bidirectional self: self - chr: int(types={'str'}) + chr: int(accept={str}) / Returns the bidirectional class assigned to the character chr as string. @@ -282,7 +282,7 @@ If no such value is defined, an empty string is returned. static PyObject * unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) -/*[clinic end generated code: output=d36310ce2039bb92 input=5ce2f877b35305b5]*/ +/*[clinic end generated code: output=d36310ce2039bb92 input=b3d8f42cebfcf475]*/ { int index; Py_UCS4 c = (Py_UCS4)chr; @@ -301,7 +301,7 @@ unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) unicodedata.UCD.combining -> int self: self - chr: int(types={'str'}) + chr: int(accept={str}) / Returns the canonical combining class assigned to the character chr as integer. @@ -311,7 +311,7 @@ Returns 0 if no combining class is defined. static int unicodedata_UCD_combining_impl(PyObject *self, int chr) -/*[clinic end generated code: output=cad056d0cb6a5920 input=9125ea7d50b319e7]*/ +/*[clinic end generated code: output=cad056d0cb6a5920 input=9f2d6b2a95d0a22a]*/ { int index; Py_UCS4 c = (Py_UCS4)chr; @@ -328,7 +328,7 @@ unicodedata_UCD_combining_impl(PyObject *self, int chr) unicodedata.UCD.mirrored -> int self: self - chr: int(types={'str'}) + chr: int(accept={str}) / Returns the mirrored property assigned to the character chr as integer. @@ -339,7 +339,7 @@ character in bidirectional text, 0 otherwise. static int unicodedata_UCD_mirrored_impl(PyObject *self, int chr) -/*[clinic end generated code: output=2532dbf8121b50e6 input=4e51e8aaf8d7e23e]*/ +/*[clinic end generated code: output=2532dbf8121b50e6 input=5dd400d351ae6f3b]*/ { int index; Py_UCS4 c = (Py_UCS4)chr; @@ -358,7 +358,7 @@ unicodedata_UCD_mirrored_impl(PyObject *self, int chr) unicodedata.UCD.east_asian_width self: self - chr: int(types={'str'}) + chr: int(accept={str}) / Returns the east asian width assigned to the character chr as string. @@ -366,7 +366,7 @@ Returns the east asian width assigned to the character chr as string. static PyObject * unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) -/*[clinic end generated code: output=484e8537d9ee8197 input=f93c61f37276c8f0]*/ +/*[clinic end generated code: output=484e8537d9ee8197 input=c4854798aab026e0]*/ { int index; Py_UCS4 c = (Py_UCS4)chr; @@ -383,7 +383,7 @@ unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) unicodedata.UCD.decomposition self: self - chr: int(types={'str'}) + chr: int(accept={str}) / Returns the character decomposition mapping assigned to the character chr as string. @@ -393,7 +393,7 @@ An empty string is returned in case no such mapping is defined. static PyObject * unicodedata_UCD_decomposition_impl(PyObject *self, int chr) -/*[clinic end generated code: output=7d699f3ec7565d27 input=7f2c0ee66d75468f]*/ +/*[clinic end generated code: output=7d699f3ec7565d27 input=e4c12459ad68507b]*/ { char decomp[256]; int code, index, count; @@ -1180,7 +1180,7 @@ static const _PyUnicode_Name_CAPI hashAPI = unicodedata.UCD.name self: self - chr: int(types={'str'}) + chr: int(accept={str}) default: object=NULL / @@ -1192,7 +1192,7 @@ ValueError is raised. static PyObject * unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value) -/*[clinic end generated code: output=6bbb37a326407707 input=51ee2f971c918113]*/ +/*[clinic end generated code: output=6bbb37a326407707 input=3e0367f534de56d9]*/ { char name[NAME_MAXLEN]; Py_UCS4 c = (Py_UCS4)chr; @@ -1215,7 +1215,7 @@ unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value) unicodedata.UCD.lookup self: self - name: str(types={'str', 'robuffer'}, length=True) + name: str(accept={str, robuffer}, length=True) / Look up character by name. @@ -1227,7 +1227,7 @@ corresponding character. If not found, KeyError is raised. static PyObject * unicodedata_UCD_lookup_impl(PyObject *self, const char *name, Py_ssize_clean_t name_length) -/*[clinic end generated code: output=765cb8186788e6be input=f2bf29706135a590]*/ +/*[clinic end generated code: output=765cb8186788e6be input=2dfe682c2491447a]*/ { Py_UCS4 code; unsigned int index; diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 5626dd9fdcd..4f0615fd731 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -26,8 +26,12 @@ import sys import tempfile import textwrap import traceback +import types import uuid +from types import * +NoneType = type(None) + # TODO: # # soon: @@ -2526,18 +2530,18 @@ class unsigned_short_converter(CConverter): if not bitwise: fail("Unsigned shorts must be bitwise (for now).") -@add_legacy_c_converter('C', types={'str'}) +@add_legacy_c_converter('C', accept={str}) class int_converter(CConverter): type = 'int' default_type = int format_unit = 'i' c_ignored_default = "0" - def converter_init(self, *, types={'int'}, type=None): - if types == {'str'}: + def converter_init(self, *, accept={int}, type=None): + if accept == {str}: self.format_unit = 'C' - elif types != {'int'}: - fail("int_converter: illegal 'types' argument " + repr(types)) + elif accept != {int}: + fail("int_converter: illegal 'accept' argument " + repr(accept)) if type != None: self.type = type @@ -2629,17 +2633,22 @@ class object_converter(CConverter): # -# We define three string conventions for buffer types in the 'types' argument: -# 'buffer' : any object supporting the buffer interface -# 'rwbuffer': any object supporting the buffer interface, but must be writeable -# 'robuffer': any object supporting the buffer interface, but must not be writeable +# We define three conventions for buffer types in the 'accept' argument: +# +# buffer : any object supporting the buffer interface +# rwbuffer: any object supporting the buffer interface, but must be writeable +# robuffer: any object supporting the buffer interface, but must not be writeable # -@add_legacy_c_converter('s#', types={"str", "robuffer"}, length=True) -@add_legacy_c_converter('y', types={"robuffer"}) -@add_legacy_c_converter('y#', types={"robuffer"}, length=True) -@add_legacy_c_converter('z', nullable=True) -@add_legacy_c_converter('z#', types={"str", "robuffer"}, nullable=True, length=True) +class buffer: pass +class rwbuffer: pass +class robuffer: pass + +@add_legacy_c_converter('s#', accept={str, robuffer}, length=True) +@add_legacy_c_converter('y', accept={robuffer}) +@add_legacy_c_converter('y#', accept={robuffer}, length=True) +@add_legacy_c_converter('z', accept={str, NoneType}) +@add_legacy_c_converter('z#', accept={str, NoneType}, length=True) # add_legacy_c_converter not supported for es, es#, et, et# # because of their extra encoding argument class str_converter(CConverter): @@ -2647,45 +2656,47 @@ class str_converter(CConverter): default_type = (str, Null, NoneType) format_unit = 's' - def converter_init(self, *, encoding=None, types={"str"}, - length=False, nullable=False, zeroes=False): + def converter_init(self, *, encoding=None, accept={str}, length=False, zeroes=False): self.length = bool(length) - is_b_or_ba = types == {"bytes", "bytearray"} - is_str = types == {"str"} - is_robuffer = types == {"robuffer"} - is_str_or_robuffer = types == {"str", "robuffer"} + is_b_or_ba = accept == {bytes, bytearray} + is_b_or_ba_or_none = accept == {bytes, bytearray, NoneType} + is_str = accept == {str} + is_str_or_none = accept == {str, NoneType} + is_robuffer = accept == {robuffer} + is_str_or_robuffer = accept == {str, robuffer} + is_str_or_robuffer_or_none = accept == {str, robuffer, NoneType} format_unit = None if encoding: self.encoding = encoding - if is_str and not length and not zeroes and not nullable: + if is_str and not length and not zeroes: format_unit = 'es' - elif is_str and length and zeroes and nullable: + elif is_str_or_none and length and zeroes: format_unit = 'es#' - elif is_b_or_ba and not length and not zeroes and not nullable: + elif is_b_or_ba and not length and not zeroes: format_unit = 'et' - elif is_b_or_ba and length and zeroes and nullable: + elif is_b_or_ba_or_none and length and zeroes: format_unit = 'et#' else: if zeroes: fail("str_converter: illegal combination of arguments (zeroes is only legal with an encoding)") - if is_str and not length and not nullable: + if is_str and not length: format_unit = 's' - elif is_str and not length and nullable: + elif is_str_or_none and not length: format_unit = 'z' - elif is_robuffer and not length and not nullable: + elif is_robuffer and not length: format_unit = 'y' - elif is_robuffer and length and not nullable: + elif is_robuffer and length: format_unit = 'y#' - elif is_str_or_robuffer and length and not nullable: + elif is_str_or_robuffer and length: format_unit = 's#' - elif is_str_or_robuffer and length and nullable: + elif is_str_or_robuffer_or_none and length: format_unit = 'z#' if not format_unit: @@ -2696,12 +2707,12 @@ class str_converter(CConverter): class PyBytesObject_converter(CConverter): type = 'PyBytesObject *' format_unit = 'S' - # types = {'bytes'} + # accept = {bytes} class PyByteArrayObject_converter(CConverter): type = 'PyByteArrayObject *' format_unit = 'Y' - # types = {'bytearray'} + # accept = {bytearray} class unicode_converter(CConverter): type = 'PyObject *' @@ -2709,45 +2720,44 @@ class unicode_converter(CConverter): format_unit = 'U' @add_legacy_c_converter('u#', length=True) -@add_legacy_c_converter('Z', nullable=True) -@add_legacy_c_converter('Z#', nullable=True, length=True) +@add_legacy_c_converter('Z', accept={str, NoneType}) +@add_legacy_c_converter('Z#', accept={str, NoneType}, length=True) class Py_UNICODE_converter(CConverter): type = 'Py_UNICODE *' default_type = (str, Null, NoneType) format_unit = 'u' - def converter_init(self, *, nullable=False, length=False): - format_unit = 'Z' if nullable else 'u' + def converter_init(self, *, accept={str}, length=False): + format_unit = 'Z' if accept=={str, NoneType} else 'u' if length: format_unit += '#' self.length = True self.format_unit = format_unit -@add_legacy_c_converter('s*', types={'str', 'buffer'}) -@add_legacy_c_converter('z*', types={'str', 'buffer'}, nullable=True) -@add_legacy_c_converter('w*', types={'rwbuffer'}) +@add_legacy_c_converter('s*', accept={str, buffer}) +@add_legacy_c_converter('z*', accept={str, buffer, NoneType}) +@add_legacy_c_converter('w*', accept={rwbuffer}) class Py_buffer_converter(CConverter): type = 'Py_buffer' format_unit = 'y*' impl_by_reference = True c_ignored_default = "{NULL, NULL}" - def converter_init(self, *, types={'buffer'}, nullable=False): + def converter_init(self, *, accept={buffer}): if self.default not in (unspecified, None): fail("The only legal default value for Py_buffer is None.") + self.c_default = self.c_ignored_default - format_unit = None - if types == {'str', 'buffer'}: - format_unit = 's*' if not nullable else 'z*' + if accept == {str, buffer, NoneType}: + format_unit = 'z*' + elif accept == {str, buffer}: + format_unit = 's*' + elif accept == {buffer}: + format_unit = 'y*' + elif accept == {rwbuffer}: + format_unit = 'w*' else: - if nullable: - fail('Py_buffer_converter: illegal combination of arguments (nullable=True)') - elif types == {'buffer'}: - format_unit = 'y*' - elif types == {'rwbuffer'}: - format_unit = 'w*' - if not format_unit: fail("Py_buffer_converter: illegal combination of arguments") self.format_unit = format_unit @@ -3030,6 +3040,24 @@ class DecodeFSDefault_return_converter(CReturnConverter): 'return_value = PyUnicode_DecodeFSDefault(_return_value);\n') +def eval_ast_expr(node, globals, *, filename='-'): + """ + Takes an ast.Expr node. Compiles and evaluates it. + Returns the result of the expression. + + globals represents the globals dict the expression + should see. (There's no equivalent for "locals" here.) + """ + + if isinstance(node, ast.Expr): + node = node.value + + node = ast.Expression(node) + co = compile(node, filename, 'eval') + fn = types.FunctionType(co, globals) + return fn() + + class IndentStack: def __init__(self): self.indents = [] @@ -3617,7 +3645,7 @@ class DSLParser: except SyntaxError: try: # the last = was probably inside a function call, like - # i: int(nullable=True) + # c: int(accept={str}) # so assume there was no actual default value. default = None ast_input = "def x({}): pass".format(line) @@ -3628,6 +3656,14 @@ class DSLParser: fail("Function " + self.function.name + " has an invalid parameter declaration:\n\t" + line) function_args = module.body[0].args + + if len(function_args.args) > 1: + fail("Function " + self.function.name + " has an invalid parameter declaration (comma?):\n\t" + line) + if function_args.defaults or function_args.kw_defaults: + fail("Function " + self.function.name + " has an invalid parameter declaration (default value?):\n\t" + line) + if function_args.vararg or function_args.kwarg: + fail("Function " + self.function.name + " has an invalid parameter declaration (*args? **kwargs?):\n\t" + line) + parameter = function_args.args[0] parameter_name = parameter.arg @@ -3790,7 +3826,9 @@ class DSLParser: fail("Annotations must be either a name, a function call, or a string.") name = annotation.func.id - kwargs = {node.arg: ast.literal_eval(node.value) for node in annotation.keywords} + symbols = globals() + + kwargs = {node.arg: eval_ast_expr(node.value, symbols) for node in annotation.keywords} return name, False, kwargs def parse_special_symbol(self, symbol):