Skip to content

Commit 790465f

Browse files
committed
Change command line processing API to use wchar_t.
Fixes python#2128.
1 parent b9279bc commit 790465f

File tree

21 files changed

+644
-416
lines changed

21 files changed

+644
-416
lines changed

Doc/c-api/init.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ Initialization, Finalization, and Threads
161161
haven't been explicitly destroyed at that point.
162162

163163

164-
.. cfunction:: void Py_SetProgramName(char *name)
164+
.. cfunction:: void Py_SetProgramName(wchar_t *name)
165165

166166
.. index::
167167
single: Py_Initialize()
@@ -170,11 +170,12 @@ Initialization, Finalization, and Threads
170170

171171
This function should be called before :cfunc:`Py_Initialize` is called for
172172
the first time, if it is called at all. It tells the interpreter the value
173-
of the ``argv[0]`` argument to the :cfunc:`main` function of the program.
173+
of the ``argv[0]`` argument to the :cfunc:`main` function of the program
174+
(converted to wide characters).
174175
This is used by :cfunc:`Py_GetPath` and some other functions below to find
175176
the Python run-time libraries relative to the interpreter executable. The
176177
default value is ``'python'``. The argument should point to a
177-
zero-terminated character string in static storage whose contents will not
178+
zero-terminated wide character string in static storage whose contents will not
178179
change for the duration of the program's execution. No code in the Python
179180
interpreter will change the contents of this storage.
180181

@@ -188,7 +189,7 @@ Initialization, Finalization, and Threads
188189
value.
189190

190191

191-
.. cfunction:: char* Py_GetPrefix()
192+
.. cfunction:: wchar_t* Py_GetPrefix()
192193

193194
Return the *prefix* for installed platform-independent files. This is derived
194195
through a number of complicated rules from the program name set with
@@ -201,7 +202,7 @@ Initialization, Finalization, and Threads
201202
It is only useful on Unix. See also the next function.
202203

203204

204-
.. cfunction:: char* Py_GetExecPrefix()
205+
.. cfunction:: wchar_t* Py_GetExecPrefix()
205206

206207
Return the *exec-prefix* for installed platform-*dependent* files. This is
207208
derived through a number of complicated rules from the program name set with
@@ -236,7 +237,7 @@ Initialization, Finalization, and Threads
236237
platform.
237238

238239

239-
.. cfunction:: char* Py_GetProgramFullPath()
240+
.. cfunction:: wchar_t* Py_GetProgramFullPath()
240241

241242
.. index::
242243
single: Py_SetProgramName()
@@ -249,7 +250,7 @@ Initialization, Finalization, and Threads
249250
to Python code as ``sys.executable``.
250251

251252

252-
.. cfunction:: char* Py_GetPath()
253+
.. cfunction:: wchar_t* Py_GetPath()
253254

254255
.. index::
255256
triple: module; search; path
@@ -342,7 +343,7 @@ Initialization, Finalization, and Threads
342343
``sys.version``.
343344

344345

345-
.. cfunction:: void PySys_SetArgv(int argc, char **argv)
346+
.. cfunction:: void PySys_SetArgv(int argc, wchar_t **argv)
346347

347348
.. index::
348349
single: main()

Doc/c-api/sys.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ accessible to C code. They all work with the current interpreter thread's
8484

8585
Reset :data:`sys.warnoptions` to an empty list.
8686

87-
.. cfunction:: void PySys_AddWarnOption(char *s)
87+
.. cfunction:: void PySys_AddWarnOption(wchar_t *s)
8888

8989
Append *s* to :data:`sys.warnoptions`.
9090

91-
.. cfunction:: void PySys_SetPath(char *path)
91+
.. cfunction:: void PySys_SetPath(wchar_t *path)
9292

9393
Set :data:`sys.path` to a list object of paths found in *path* which should
9494
be a list of paths separated with the platform's search path delimiter

