diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 376a525..bd9e571 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -21,14 +21,38 @@ PyAPI_FUNC(void) _PyModule_Clear(PyObject *); PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*); PyAPI_FUNC(void*) PyModule_GetState(PyObject*); +/* Set if the module depends on width of Py_UNICODE */ +#define Py_MFLAGS_PYUNICODE (1L<<0) + +/* Set if the module was compiled with UCS4, clear for UCS2. The flag is + ignore if Py_MFLAGS_PYUNICODE is not set. */ +#define Py_MFLAGS_PYUNICODE_WIDE (1L<<1) + +#define PyModule_HasFlag(m,f) (((m)->m_base.m_flags & (f)) != 0) + typedef struct PyModuleDef_Base { PyObject_HEAD PyObject* (*m_init)(void); Py_ssize_t m_index; PyObject* m_copy; + long m_flags; } PyModuleDef_Base; -#define PyModuleDef_HEAD_INIT {PyObject_HEAD_INIT(NULL)} +#if defined(Py_UNICODE_AGNOSTIC) && !defined(Py_BUILD_CORE) +#define Py_MFLAGS_DEFAULT (0) +#elif Py_UNICODE_SIZE == 2 +#define Py_MFLAGS_DEFAULT (Py_MFLAGS_PYUNICODE) +#else +#define Py_MFLAGS_DEFAULT (Py_MFLAGS_PYUNICODE | Py_MFLAGS_PYUNICODE_WIDE) +#endif + +#define PyModuleDef_HEAD_INIT { \ + PyObject_HEAD_INIT(NULL) \ + NULL, \ + 0, \ + NULL, \ + Py_MFLAGS_DEFAULT, \ + } typedef struct PyModuleDef{ PyModuleDef_Base m_base; diff --git a/Include/pyunicode.h b/Include/pyunicode.h new file mode 100644 index 0000000..20c12f6 --- /dev/null +++ b/Include/pyunicode.h @@ -0,0 +1,165 @@ +#ifndef Py_UNICODE_H +#define Py_UNICODE_H + +/* This header is included by unicodeobject.h as long as + * Py_UNICODE_AGNOSTIC is not defined. It should not be included + * directly. */ + +#include "Python.h" + +/* FIXME: MvL's new implementation assumes that Py_UNICODE_SIZE is + properly set, but the default rules below doesn't set it. I'll + sort this out some other day -- fredrik@pythonware.com */ + +#ifndef Py_UNICODE_SIZE +#error Must define Py_UNICODE_SIZE +#endif + +/* Setting Py_UNICODE_WIDE enables UCS-4 storage. Otherwise, Unicode + strings are stored as UCS-2 (with limited support for UTF-16) */ + +#if Py_UNICODE_SIZE >= 4 +#define Py_UNICODE_WIDE +#endif + +/* Defaults for various platforms */ +#ifndef PY_UNICODE_TYPE + +/* Windows has a usable wchar_t type (unless we're using UCS-4) */ +# if defined(MS_WIN32) && Py_UNICODE_SIZE == 2 +# define HAVE_USABLE_WCHAR_T +# define PY_UNICODE_TYPE wchar_t +# endif + +# if defined(Py_UNICODE_WIDE) +# define PY_UNICODE_TYPE Py_UCS4 +# endif + +#endif + +typedef PY_UNICODE_TYPE Py_UNICODE; + +/* --- Constants ---------------------------------------------------------- */ + +/* This Unicode character will be used as replacement character during + decoding if the errors argument is set to "replace". Note: the + Unicode character U+FFFD is the official REPLACEMENT CHARACTER in + Unicode 3.0. */ + +#define Py_UNICODE_REPLACEMENT_CHARACTER ((Py_UNICODE) 0xFFFD) + +#ifdef __cplusplus +extern "C" { +#endif + +/* --- Internal Unicode Operations ---------------------------------------- */ + +/* If you want Python to use the compiler's wctype.h functions instead + of the ones supplied with Python, define WANT_WCTYPE_FUNCTIONS or + configure Python using --with-wctype-functions. This reduces the + interpreter's code size. */ + +#if defined(Py_UNICODE_WIDE) && defined(HAVE_USABLE_WCHAR_T) && defined(WANT_WCTYPE_FUNCTIONS) + +#include + +#define Py_UNICODE_ISSPACE(ch) iswspace(ch) + +#define Py_UNICODE_ISLOWER(ch) iswlower(ch) +#define Py_UNICODE_ISUPPER(ch) iswupper(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) towlower(ch) +#define Py_UNICODE_TOUPPER(ch) towupper(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) +#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) iswalpha(ch) + +#else + +/* Since splitting on whitespace is an important use case, and + whitespace in most situations is solely ASCII whitespace, we + optimize for the common case by using a quick look-up table + _Py_ascii_whitespace (see below) with an inlined check. + + */ +#define Py_UNICODE_ISSPACE(ch) \ + ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) + +#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) +#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) +#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) +#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) + +#endif + +#define Py_UNICODE_ISALNUM(ch) \ + (Py_UNICODE_ISALPHA(ch) || \ + Py_UNICODE_ISDECIMAL(ch) || \ + Py_UNICODE_ISDIGIT(ch) || \ + Py_UNICODE_ISNUMERIC(ch)) + +#define Py_UNICODE_COPY(target, source, length) \ + Py_MEMCPY((target), (source), (length)*sizeof(Py_UNICODE)) + +#define Py_UNICODE_FILL(target, value, length) \ + do {Py_ssize_t i_; Py_UNICODE *t_ = (target); Py_UNICODE v_ = (value);\ + for (i_ = 0; i_ < (length); i_++) t_[i_] = v_;\ + } while (0) + +/* Check if substring matches at given offset. the offset must be + valid, and the substring must not be empty */ + +#define Py_UNICODE_MATCH(string, offset, substring) \ + ((*((string)->str + (offset)) == *((substring)->str)) && \ + ((*((string)->str + (offset) + (substring)->length-1) == *((substring)->str + (substring)->length-1))) && \ + !memcmp((string)->str + (offset), (substring)->str, (substring)->length*sizeof(Py_UNICODE))) + +/* Fast access macros for PyUnicodeObject*/ +#define PyUnicode_GET_DATA_SIZE(op) \ + (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->length * sizeof(Py_UNICODE))) + +/* Get the maximum ordinal for a Unicode character. */ +PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void); + +/* === Py_UNICODE * string manipulation =================================== */ + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr( + const Py_UNICODE *s, + Py_UNICODE c + ); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( + const Py_UNICODE *s, + Py_UNICODE c + ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 0de0d66..755ae7e 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -63,41 +63,13 @@ Copyright (c) Corporation for National Research Initiatives. /* Python 3.x requires unicode */ #define Py_USING_UNICODE -/* FIXME: MvL's new implementation assumes that Py_UNICODE_SIZE is - properly set, but the default rules below doesn't set it. I'll - sort this out some other day -- fredrik@pythonware.com */ - -#ifndef Py_UNICODE_SIZE -#error Must define Py_UNICODE_SIZE -#endif - -/* Setting Py_UNICODE_WIDE enables UCS-4 storage. Otherwise, Unicode - strings are stored as UCS-2 (with limited support for UTF-16) */ - -#if Py_UNICODE_SIZE >= 4 -#define Py_UNICODE_WIDE -#endif - -/* Set these flags if the platform has "wchar.h", "wctype.h" and the - wchar_t type is a 16-bit unsigned type */ +/* Set if the platform has "wchar.h" and "wctype.h" */ /* #define HAVE_WCHAR_H */ + +/* Set if HAVE_WCHAR_H and sizeof(wchar_t) == sizeof(Py_UNICODE) and wchar_t + is unsigned */ /* #define HAVE_USABLE_WCHAR_T */ -/* Defaults for various platforms */ -#ifndef PY_UNICODE_TYPE - -/* Windows has a usable wchar_t type (unless we're using UCS-4) */ -# if defined(MS_WIN32) && Py_UNICODE_SIZE == 2 -# define HAVE_USABLE_WCHAR_T -# define PY_UNICODE_TYPE wchar_t -# endif - -# if defined(Py_UNICODE_WIDE) -# define PY_UNICODE_TYPE Py_UCS4 -# endif - -#endif - /* If the compiler provides a wchar_t type we try to support it through the interface functions PyUnicode_FromWideChar() and PyUnicode_AsWideChar(). */ @@ -126,275 +98,15 @@ typedef unsigned int Py_UCS4; typedef unsigned long Py_UCS4; #endif -/* Py_UNICODE is the native Unicode storage format (code unit) used by - Python and represents a single Unicode element in the Unicode - type. */ - -typedef PY_UNICODE_TYPE Py_UNICODE; - -/* --- UCS-2/UCS-4 Name Mangling ------------------------------------------ */ - -/* Unicode API names are mangled to assure that UCS-2 and UCS-4 builds - produce different external names and thus cause import errors in - case Python interpreters and extensions with mixed compiled in - Unicode width assumptions are combined. */ - -#ifndef Py_UNICODE_WIDE - -# define PyUnicode_AsASCIIString PyUnicodeUCS2_AsASCIIString -# define PyUnicode_AsCharmapString PyUnicodeUCS2_AsCharmapString -# define PyUnicode_AsDecodedObject PyUnicodeUCS2_AsDecodedObject -# define PyUnicode_AsDecodedUnicode PyUnicodeUCS2_AsDecodedUnicode -# define PyUnicode_AsEncodedObject PyUnicodeUCS2_AsEncodedObject -# define PyUnicode_AsEncodedString PyUnicodeUCS2_AsEncodedString -# define PyUnicode_AsEncodedUnicode PyUnicodeUCS2_AsEncodedUnicode -# define PyUnicode_AsLatin1String PyUnicodeUCS2_AsLatin1String -# define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS2_AsRawUnicodeEscapeString -# define PyUnicode_AsUTF32String PyUnicodeUCS2_AsUTF32String -# define PyUnicode_AsUTF16String PyUnicodeUCS2_AsUTF16String -# define PyUnicode_AsUTF8String PyUnicodeUCS2_AsUTF8String -# define PyUnicode_AsUnicode PyUnicodeUCS2_AsUnicode -# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS2_AsUnicodeEscapeString -# define PyUnicode_AsWideChar PyUnicodeUCS2_AsWideChar -# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist -# define PyUnicode_Compare PyUnicodeUCS2_Compare -# define PyUnicode_CompareWithASCII PyUnicodeUCS2_CompareASCII -# define PyUnicode_Concat PyUnicodeUCS2_Concat -# define PyUnicode_Append PyUnicodeUCS2_Append -# define PyUnicode_AppendAndDel PyUnicodeUCS2_AppendAndDel -# define PyUnicode_Contains PyUnicodeUCS2_Contains -# define PyUnicode_Count PyUnicodeUCS2_Count -# define PyUnicode_Decode PyUnicodeUCS2_Decode -# define PyUnicode_DecodeASCII PyUnicodeUCS2_DecodeASCII -# define PyUnicode_DecodeCharmap PyUnicodeUCS2_DecodeCharmap -# define PyUnicode_DecodeLatin1 PyUnicodeUCS2_DecodeLatin1 -# define PyUnicode_DecodeFSDefault PyUnicodeUCS2_DecodeFSDefault -# define PyUnicode_DecodeFSDefaultAndSize PyUnicodeUCS2_DecodeFSDefaultAndSize -# define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS2_DecodeRawUnicodeEscape -# define PyUnicode_DecodeUTF32 PyUnicodeUCS2_DecodeUTF32 -# define PyUnicode_DecodeUTF32Stateful PyUnicodeUCS2_DecodeUTF32Stateful -# define PyUnicode_DecodeUTF16 PyUnicodeUCS2_DecodeUTF16 -# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS2_DecodeUTF16Stateful -# define PyUnicode_DecodeUTF8 PyUnicodeUCS2_DecodeUTF8 -# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS2_DecodeUTF8Stateful -# define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS2_DecodeUnicodeEscape -# define PyUnicode_Encode PyUnicodeUCS2_Encode -# define PyUnicode_EncodeASCII PyUnicodeUCS2_EncodeASCII -# define PyUnicode_EncodeCharmap PyUnicodeUCS2_EncodeCharmap -# define PyUnicode_EncodeDecimal PyUnicodeUCS2_EncodeDecimal -# define PyUnicode_EncodeLatin1 PyUnicodeUCS2_EncodeLatin1 -# define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS2_EncodeRawUnicodeEscape -# define PyUnicode_EncodeUTF32 PyUnicodeUCS2_EncodeUTF32 -# define PyUnicode_EncodeUTF16 PyUnicodeUCS2_EncodeUTF16 -# define PyUnicode_EncodeUTF8 PyUnicodeUCS2_EncodeUTF8 -# define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS2_EncodeUnicodeEscape -# define PyUnicode_Find PyUnicodeUCS2_Find -# define PyUnicode_Format PyUnicodeUCS2_Format -# define PyUnicode_FromEncodedObject PyUnicodeUCS2_FromEncodedObject -# define PyUnicode_FromFormat PyUnicodeUCS2_FromFormat -# define PyUnicode_FromFormatV PyUnicodeUCS2_FromFormatV -# define PyUnicode_FromObject PyUnicodeUCS2_FromObject -# define PyUnicode_FromOrdinal PyUnicodeUCS2_FromOrdinal -# define PyUnicode_FromString PyUnicodeUCS2_FromString -# define PyUnicode_FromStringAndSize PyUnicodeUCS2_FromStringAndSize -# define PyUnicode_FromUnicode PyUnicodeUCS2_FromUnicode -# define PyUnicode_FromWideChar PyUnicodeUCS2_FromWideChar -# define PyUnicode_FSConverter PyUnicodeUCS2_FSConverter -# define PyUnicode_FSDecoder PyUnicodeUCS2_FSDecoder -# define PyUnicode_GetDefaultEncoding PyUnicodeUCS2_GetDefaultEncoding -# define PyUnicode_GetMax PyUnicodeUCS2_GetMax -# define PyUnicode_GetSize PyUnicodeUCS2_GetSize -# define PyUnicode_IsIdentifier PyUnicodeUCS2_IsIdentifier -# define PyUnicode_Join PyUnicodeUCS2_Join -# define PyUnicode_Partition PyUnicodeUCS2_Partition -# define PyUnicode_RPartition PyUnicodeUCS2_RPartition -# define PyUnicode_RSplit PyUnicodeUCS2_RSplit -# define PyUnicode_Replace PyUnicodeUCS2_Replace -# define PyUnicode_Resize PyUnicodeUCS2_Resize -# define PyUnicode_RichCompare PyUnicodeUCS2_RichCompare -# define PyUnicode_Split PyUnicodeUCS2_Split -# define PyUnicode_Splitlines PyUnicodeUCS2_Splitlines -# define PyUnicode_Tailmatch PyUnicodeUCS2_Tailmatch -# define PyUnicode_Translate PyUnicodeUCS2_Translate -# define PyUnicode_TranslateCharmap PyUnicodeUCS2_TranslateCharmap -# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS2_AsDefaultEncodedString -# define _PyUnicode_Fini _PyUnicodeUCS2_Fini -# define _PyUnicode_Init _PyUnicodeUCS2_Init -# define PyUnicode_strdup PyUnicodeUCS2_strdup - +#if !defined(Py_UNICODE_AGNOSTIC) || defined(Py_BUILD_CORE) +#include "pyunicode.h" #else - -# define PyUnicode_AsASCIIString PyUnicodeUCS4_AsASCIIString -# define PyUnicode_AsCharmapString PyUnicodeUCS4_AsCharmapString -# define PyUnicode_AsDecodedObject PyUnicodeUCS4_AsDecodedObject -# define PyUnicode_AsDecodedUnicode PyUnicodeUCS4_AsDecodedUnicode -# define PyUnicode_AsEncodedObject PyUnicodeUCS4_AsEncodedObject -# define PyUnicode_AsEncodedString PyUnicodeUCS4_AsEncodedString -# define PyUnicode_AsEncodedUnicode PyUnicodeUCS4_AsEncodedUnicode -# define PyUnicode_AsLatin1String PyUnicodeUCS4_AsLatin1String -# define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS4_AsRawUnicodeEscapeString -# define PyUnicode_AsUTF32String PyUnicodeUCS4_AsUTF32String -# define PyUnicode_AsUTF16String PyUnicodeUCS4_AsUTF16String -# define PyUnicode_AsUTF8String PyUnicodeUCS4_AsUTF8String -# define PyUnicode_AsUnicode PyUnicodeUCS4_AsUnicode -# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS4_AsUnicodeEscapeString -# define PyUnicode_AsWideChar PyUnicodeUCS4_AsWideChar -# define PyUnicode_ClearFreeList PyUnicodeUCS4_ClearFreelist -# define PyUnicode_Compare PyUnicodeUCS4_Compare -# define PyUnicode_CompareWithASCII PyUnicodeUCS4_CompareWithASCII -# define PyUnicode_Concat PyUnicodeUCS4_Concat -# define PyUnicode_Append PyUnicodeUCS4_Append -# define PyUnicode_AppendAndDel PyUnicodeUCS4_AppendAndDel -# define PyUnicode_Contains PyUnicodeUCS4_Contains -# define PyUnicode_Count PyUnicodeUCS4_Count -# define PyUnicode_Decode PyUnicodeUCS4_Decode -# define PyUnicode_DecodeASCII PyUnicodeUCS4_DecodeASCII -# define PyUnicode_DecodeCharmap PyUnicodeUCS4_DecodeCharmap -# define PyUnicode_DecodeLatin1 PyUnicodeUCS4_DecodeLatin1 -# define PyUnicode_DecodeFSDefault PyUnicodeUCS4_DecodeFSDefault -# define PyUnicode_DecodeFSDefaultAndSize PyUnicodeUCS4_DecodeFSDefaultAndSize -# define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS4_DecodeRawUnicodeEscape -# define PyUnicode_DecodeUTF32 PyUnicodeUCS4_DecodeUTF32 -# define PyUnicode_DecodeUTF32Stateful PyUnicodeUCS4_DecodeUTF32Stateful -# define PyUnicode_DecodeUTF16 PyUnicodeUCS4_DecodeUTF16 -# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS4_DecodeUTF16Stateful -# define PyUnicode_DecodeUTF8 PyUnicodeUCS4_DecodeUTF8 -# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS4_DecodeUTF8Stateful -# define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS4_DecodeUnicodeEscape -# define PyUnicode_Encode PyUnicodeUCS4_Encode -# define PyUnicode_EncodeASCII PyUnicodeUCS4_EncodeASCII -# define PyUnicode_EncodeCharmap PyUnicodeUCS4_EncodeCharmap -# define PyUnicode_EncodeDecimal PyUnicodeUCS4_EncodeDecimal -# define PyUnicode_EncodeLatin1 PyUnicodeUCS4_EncodeLatin1 -# define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS4_EncodeRawUnicodeEscape -# define PyUnicode_EncodeUTF32 PyUnicodeUCS4_EncodeUTF32 -# define PyUnicode_EncodeUTF16 PyUnicodeUCS4_EncodeUTF16 -# define PyUnicode_EncodeUTF8 PyUnicodeUCS4_EncodeUTF8 -# define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS4_EncodeUnicodeEscape -# define PyUnicode_Find PyUnicodeUCS4_Find -# define PyUnicode_Format PyUnicodeUCS4_Format -# define PyUnicode_FromEncodedObject PyUnicodeUCS4_FromEncodedObject -# define PyUnicode_FromFormat PyUnicodeUCS4_FromFormat -# define PyUnicode_FromFormatV PyUnicodeUCS4_FromFormatV -# define PyUnicode_FromObject PyUnicodeUCS4_FromObject -# define PyUnicode_FromOrdinal PyUnicodeUCS4_FromOrdinal -# define PyUnicode_FromString PyUnicodeUCS4_FromString -# define PyUnicode_FromStringAndSize PyUnicodeUCS4_FromStringAndSize -# define PyUnicode_FromUnicode PyUnicodeUCS4_FromUnicode -# define PyUnicode_FromWideChar PyUnicodeUCS4_FromWideChar -# define PyUnicode_FSConverter PyUnicodeUCS4_FSConverter -# define PyUnicode_FSDecoder PyUnicodeUCS4_FSDecoder -# define PyUnicode_GetDefaultEncoding PyUnicodeUCS4_GetDefaultEncoding -# define PyUnicode_GetMax PyUnicodeUCS4_GetMax -# define PyUnicode_GetSize PyUnicodeUCS4_GetSize -# define PyUnicode_IsIdentifier PyUnicodeUCS4_IsIdentifier -# define PyUnicode_Join PyUnicodeUCS4_Join -# define PyUnicode_Partition PyUnicodeUCS4_Partition -# define PyUnicode_RPartition PyUnicodeUCS4_RPartition -# define PyUnicode_RSplit PyUnicodeUCS4_RSplit -# define PyUnicode_Replace PyUnicodeUCS4_Replace -# define PyUnicode_Resize PyUnicodeUCS4_Resize -# define PyUnicode_RichCompare PyUnicodeUCS4_RichCompare -# define PyUnicode_Split PyUnicodeUCS4_Split -# define PyUnicode_Splitlines PyUnicodeUCS4_Splitlines -# define PyUnicode_Tailmatch PyUnicodeUCS4_Tailmatch -# define PyUnicode_Translate PyUnicodeUCS4_Translate -# define PyUnicode_TranslateCharmap PyUnicodeUCS4_TranslateCharmap -# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS4_AsDefaultEncodedString -# define _PyUnicode_Fini _PyUnicodeUCS4_Fini -# define _PyUnicode_Init _PyUnicodeUCS4_Init -# define PyUnicode_strdup PyUnicodeUCS4_strdup - +#undef HAVE_USABLE_WCHAR_T +#undef Py_UNICODE_SIZE +typedef struct Py_UNICODE_STRUCT Py_UNICODE_STRUCT; +#define Py_UNICODE Py_UNICODE_STRUCT #endif -/* --- Internal Unicode Operations ---------------------------------------- */ - -/* If you want Python to use the compiler's wctype.h functions instead - of the ones supplied with Python, define WANT_WCTYPE_FUNCTIONS or - configure Python using --with-wctype-functions. This reduces the - interpreter's code size. */ - -#if defined(Py_UNICODE_WIDE) && defined(HAVE_USABLE_WCHAR_T) && defined(WANT_WCTYPE_FUNCTIONS) - -#include - -#define Py_UNICODE_ISSPACE(ch) iswspace(ch) - -#define Py_UNICODE_ISLOWER(ch) iswlower(ch) -#define Py_UNICODE_ISUPPER(ch) iswupper(ch) -#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) -#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) - -#define Py_UNICODE_TOLOWER(ch) towlower(ch) -#define Py_UNICODE_TOUPPER(ch) towupper(ch) -#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) - -#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) -#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) -#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) -#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) - -#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) -#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) -#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) - -#define Py_UNICODE_ISALPHA(ch) iswalpha(ch) - -#else - -/* Since splitting on whitespace is an important use case, and - whitespace in most situations is solely ASCII whitespace, we - optimize for the common case by using a quick look-up table - _Py_ascii_whitespace (see below) with an inlined check. - - */ -#define Py_UNICODE_ISSPACE(ch) \ - ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) - -#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) -#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) -#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) -#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) - -#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) -#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) -#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) - -#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) -#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) -#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) -#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) - -#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) -#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) -#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) - -#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) - -#endif - -#define Py_UNICODE_ISALNUM(ch) \ - (Py_UNICODE_ISALPHA(ch) || \ - Py_UNICODE_ISDECIMAL(ch) || \ - Py_UNICODE_ISDIGIT(ch) || \ - Py_UNICODE_ISNUMERIC(ch)) - -#define Py_UNICODE_COPY(target, source, length) \ - Py_MEMCPY((target), (source), (length)*sizeof(Py_UNICODE)) - -#define Py_UNICODE_FILL(target, value, length) \ - do {Py_ssize_t i_; Py_UNICODE *t_ = (target); Py_UNICODE v_ = (value);\ - for (i_ = 0; i_ < (length); i_++) t_[i_] = v_;\ - } while (0) - -/* Check if substring matches at given offset. the offset must be - valid, and the substring must not be empty */ - -#define Py_UNICODE_MATCH(string, offset, substring) \ - ((*((string)->str + (offset)) == *((substring)->str)) && \ - ((*((string)->str + (offset) + (substring)->length-1) == *((substring)->str + (substring)->length-1))) && \ - !memcmp((string)->str + (offset), (substring)->str, (substring)->length*sizeof(Py_UNICODE))) - #ifdef __cplusplus extern "C" { #endif @@ -428,22 +140,11 @@ PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; /* Fast access macros */ #define PyUnicode_GET_SIZE(op) \ (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->length)) -#define PyUnicode_GET_DATA_SIZE(op) \ - (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->length * sizeof(Py_UNICODE))) #define PyUnicode_AS_UNICODE(op) \ (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->str)) #define PyUnicode_AS_DATA(op) \ (assert(PyUnicode_Check(op)),((const char *)((PyUnicodeObject *)(op))->str)) -/* --- Constants ---------------------------------------------------------- */ - -/* This Unicode character will be used as replacement character during - decoding if the errors argument is set to "replace". Note: the - Unicode character U+FFFD is the official REPLACEMENT CHARACTER in - Unicode 3.0. */ - -#define Py_UNICODE_REPLACEMENT_CHARACTER ((Py_UNICODE) 0xFFFD) - /* === Public API ========================================================= */ /* --- Plain Py_UNICODE --------------------------------------------------- */ @@ -488,9 +189,6 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( PyObject *unicode /* Unicode object */ ); -/* Get the maximum ordinal for a Unicode character. */ -PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void); - /* Resize an already allocated Unicode object to the new size length. *unicode is modified to point to the new (resized) object and 0 @@ -1566,6 +1264,8 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha( Py_UCS4 ch /* Unicode character */ ); +/* === Py_UNICODE * string manipulation =================================== */ + PyAPI_FUNC(size_t) Py_UNICODE_strlen( const Py_UNICODE *u ); @@ -1593,16 +1293,6 @@ PyAPI_FUNC(int) Py_UNICODE_strncmp( size_t n ); -PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr( - const Py_UNICODE *s, - Py_UNICODE c - ); - -PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( - const Py_UNICODE *s, - Py_UNICODE c - ); - /* Create a copy of a unicode string ending with a nul character. Return NULL and raise a MemoryError exception on memory allocation failure, otherwise return a new allocated buffer (use PyMem_Free() to free the buffer). */ diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 32f8fae..84ceb13 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -139,6 +139,19 @@ class Test6012(unittest.TestCase): def test(self): self.assertEqual(_testcapi.argparsing("Hello", "World"), 1) +class TestPyUnicode(unittest.TestCase): + def test_mismatch(self): + def import_mismatched_unicode(): + import _testunicodemismatched + self.assertRaises(ImportError, import_mismatched_unicode) + + def test_agnostic(self): + import _testunicodeagnostic + s = _testunicodeagnostic.exercise1("the start:") + self.assertEqual(s, "the start:the end") + self.assertTrue(_testunicodeagnostic.exercise2("check")) + self.assertFalse(_testunicodeagnostic.exercise2("not check")) + def test_main(): support.run_unittest(CAPITest) @@ -175,7 +188,7 @@ def test_main(): t.start() t.join() - support.run_unittest(TestPendingCalls, Test6012) + support.run_unittest(TestPendingCalls, Test6012, TestPyUnicode) if __name__ == "__main__": diff --git a/Modules/_testunicodeagnostic.c b/Modules/_testunicodeagnostic.c new file mode 100644 index 0000000..2cc2940 --- /dev/null +++ b/Modules/_testunicodeagnostic.c @@ -0,0 +1,89 @@ +/* + * C Extension module to test Unicode-agnostic mode + * + * The 'test_*' functions exported by this module are run as part of the + * standard Python regression test, via Lib/test/test_capi.py. + */ + +#define Py_UNICODE_AGNOSTIC +#define PY_SSIZE_T_CLEAN + +/* Setup compilation settings using a Unicode setting opposite of the + * interpreter. The module is compiled in Unicode-agnostic mode, so it should + * load anyway. */ +#include "pyconfig.h" +#undef HAVE_USABLE_WCHAR_T +#undef PY_UNICODE_TYPE +#if Py_UNICODE_SIZE == 2 +#undef Py_UNICODE_SIZE +#define Py_UNICODE_SIZE 4 +#else +#undef Py_UNICODE_SIZE +#define Py_UNICODE_SIZE 2 +#endif + +#include "Python.h" + +/* Exercise a PyUnicode_ functions */ +static PyObject *exercise1(PyObject *self, PyObject *arg) +{ + PyObject *end, *result; + + end = PyUnicode_FromString("the end"); + if (end == NULL) + return NULL; + result = PyUnicode_Concat(arg, end); + Py_DECREF(end); + return result; +} + +/* Exercise a Py_UNICODE_ functions */ +static PyObject *exercise2(PyObject *self, PyObject *arg) +{ + int cmp; + PyObject *check_ob; + + if (!PyUnicode_CheckExact(arg)) + Py_RETURN_FALSE; + + check_ob = PyUnicode_FromString("check"); + if (check_ob == NULL) + return NULL; + + cmp = Py_UNICODE_strcmp(PyUnicode_AsUnicode(check_ob), + PyUnicode_AsUnicode(arg)); + Py_DECREF(check_ob); + if (cmp == 0) + Py_RETURN_TRUE; + Py_RETURN_FALSE; +} + +static PyMethodDef TestMethods[] = { + {"exercise1", exercise1, METH_O}, + {"exercise2", exercise2, METH_O}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + +static struct PyModuleDef _testunicodeagnostic = { + PyModuleDef_HEAD_INIT, + "_testunicodeagnostic", + NULL, + -1, + TestMethods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__testunicodeagnostic(void) +{ + PyObject *m; + + m = PyModule_Create(&_testunicodeagnostic); + if (m == NULL) + return NULL; + + return m; +} diff --git a/Modules/_testunicodemismatched.c b/Modules/_testunicodemismatched.c new file mode 100644 index 0000000..6a0f878 --- /dev/null +++ b/Modules/_testunicodemismatched.c @@ -0,0 +1,49 @@ +/* + * C Extension module to Unicode-agnostic and Unicode-dependent modes + * + * The 'test_*' functions exported by this module are run as part of the + * standard Python regression test, via Lib/test/test_capi.py. + */ + +#define PY_SSIZE_T_CLEAN + +/* Setup compilation settings using a Unicode setting opposite of the + * interpreter. The module is compiled in Unicode-dependent mode, so the + * interpreter should throw and ImportError when trying to load it. */ +#include "pyconfig.h" +#undef HAVE_USABLE_WCHAR_T +#undef PY_UNICODE_TYPE +#if Py_UNICODE_SIZE == 2 +#undef Py_UNICODE_SIZE +#define Py_UNICODE_SIZE 4 +#else +#undef Py_UNICODE_SIZE +#define Py_UNICODE_SIZE 2 +#define PY_UNICODE_TYPE unsigned short +#endif + +#include "Python.h" + +static struct PyModuleDef _testunicodemismatched = { + PyModuleDef_HEAD_INIT, + "_testunicodemismatched", + NULL, + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__testunicodemismatched(void) +{ + PyObject *m; + + m = PyModule_Create(&_testunicodemismatched); + if (m == NULL) + return NULL; + + return m; +} diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 3a95261..0a45fa1 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -67,6 +67,14 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version) Py_FatalError("Interpreter not initialized (version mismatch?)"); if (PyType_Ready(&moduledef_type) < 0) return NULL; + if (PyModule_HasFlag(module, Py_MFLAGS_PYUNICODE) + && (!!PyModule_HasFlag(module, Py_MFLAGS_PYUNICODE_WIDE) + != (Py_UNICODE_SIZE == 4))) { + PyErr_SetString(PyExc_ImportError, + "module's Unicode representation does not " + "match the interpreter's"); + return NULL; + } if (module->m_base.m_index == 0) { max_module_number++; Py_REFCNT(module) = 1; diff --git a/PCbuild/_testunicodeagnostic.vcproj b/PCbuild/_testunicodeagnostic.vcproj new file mode 100644 index 0000000..2969869 --- /dev/null +++ b/PCbuild/_testunicodeagnostic.vcproj @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PCbuild/_testunicodemismatched.vcproj b/PCbuild/_testunicodemismatched.vcproj new file mode 100644 index 0000000..cd0f790 --- /dev/null +++ b/PCbuild/_testunicodemismatched.vcproj @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 1f6c6fb..a66168f 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -81,6 +81,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcpr {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testunicodemismatched", "_testunicodemismatched.vcproj", "{ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}" + ProjectSection(ProjectDependencies) = postProject + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testunicodeagnostic", "_testunicodeagnostic.vcproj", "{BC8C95B9-DDDC-4605-979F-B60C98EA4348}" + ProjectSection(ProjectDependencies) = postProject + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" ProjectSection(ProjectDependencies) = postProject {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} @@ -378,6 +388,38 @@ Global {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.Debug|Win32.ActiveCfg = Debug|Win32 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.Debug|Win32.Build.0 = Debug|Win32 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.Debug|x64.ActiveCfg = Debug|x64 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.Debug|x64.Build.0 = Debug|x64 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.Release|Win32.ActiveCfg = Release|Win32 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.Release|Win32.Build.0 = Release|Win32 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.Release|x64.ActiveCfg = Release|x64 + {BC8C95B9-DDDC-4605-979F-B60C98EA4348}.Release|x64.Build.0 = Release|x64 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.Debug|Win32.ActiveCfg = Debug|Win32 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.Debug|Win32.Build.0 = Debug|Win32 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.Debug|x64.ActiveCfg = Debug|x64 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.Debug|x64.Build.0 = Debug|x64 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.Release|Win32.ActiveCfg = Release|Win32 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.Release|Win32.Build.0 = Release|Win32 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.Release|x64.ActiveCfg = Release|x64 + {ECBB7F46-AEB0-43EF-93CB-6B55C35A3B85}.Release|x64.Build.0 = Release|x64 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/setup.py b/setup.py index 8e51960..d14cdef 100644 --- a/setup.py +++ b/setup.py @@ -317,6 +317,12 @@ class PyBuildExt(build_ext): # cached. Clear that cache before trying to import. sys.path_importer_cache.clear() + if ext.name.startswith('_testunicode'): + # Importing will be tested by the automated tests. + # _testunicodemismatched *should* fail to import, and we + # don't want to rename it here. + return + try: imp.load_dynamic(ext.name, ext_filename) except ImportError as why: @@ -480,9 +486,13 @@ class PyBuildExt(build_ext): exts.append( Extension("atexit", ["atexitmodule.c"]) ) # _json speedups exts.append( Extension("_json", ["_json.c"]) ) - # Python C API test module + # Python C API test modules exts.append( Extension('_testcapi', ['_testcapimodule.c'], depends=['testcapi_long.h']) ) + exts.append( Extension('_testunicodemismatched', + ['_testunicodemismatched.c'])) + exts.append( Extension('_testunicodeagnostic', + ['_testunicodeagnostic.c'])) # profiler (_lsprof is for cProfile.py) exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) ) # static Unicode character database