mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Fixed "u#" parser marker to pass through Unicode objects as-is without
going through the buffer interface API. Added tests for this to the _testcapi module and updated docs.
This commit is contained in:
		
							parent
							
								
									e0b1e6af58
								
							
						
					
					
						commit
						3e3eacb5fc
					
				
					 4 changed files with 61 additions and 2 deletions
				
			
		|  | @ -669,6 +669,8 @@ address you pass. | ||||||
| \item[\samp{u\#} (Unicode object) {[Py_UNICODE *, int]}] | \item[\samp{u\#} (Unicode object) {[Py_UNICODE *, int]}] | ||||||
| This variant on \samp{u} stores into two C variables, the first one | This variant on \samp{u} stores into two C variables, the first one | ||||||
| a pointer to a Unicode data buffer, the second one its length. | a pointer to a Unicode data buffer, the second one its length. | ||||||
|  | Non-Unicode objects are handled by interpreting their read buffer | ||||||
|  | pointer as pointer to a Py_UNICODE array. | ||||||
| 
 | 
 | ||||||
| \item[\samp{es} (string, Unicode object or character buffer compatible | \item[\samp{es} (string, Unicode object or character buffer compatible | ||||||
| object) {[const char *encoding, char **buffer]}] | object) {[const char *encoding, char **buffer]}] | ||||||
|  |  | ||||||
|  | @ -28,6 +28,9 @@ Build | ||||||
| 
 | 
 | ||||||
| C API | C API | ||||||
| 
 | 
 | ||||||
|  | - The "u#" parser marker will now pass through Unicode object as-is | ||||||
|  |   without going through the buffer API. | ||||||
|  | 
 | ||||||
| - The enumerators of cmp_op have been renamed to use the prefix PyCmp_. | - The enumerators of cmp_op have been renamed to use the prefix PyCmp_. | ||||||
| 
 | 
 | ||||||
| - An old #define of ANY as void has been removed from pyport.h.  This | - An old #define of ANY as void has been removed from pyport.h.  This | ||||||
|  |  | ||||||
|  | @ -307,6 +307,53 @@ test_L_code(PyObject *self, PyObject *args) | ||||||
| 
 | 
 | ||||||
| #endif	/* ifdef HAVE_LONG_LONG */ | #endif	/* ifdef HAVE_LONG_LONG */ | ||||||
| 
 | 
 | ||||||
|  | #ifdef Py_USING_UNICODE | ||||||
|  | 
 | ||||||
|  | /* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case
 | ||||||
|  |    of an error. | ||||||
|  | */ | ||||||
|  | static PyObject * | ||||||
|  | test_u_code(PyObject *self, PyObject *args) | ||||||
|  | { | ||||||
|  | 	PyObject *tuple, *obj; | ||||||
|  | 	Py_UNICODE *value; | ||||||
|  | 	int len; | ||||||
|  | 
 | ||||||
|  |         if (!PyArg_ParseTuple(args, ":test_u_code")) | ||||||
|  |                 return NULL; | ||||||
|  | 
 | ||||||
|  |         tuple = PyTuple_New(1); | ||||||
|  |         if (tuple == NULL) | ||||||
|  |         	return NULL; | ||||||
|  | 
 | ||||||
|  |         obj = PyUnicode_Decode("test", strlen("test"), | ||||||
|  | 			       "ascii", NULL); | ||||||
|  |         if (obj == NULL) | ||||||
|  |         	return NULL; | ||||||
|  | 
 | ||||||
|  |         PyTuple_SET_ITEM(tuple, 0, obj); | ||||||
|  | 
 | ||||||
|  |         value = 0; | ||||||
|  |         if (PyArg_ParseTuple(tuple, "u:test_u_code", &value) < 0) | ||||||
|  |         	return NULL; | ||||||
|  |         if (value != PyUnicode_AS_UNICODE(obj)) | ||||||
|  |         	return raiseTestError("test_u_code", | ||||||
|  | 			"u code returned wrong value for u'test'"); | ||||||
|  |         value = 0; | ||||||
|  |         if (PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len) < 0) | ||||||
|  |         	return NULL; | ||||||
|  |         if (value != PyUnicode_AS_UNICODE(obj) || | ||||||
|  | 	    len != PyUnicode_GET_SIZE(obj)) | ||||||
|  |         	return raiseTestError("test_u_code", | ||||||
|  | 			"u# code returned wrong values for u'test'"); | ||||||
|  | 	 | ||||||
|  | 	Py_DECREF(tuple); | ||||||
|  | 	Py_INCREF(Py_None); | ||||||
|  | 	return Py_None; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| static PyObject * | static PyObject * | ||||||
| raise_exception(PyObject *self, PyObject *args) | raise_exception(PyObject *self, PyObject *args) | ||||||
| { | { | ||||||
|  | @ -342,6 +389,9 @@ static PyMethodDef TestMethods[] = { | ||||||
| #ifdef HAVE_LONG_LONG | #ifdef HAVE_LONG_LONG | ||||||
| 	{"test_longlong_api",	test_longlong_api,	METH_VARARGS}, | 	{"test_longlong_api",	test_longlong_api,	METH_VARARGS}, | ||||||
| 	{"test_L_code",		test_L_code,		METH_VARARGS}, | 	{"test_L_code",		test_L_code,		METH_VARARGS}, | ||||||
|  | #endif | ||||||
|  | #ifdef Py_USING_UNICODE | ||||||
|  | 	{"test_u_code",		test_u_code,		METH_VARARGS}, | ||||||
| #endif | #endif | ||||||
| 	{NULL, NULL} /* sentinel */ | 	{NULL, NULL} /* sentinel */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -838,16 +838,20 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf, | ||||||
| 		if (*format == '#') { /* any buffer-like object */ | 		if (*format == '#') { /* any buffer-like object */ | ||||||
| 			void **p = (void **)va_arg(*p_va, char **); | 			void **p = (void **)va_arg(*p_va, char **); | ||||||
| 			int *q = va_arg(*p_va, int *); | 			int *q = va_arg(*p_va, int *); | ||||||
|  | 			if (PyUnicode_Check(arg)) { | ||||||
|  | 			    	*p = PyUnicode_AS_UNICODE(arg); | ||||||
|  | 				*q = PyUnicode_GET_SIZE(arg); | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
| 			char *buf; | 			char *buf; | ||||||
| 			int count = convertbuffer(arg, p, &buf); | 			int count = convertbuffer(arg, p, &buf); | ||||||
| 
 |  | ||||||
| 			if (count < 0) | 			if (count < 0) | ||||||
| 				return converterr(buf, arg, msgbuf, bufsize); | 				return converterr(buf, arg, msgbuf, bufsize); | ||||||
| 			*q = count/(sizeof(Py_UNICODE));  | 			*q = count/(sizeof(Py_UNICODE));  | ||||||
|  | 			} | ||||||
| 			format++; | 			format++; | ||||||
| 		} else { | 		} else { | ||||||
| 			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); | 			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); | ||||||
| 			 |  | ||||||
| 			if (PyUnicode_Check(arg)) | 			if (PyUnicode_Check(arg)) | ||||||
| 				*p = PyUnicode_AS_UNICODE(arg); | 				*p = PyUnicode_AS_UNICODE(arg); | ||||||
| 			else | 			else | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Marc-André Lemburg
						Marc-André Lemburg