Doc/c-api/unicode.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ the system's :ctype:`wchar_t`.
336336
.. cfunction:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size)
337337

338338
Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given size.
339+
Passing -1 as the size indicates that the function must itself compute the length,
340+
using wcslen.
339341
Return *NULL* on failure.
340342

341343

Doc/c-api/veryhigh.rst

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@ are only passed to these functions if it is certain that they were created by
2525
the same library that the Python runtime is using.
2626

2727

28-
.. cfunction:: int Py_Main(int argc, char **argv)
29-
30-
The main program for the standard interpreter. This is made available for
31-
programs which embed Python. The *argc* and *argv* parameters should be
32-
prepared exactly as those which are passed to a C program's :cfunc:`main`
33-
function. It is important to note that the argument list may be modified (but
34-
the contents of the strings pointed to by the argument list are not). The return
35-
value will be the integer passed to the :func:`sys.exit` function, ``1`` if the
36-
interpreter exits due to an exception, or ``2`` if the parameter list does not
37-
represent a valid Python command line.
28+
.. cfunction:: int Py_Main(int argc, wchar_t **argv)
29+
30+
The main program for the standard interpreter. This is made
31+
available for programs which embed Python. The *argc* and *argv*
32+
parameters should be prepared exactly as those which are passed to
33+
a C program's :cfunc:`main` function (converted to wchar_t
34+
according to the user's locale). It is important to note that the
35+
argument list may be modified (but the contents of the strings
36+
pointed to by the argument list are not). The return value will be
37+
the integer passed to the :func:`sys.exit` function, ``1`` if the
38+
interpreter exits due to an exception, or ``2`` if the parameter
39+
list does not represent a valid Python command line.
3840

3941

4042
.. cfunction:: int PyRun_AnyFile(FILE *fp, const char *filename)

Include/osdefs.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ extern "C" {
1212
#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)
1313
#if defined(PYOS_OS2) && defined(PYCC_GCC)
1414
#define MAXPATHLEN 260
15-
#define SEP '/'
16-
#define ALTSEP '\\'
15+
#define SEP L'/'
16+
#define ALTSEP L'\\'
1717
#else
18-
#define SEP '\\'
19-
#define ALTSEP '/'
18+
#define SEP L'\\'
19+
#define ALTSEP L'/'
2020
#define MAXPATHLEN 256
2121
#endif
22-
#define DELIM ';'
22+
#define DELIM L';'
2323
#endif
2424
#endif
2525

2626
/* Filename separator */
2727
#ifndef SEP
28-
#define SEP '/'
28+
#define SEP L'/'
2929
#endif
3030

3131
/* Max pathname length */
@@ -39,7 +39,7 @@ extern "C" {
3939

4040
/* Search path entry delimiter */
4141
#ifndef DELIM
42-
#define DELIM ':'
42+
#define DELIM L':'
4343
#endif
4444

4545
#ifdef __cplusplus

Include/pygetopt.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ extern "C" {
77

88
PyAPI_DATA(int) _PyOS_opterr;
99
PyAPI_DATA(int) _PyOS_optind;
10-
PyAPI_DATA(char *) _PyOS_optarg;
10+
PyAPI_DATA(wchar_t *) _PyOS_optarg;
1111

12-
PyAPI_FUNC(int) _PyOS_GetOpt(int argc, char **argv, char *optstring);
12+
PyAPI_FUNC(int) _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring);
1313

1414
#ifdef __cplusplus
1515
}

Include/pythonrun.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ typedef struct {
1717
int cf_flags; /* bitmask of CO_xxx flags relevant to future */
1818
} PyCompilerFlags;
1919

20-
PyAPI_FUNC(void) Py_SetProgramName(char *);
21-
PyAPI_FUNC(char *) Py_GetProgramName(void);
20+
PyAPI_FUNC(void) Py_SetProgramName(wchar_t *);
21+
PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
2222

23-
PyAPI_FUNC(void) Py_SetPythonHome(char *);
24-
PyAPI_FUNC(char *) Py_GetPythonHome(void);
23+
PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *);
24+
PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
2525

