diff options
-rw-r--r-- | Doc/whatsnew/3.13.rst | 7 | ||||
-rw-r--r-- | Include/Python.h | 1 | ||||
-rw-r--r-- | Include/pyport.h | 38 | ||||
-rw-r--r-- | Misc/NEWS.d/next/C API/2023-09-02-22-35-55.gh-issue-108765.4TOdBT.rst | 5 | ||||
-rw-r--r-- | Modules/_localemodule.c | 34 | ||||
-rw-r--r-- | Modules/_sre/sre.c | 38 | ||||
-rw-r--r-- | Modules/_struct.c | 1 | ||||
-rw-r--r-- | Modules/_tkinter.c | 13 | ||||
-rw-r--r-- | Modules/_zoneinfo.c | 7 | ||||
-rw-r--r-- | Modules/pyexpat.c | 1 | ||||
-rw-r--r-- | Modules/timemodule.c | 7 | ||||
-rw-r--r-- | Objects/abstract.c | 3 | ||||
-rw-r--r-- | Objects/floatobject.c | 3 | ||||
-rw-r--r-- | Objects/longobject.c | 6 | ||||
-rw-r--r-- | Objects/typeobject.c | 2 | ||||
-rw-r--r-- | Python/bltinmodule.c | 1 | ||||
-rw-r--r-- | Python/ceval.c | 4 | ||||
-rw-r--r-- | Python/codecs.c | 1 | ||||
-rw-r--r-- | Python/dynload_win.c | 9 | ||||
-rw-r--r-- | Python/errors.c | 1 | ||||
-rw-r--r-- | Python/getargs.c | 4 | ||||
-rw-r--r-- | Python/mystrtoul.c | 14 |
22 files changed, 86 insertions, 114 deletions
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 1c91a1d..5d8ecbb 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -942,6 +942,13 @@ Porting to Python 3.13 and ``setitimer()`` functions. (Contributed by Victor Stinner in :gh:`108765`.) +* ``Python.h`` no longer includes the ``<ctype.h>`` standard header file. If + needed, it should now be included explicitly. For example, it provides + ``isalpha()`` and ``tolower()`` functions which are locale dependent. Python + provides locale independent functions, like :c:func:`!Py_ISALPHA` and + :c:func:`!Py_TOLOWER`. + (Contributed by Victor Stinner in :gh:`108765`.) + Deprecated ---------- diff --git a/Include/Python.h b/Include/Python.h index 4cc72bb..8b28200 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -17,7 +17,6 @@ // Include standard header files #include <assert.h> // assert() -#include <ctype.h> // tolower() #include <inttypes.h> // uintptr_t #include <limits.h> // INT_MAX #include <math.h> // HUGE_VAL diff --git a/Include/pyport.h b/Include/pyport.h index c4168d1..4d9b9c0 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -392,44 +392,6 @@ extern "C" { # define Py_NO_INLINE #endif -/* On 4.4BSD-descendants, ctype functions serves the whole range of - * wchar_t character set rather than single byte code points only. - * This characteristic can break some operations of string object - * including str.upper() and str.split() on UTF-8 locales. This - * workaround was provided by Tim Robbins of FreeBSD project. - */ - -#if defined(__APPLE__) -# define _PY_PORT_CTYPE_UTF8_ISSUE -#endif - -#ifdef _PY_PORT_CTYPE_UTF8_ISSUE -#ifndef __cplusplus - /* The workaround below is unsafe in C++ because - * the <locale> defines these symbols as real functions, - * with a slightly different signature. - * See issue #10910 - */ -#include <ctype.h> -#include <wctype.h> -#undef isalnum -#define isalnum(c) iswalnum(btowc(c)) -#undef isalpha -#define isalpha(c) iswalpha(btowc(c)) -#undef islower -#define islower(c) iswlower(btowc(c)) -#undef isspace -#define isspace(c) iswspace(btowc(c)) -#undef isupper -#define isupper(c) iswupper(btowc(c)) -#undef tolower -#define tolower(c) towlower(btowc(c)) -#undef toupper -#define toupper(c) towupper(btowc(c)) -#endif -#endif - - /* Declarations for symbol visibility. PyAPI_FUNC(type): Declares a public Python API function and return type diff --git a/Misc/NEWS.d/next/C API/2023-09-02-22-35-55.gh-issue-108765.4TOdBT.rst b/Misc/NEWS.d/next/C API/2023-09-02-22-35-55.gh-issue-108765.4TOdBT.rst new file mode 100644 index 0000000..c13b6d9 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-09-02-22-35-55.gh-issue-108765.4TOdBT.rst @@ -0,0 +1,5 @@ +``Python.h`` no longer includes the ``<ctype.h>`` standard header file. If +needed, it should now be included explicitly. For example, it provides +``isalpha()`` and ``tolower()`` functions which are locale dependent. Python +provides locale independent functions, like :c:func:`!Py_ISALPHA` and +:c:func:`!Py_TOLOWER`. Patch by Victor Stinner. diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 1847a48..fe8e4c5 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -10,35 +10,25 @@ This software comes with no warranty. Use at your own risk. ******************************************************************/ #include "Python.h" -#include "pycore_fileutils.h" -#include "pycore_pymem.h" // _PyMem_Strdup - -#include <stdio.h> -#include <locale.h> -#include <string.h> -#include <ctype.h> +#include "pycore_fileutils.h" // _Py_GetLocaleconvNumeric() +#include "pycore_pymem.h" // _PyMem_Strdup() +#include <locale.h> // setlocale() +#include <string.h> // strlen() #ifdef HAVE_ERRNO_H -#include <errno.h> +# include <errno.h> // errno #endif - #ifdef HAVE_LANGINFO_H -#include <langinfo.h> +# include <langinfo.h> // nl_langinfo() #endif - #ifdef HAVE_LIBINTL_H -#include <libintl.h> -#endif - -#ifdef HAVE_WCHAR_H -#include <wchar.h> +# include <libintl.h> #endif - -#if defined(MS_WINDOWS) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> +#ifdef MS_WINDOWS +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include <windows.h> #endif PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index 3872c36..07da5da 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -43,12 +43,40 @@ static const char copyright[] = #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "sre.h" // SRE_CODE -#include "sre.h" +#include <ctype.h> // tolower(), toupper(), isalnum() #define SRE_CODE_BITS (8 * sizeof(SRE_CODE)) -#include <ctype.h> +// On macOS, use the wide character ctype API using btowc() +#if defined(__APPLE__) +# define USE_CTYPE_WINT_T +#endif + +static int sre_isalnum(unsigned int ch) { +#ifdef USE_CTYPE_WINT_T + return (unsigned int)iswalnum(btowc((int)ch)); +#else + return (unsigned int)isalnum((int)ch); +#endif +} + +static unsigned int sre_tolower(unsigned int ch) { +#ifdef USE_CTYPE_WINT_T + return (unsigned int)towlower(btowc((int)ch)); +#else + return (unsigned int)tolower((int)ch); +#endif +} + +static unsigned int sre_toupper(unsigned int ch) { +#ifdef USE_CTYPE_WINT_T + return (unsigned int)towupper(btowc((int)ch)); +#else + return (unsigned int)toupper((int)ch); +#endif +} /* Defining this one controls tracing: * 0 -- disabled @@ -114,17 +142,17 @@ static unsigned int sre_lower_ascii(unsigned int ch) /* locale-specific character predicates */ /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids * warnings when c's type supports only numbers < N+1 */ -#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0) +#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? sre_isalnum((ch)) : 0) #define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_') static unsigned int sre_lower_locale(unsigned int ch) { - return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch); + return ((ch) < 256 ? (unsigned int)sre_tolower((ch)) : ch); } static unsigned int sre_upper_locale(unsigned int ch) { - return ((ch) < 256 ? (unsigned int)toupper((ch)) : ch); + return ((ch) < 256 ? (unsigned int)sre_toupper((ch)) : ch); } /* unicode-specific character predicates */ diff --git a/Modules/_struct.c b/Modules/_struct.c index be4c23a..1f8f9c4 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -12,7 +12,6 @@ #include "pycore_long.h" // _PyLong_AsByteArray() #include "pycore_moduleobject.h" // _PyModule_GetState() -#include <ctype.h> #include <stddef.h> // offsetof() /*[clinic input] diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 663b411..f9a1864 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -26,15 +26,14 @@ Copyright (C) 1994 Steen Lumholt. #endif #include "Python.h" -#include <ctype.h> #ifdef MS_WINDOWS # include "pycore_fileutils.h" // _Py_stat() #endif -#include "pycore_long.h" +#include "pycore_long.h" // _PyLong_IsNegative() #ifdef MS_WINDOWS -#include <windows.h> +# include <windows.h> #endif #define CHECK_SIZE(size, elemsize) \ @@ -46,11 +45,11 @@ Copyright (C) 1994 Steen Lumholt. #define TCL_THREADS #ifdef TK_FRAMEWORK -#include <Tcl/tcl.h> -#include <Tk/tk.h> +# include <Tcl/tcl.h> +# include <Tk/tk.h> #else -#include <tcl.h> -#include <tk.h> +# include <tcl.h> +# include <tk.h> #endif #include "tkinter.h" diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 3f7b285..eb4e522 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -6,11 +6,10 @@ #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() -#include <ctype.h> -#include <stddef.h> -#include <stdint.h> +#include "datetime.h" // PyDateTime_TZInfo -#include "datetime.h" +#include <stddef.h> // offsetof() +#include <stdint.h> #include "clinic/_zoneinfo.c.h" /*[clinic input] diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 52dd06c..bd24523 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -7,7 +7,6 @@ #include "pycore_pyhash.h" // _Py_HashSecret #include "pycore_traceback.h" // _PyTraceback_Add() -#include <ctype.h> #include <stddef.h> // offsetof() #include "expat.h" #include "pyexpat.h" diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 4e55da7..a2b6652 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -6,22 +6,21 @@ #include "pycore_namespace.h" // _PyNamespace_New() #include "pycore_runtime.h" // _Py_ID() -#include <ctype.h> #include <time.h> // clock() #ifdef HAVE_SYS_TIMES_H -# include <sys/times.h> +# include <sys/times.h> // times() #endif #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif #if defined(HAVE_SYS_RESOURCE_H) -# include <sys/resource.h> +# include <sys/resource.h> // getrusage(RUSAGE_SELF) #endif #ifdef QUICKWIN # include <io.h> #endif #if defined(HAVE_PTHREAD_H) -# include <pthread.h> +# include <pthread.h> // pthread_getcpuclockid() #endif #if defined(_AIX) # include <sys/thread.h> diff --git a/Objects/abstract.c b/Objects/abstract.c index c113364..6713926 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -9,9 +9,8 @@ #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_unionobject.h" // _PyUnion_Check() -#include <ctype.h> -#include <stddef.h> // offsetof() +#include <stddef.h> // offsetof() /* Shorthands to return certain errors */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 1c5078b..776c709 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -16,8 +16,7 @@ #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() -#include <ctype.h> -#include <float.h> +#include <float.h> // DBL_MAX #include <stdlib.h> // strtol() /*[clinic input] diff --git a/Objects/longobject.c b/Objects/longobject.c index d20ef41..e73de74 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -10,10 +10,8 @@ #include "pycore_runtime.h" // _PY_NSMALLPOSINTS #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() -#include <ctype.h> -#include <float.h> -#include <stddef.h> -#include <stdlib.h> // abs() +#include <float.h> // DBL_MANT_DIG +#include <stddef.h> // offsetof #include "clinic/longobject.c.h" /*[clinic input] diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 67e059c..84c5050 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -19,8 +19,6 @@ #include "pycore_weakref.h" // _PyWeakref_GET_REF() #include "opcode.h" // MAKE_CELL - -#include <ctype.h> #include <stddef.h> // ptrdiff_t /*[clinic input] diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 971067e..8e234e0 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1,7 +1,6 @@ /* Built-in functions */ #include "Python.h" -#include <ctype.h> #include "pycore_ast.h" // _PyAST_Validate() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_Vector() diff --git a/Python/ceval.c b/Python/ceval.c index a22852e..6f90d8e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -35,9 +35,7 @@ #include "pydtrace.h" #include "setobject.h" - -#include <ctype.h> -#include <stdbool.h> +#include <stdbool.h> // bool #ifdef Py_DEBUG /* For debugging the interpreter: */ diff --git a/Python/codecs.c b/Python/codecs.c index 87ae896..b79bf55 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -14,7 +14,6 @@ Copyright (c) Corporation for National Research Initiatives. #include "pycore_pyerrors.h" // _PyErr_FormatNote() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI -#include <ctype.h> const char *Py_hexdigits = "0123456789abcdef"; diff --git a/Python/dynload_win.c b/Python/dynload_win.c index acab05e..f69995b 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -5,13 +5,8 @@ #include "pycore_fileutils.h" // _Py_add_relfile() #include "pycore_pystate.h" // _PyInterpreterState_GET() -#ifdef HAVE_DIRECT_H -#include <direct.h> -#endif -#include <ctype.h> - -#include "importdl.h" -#include "patchlevel.h" +#include "importdl.h" // dl_funcptr +#include "patchlevel.h" // PY_MAJOR_VERSION #include <windows.h> #ifdef _DEBUG diff --git a/Python/errors.c b/Python/errors.c index fb5b3ff..f670b78 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -10,7 +10,6 @@ #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_traceback.h" // _PyTraceBack_FromFrame() -#include <ctype.h> #ifdef MS_WINDOWS # include <windows.h> # include <winbase.h> diff --git a/Python/getargs.c b/Python/getargs.c index fdc1444..cbfe561 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -7,10 +7,6 @@ #include "pycore_pylifecycle.h" // _PyArg_Fini #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include <ctype.h> -#include <float.h> - - #ifdef __cplusplus extern "C" { #endif diff --git a/Python/mystrtoul.c b/Python/mystrtoul.c index e6fe154..fcd3e27 100644 --- a/Python/mystrtoul.c +++ b/Python/mystrtoul.c @@ -1,16 +1,22 @@ +// strtol() and strtoul(), renamed to avoid conflicts. +// +// API: +// +// - PyOS_strtol(): convert string to C long integer. +// - PyOS_strtoul(): convert string to C unsigned long integer. + #include "Python.h" #include "pycore_long.h" // _PyLong_DigitValue #if defined(__sgi) && !defined(_SGI_MP_SOURCE) -#define _SGI_MP_SOURCE +# define _SGI_MP_SOURCE #endif /* strtol and strtoul, renamed to avoid conflicts */ -#include <ctype.h> #ifdef HAVE_ERRNO_H -#include <errno.h> +# include <errno.h> // errno #endif /* Static overflow check values for bases 2 through 36. @@ -75,7 +81,7 @@ static const int digitlimit[] = { 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */ 13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */ #else -#error "Need table for SIZEOF_LONG" +# error "Need table for SIZEOF_LONG" #endif /* |