Issue #24001: Argument Clinic converters now use accept={type}

instead of types={'type'} to specify the types the converter accepts.
This commit is contained in:
Larry Hastings 2015-05-04 06:59:46 -07:00
parent cb98556373
commit dbfdc380df
16 changed files with 163 additions and 122 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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. */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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):