2626
PyAPI_FUNC(void) Py_Initialize(void);
2727
PyAPI_FUNC(void) Py_InitializeEx(int);
@@ -81,7 +81,7 @@ PyAPI_FUNC(void) Py_Exit(int);
8181
PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
8282

8383
/* Bootstrap */
84-
PyAPI_FUNC(int) Py_Main(int argc, char **argv);
84+
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
8585

8686
/* Use macros for a bunch of old variants */
8787
#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL)
@@ -103,10 +103,10 @@ PyAPI_FUNC(int) Py_Main(int argc, char **argv);
103103
PyRun_FileExFlags(fp, p, s, g, l, 0, flags)
104104

105105
/* In getpath.c */
106-
PyAPI_FUNC(char *) Py_GetProgramFullPath(void);
107-
PyAPI_FUNC(char *) Py_GetPrefix(void);
108-
PyAPI_FUNC(char *) Py_GetExecPrefix(void);
109-
PyAPI_FUNC(char *) Py_GetPath(void);
106+
PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void);
107+
PyAPI_FUNC(wchar_t *) Py_GetPrefix(void);
108+
PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
109+
PyAPI_FUNC(wchar_t *) Py_GetPath(void);
110110

111111
/* In their own files */
112112
PyAPI_FUNC(const char *) Py_GetVersion(void);

Include/sysmodule.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ extern "C" {
99

1010
PyAPI_FUNC(PyObject *) PySys_GetObject(const char *);
1111
PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *);
12-
PyAPI_FUNC(void) PySys_SetArgv(int, char **);
13-
PyAPI_FUNC(void) PySys_SetPath(const char *);
12+
PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **);
13+
PyAPI_FUNC(void) PySys_SetPath(const wchar_t *);
1414

1515
PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
1616
Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
@@ -21,7 +21,7 @@ PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc;
2121
PyAPI_DATA(int) _PySys_CheckInterval;
2222

2323
PyAPI_FUNC(void) PySys_ResetWarnOptions(void);
24-
PyAPI_FUNC(void) PySys_AddWarnOption(const char *);
24+
PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *);
2525

2626
#ifdef __cplusplus
2727
}

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ What's New in Python 3.0a5?
1212
Core and Builtins
1313
-----------------
1414

15+
- The command line processing was converted to pass Unicode strings
16+
through as unmodified as possible; as a consequence, the C API
17+
related to command line arguments was changed to use wchar_t.
18+
1519
Extension Modules
1620
-----------------
1721

Modules/_tkinter.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3012,7 +3012,7 @@ ins_string(PyObject *d, char *name, char *val)
30123012
PyMODINIT_FUNC
30133013
init_tkinter(void)
30143014
{
3015-
PyObject *m, *d;
3015+
PyObject *m, *d, *uexe, *cexe;
30163016

30173017
Py_TYPE(&Tkapp_Type) = &PyType_Type;
30183018

@@ -3065,7 +3065,16 @@ init_tkinter(void)
30653065

30663066
/* This helps the dynamic loader; in Unicode aware Tcl versions
30673067
it also helps Tcl find its encodings. */
3068-
Tcl_FindExecutable(Py_GetProgramName());
3068+
uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
3069+
if (uexe) {
3070+
cexe = PyUnicode_AsEncodedString(uexe,
3071+
Py_FileSystemDefaultEncoding,
3072+
NULL);
3073+
if (cexe)
3074+
Tcl_FindExecutable(PyString_AsString(cexe));
3075+
Py_XDECREF(cexe);
3076+
Py_DECREF(uexe);
3077+
}
30693078

30703079
if (PyErr_Occurred())
30713080
return;

0 commit comments

Comments
 (0)