mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
Issue #10089: Add support for arbitrary -X options on the command-line.
They can be retrieved through a new attribute `sys._xoptions`.
This commit is contained in:
parent
6d61cb4d2f
commit
9583cac633
10 changed files with 136 additions and 14 deletions
|
|
@ -127,6 +127,21 @@ accessible to C code. They all work with the current interpreter thread's
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. c:function:: void PySys_AddXOption(const wchar_t *s)
|
||||||
|
|
||||||
|
Parse *s* as a set of :option:`-X` options and add them to the current
|
||||||
|
options mapping as returned by :c:func:`PySys_GetXOptions`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PySys_GetXOptions()
|
||||||
|
|
||||||
|
Return the current dictionary of :option:`-X` options, similarly to
|
||||||
|
:data:`sys._xoptions`. On error, *NULL* is returned and an exception is
|
||||||
|
set.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
.. _processcontrol:
|
.. _processcontrol:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1305,6 +1305,9 @@ PyString_AsEncodedString:const char*:errors::
|
||||||
PySys_AddWarnOption:void:::
|
PySys_AddWarnOption:void:::
|
||||||
PySys_AddWarnOption:char*:s::
|
PySys_AddWarnOption:char*:s::
|
||||||
|
|
||||||
|
PySys_AddXOption:void:::
|
||||||
|
PySys_AddXOption:const wchar_t*:s::
|
||||||
|
|
||||||
PySys_GetFile:FILE*:::
|
PySys_GetFile:FILE*:::
|
||||||
PySys_GetFile:char*:name::
|
PySys_GetFile:char*:name::
|
||||||
PySys_GetFile:FILE*:def::
|
PySys_GetFile:FILE*:def::
|
||||||
|
|
@ -1312,6 +1315,8 @@ PySys_GetFile:FILE*:def::
|
||||||
PySys_GetObject:PyObject*::0:
|
PySys_GetObject:PyObject*::0:
|
||||||
PySys_GetObject:char*:name::
|
PySys_GetObject:char*:name::
|
||||||
|
|
||||||
|
PySys_GetXOptions:PyObject*::0:
|
||||||
|
|
||||||
PySys_SetArgv:int:::
|
PySys_SetArgv:int:::
|
||||||
PySys_SetArgv:int:argc::
|
PySys_SetArgv:int:argc::
|
||||||
PySys_SetArgv:char**:argv::
|
PySys_SetArgv:char**:argv::
|
||||||
|
|
|
||||||
|
|
@ -975,6 +975,30 @@ always available.
|
||||||
module for informational purposes; modifying this value has no effect on the
|
module for informational purposes; modifying this value has no effect on the
|
||||||
registry keys used by Python. Availability: Windows.
|
registry keys used by Python. Availability: Windows.
|
||||||
|
|
||||||
|
|
||||||
|
.. data:: _xoptions
|
||||||
|
|
||||||
|
A dictionary of the various implementation-specific flags passed through
|
||||||
|
the :option:`-X` command-line option. Option names are either mapped to
|
||||||
|
their values, if given explicitly, or to :const:`True`. Example::
|
||||||
|
|
||||||
|
$ ./python -Xa=b -Xc
|
||||||
|
Python 3.2a3+ (py3k, Oct 16 2010, 20:14:50)
|
||||||
|
[GCC 4.4.3] on linux2
|
||||||
|
Type "help", "copyright", "credits" or "license" for more information.
|
||||||
|
>>> import sys
|
||||||
|
>>> sys._xoptions
|
||||||
|
{'a': 'b', 'c': True}
|
||||||
|
|
||||||
|
.. impl-detail::
|
||||||
|
|
||||||
|
This is a CPython-specific way of accessing options passed through
|
||||||
|
:option:`-X`. Other implementations may export them through other
|
||||||
|
means, or not at all.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
||||||
.. rubric:: Citations
|
.. rubric:: Citations
|
||||||
|
|
||||||
.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf .
|
.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf .
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,17 @@ Miscellaneous options
|
||||||
|
|
||||||
.. note:: The line numbers in error messages will be off by one.
|
.. note:: The line numbers in error messages will be off by one.
|
||||||
|
|
||||||
|
|
||||||
|
.. cmdoption:: -X
|
||||||
|
|
||||||
|
Reserved for various implementation-specific options. CPython currently
|
||||||
|
defines none of them, but allows to pass arbitrary values and retrieve
|
||||||
|
them through the :data:`sys._xoptions` dictionary.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.2
|
||||||
|
It is now allowed to pass :option:`-X` with CPython.
|
||||||
|
|
||||||
|
|
||||||
Options you shouldn't use
|
Options you shouldn't use
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
@ -330,11 +341,6 @@ Options you shouldn't use
|
||||||
|
|
||||||
.. _Jython: http://jython.org
|
.. _Jython: http://jython.org
|
||||||
|
|
||||||
.. cmdoption:: -X
|
|
||||||
|
|
||||||
Reserved for alternative implementations of Python to use for their own
|
|
||||||
purposes.
|
|
||||||
|
|
||||||
.. _using-on-envvars:
|
.. _using-on-envvars:
|
||||||
|
|
||||||
Environment variables
|
Environment variables
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *);
|
||||||
PyAPI_FUNC(void) PySys_AddWarnOptionUnicode(PyObject *);
|
PyAPI_FUNC(void) PySys_AddWarnOptionUnicode(PyObject *);
|
||||||
PyAPI_FUNC(int) PySys_HasWarnOptions(void);
|
PyAPI_FUNC(int) PySys_HasWarnOptions(void);
|
||||||
|
|
||||||
|
PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *);
|
||||||
|
PyAPI_FUNC(PyObject *) PySys_GetXOptions(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,15 @@ class CmdLineTest(unittest.TestCase):
|
||||||
rc, out, err = assert_python_ok('-vv')
|
rc, out, err = assert_python_ok('-vv')
|
||||||
self.assertNotIn(b'stack overflow', err)
|
self.assertNotIn(b'stack overflow', err)
|
||||||
|
|
||||||
|
def test_xoptions(self):
|
||||||
|
rc, out, err = assert_python_ok('-c', 'import sys; print(sys._xoptions)')
|
||||||
|
opts = eval(out.splitlines()[0])
|
||||||
|
self.assertEqual(opts, {})
|
||||||
|
rc, out, err = assert_python_ok(
|
||||||
|
'-Xa', '-Xb=c,d=e', '-c', 'import sys; print(sys._xoptions)')
|
||||||
|
opts = eval(out.splitlines()[0])
|
||||||
|
self.assertEqual(opts, {'a': True, 'b': 'c,d=e'})
|
||||||
|
|
||||||
def test_run_module(self):
|
def test_run_module(self):
|
||||||
# Test expected operation of the '-m' switch
|
# Test expected operation of the '-m' switch
|
||||||
# Switch needs an argument
|
# Switch needs an argument
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ What's New in Python 3.2 Beta 1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #10089: Add support for arbitrary -X options on the command-line.
|
||||||
|
They can be retrieved through a new attribute ``sys._xoptions``.
|
||||||
|
|
||||||
- Issue #4388: On Mac OS X, decode command line arguments from UTF-8, instead
|
- Issue #4388: On Mac OS X, decode command line arguments from UTF-8, instead
|
||||||
of the locale encoding. If the LANG (and LC_ALL and LC_CTYPE) environment
|
of the locale encoding. If the LANG (and LC_ALL and LC_CTYPE) environment
|
||||||
variable is not set, the locale encoding is ISO-8859-1, whereas most programs
|
variable is not set, the locale encoding is ISO-8859-1, whereas most programs
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ static wchar_t **orig_argv;
|
||||||
static int orig_argc;
|
static int orig_argc;
|
||||||
|
|
||||||
/* command line options */
|
/* command line options */
|
||||||
#define BASE_OPTS L"bBc:dEhiJm:OsStuvVW:xX?"
|
#define BASE_OPTS L"bBc:dEhiJm:OsStuvVW:xX:?"
|
||||||
|
|
||||||
#define PROGRAM_OPTS BASE_OPTS
|
#define PROGRAM_OPTS BASE_OPTS
|
||||||
|
|
||||||
|
|
@ -84,6 +84,7 @@ static char *usage_3 = "\
|
||||||
-W arg : warning control; arg is action:message:category:module:lineno\n\
|
-W arg : warning control; arg is action:message:category:module:lineno\n\
|
||||||
also PYTHONWARNINGS=arg\n\
|
also PYTHONWARNINGS=arg\n\
|
||||||
-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
|
-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
|
||||||
|
-X opt : set implementation-specific option\n\
|
||||||
";
|
";
|
||||||
static char *usage_4 = "\
|
static char *usage_4 = "\
|
||||||
file : program read from script file\n\
|
file : program read from script file\n\
|
||||||
|
|
@ -407,8 +408,6 @@ Py_Main(int argc, wchar_t **argv)
|
||||||
skipfirstline = 1;
|
skipfirstline = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* case 'X': reserved for implementation-specific arguments */
|
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
case '?':
|
case '?':
|
||||||
help++;
|
help++;
|
||||||
|
|
@ -422,6 +421,10 @@ Py_Main(int argc, wchar_t **argv)
|
||||||
PySys_AddWarnOption(_PyOS_optarg);
|
PySys_AddWarnOption(_PyOS_optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'X':
|
||||||
|
PySys_AddXOption(_PyOS_optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
/* This space reserved for other options */
|
/* This space reserved for other options */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -89,12 +89,6 @@ int _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring)
|
||||||
return '_';
|
return '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option == 'X') {
|
|
||||||
fprintf(stderr,
|
|
||||||
"-X is reserved for implementation-specific arguments\n");
|
|
||||||
return '_';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ptr = wcschr(optstring, option)) == NULL) {
|
if ((ptr = wcschr(optstring, option)) == NULL) {
|
||||||
if (_PyOS_opterr)
|
if (_PyOS_opterr)
|
||||||
fprintf(stderr, "Unknown option: -%c\n", (char)option);
|
fprintf(stderr, "Unknown option: -%c\n", (char)option);
|
||||||
|
|
|
||||||
|
|
@ -1086,6 +1086,61 @@ PySys_HasWarnOptions(void)
|
||||||
return (warnoptions != NULL && (PyList_Size(warnoptions) > 0)) ? 1 : 0;
|
return (warnoptions != NULL && (PyList_Size(warnoptions) > 0)) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *xoptions = NULL;
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
get_xoptions(void)
|
||||||
|
{
|
||||||
|
if (xoptions == NULL || !PyDict_Check(xoptions)) {
|
||||||
|
Py_XDECREF(xoptions);
|
||||||
|
xoptions = PyDict_New();
|
||||||
|
}
|
||||||
|
return xoptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PySys_AddXOption(const wchar_t *s)
|
||||||
|
{
|
||||||
|
PyObject *opts;
|
||||||
|
PyObject *name = NULL, *value = NULL;
|
||||||
|
const wchar_t *name_end;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
opts = get_xoptions();
|
||||||
|
if (opts == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
name_end = wcschr(s, L'=');
|
||||||
|
if (!name_end) {
|
||||||
|
name = PyUnicode_FromWideChar(s, -1);
|
||||||
|
value = Py_True;
|
||||||
|
Py_INCREF(value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = PyUnicode_FromWideChar(s, name_end - s);
|
||||||
|
value = PyUnicode_FromWideChar(name_end + 1, -1);
|
||||||
|
}
|
||||||
|
if (name == NULL || value == NULL)
|
||||||
|
goto error;
|
||||||
|
r = PyDict_SetItem(opts, name, value);
|
||||||
|
Py_DECREF(name);
|
||||||
|
Py_DECREF(value);
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
Py_XDECREF(name);
|
||||||
|
Py_XDECREF(value);
|
||||||
|
/* No return value, therefore clear error state if possible */
|
||||||
|
if (_Py_atomic_load_relaxed(&_PyThreadState_Current))
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
PySys_GetXOptions(void)
|
||||||
|
{
|
||||||
|
return get_xoptions();
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
|
/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
|
||||||
Two literals concatenated works just fine. If you have a K&R compiler
|
Two literals concatenated works just fine. If you have a K&R compiler
|
||||||
or other abomination that however *does* understand longer strings,
|
or other abomination that however *does* understand longer strings,
|
||||||
|
|
@ -1535,6 +1590,11 @@ _PySys_Init(void)
|
||||||
PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
|
PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v = get_xoptions();
|
||||||
|
if (v != NULL) {
|
||||||
|
PyDict_SetItemString(sysdict, "_xoptions", v);
|
||||||
|
}
|
||||||
|
|
||||||
/* version_info */
|
/* version_info */
|
||||||
if (VersionInfoType.tp_name == 0)
|
if (VersionInfoType.tp_name == 0)
|
||||||
PyStructSequence_InitType(&VersionInfoType, &version_info_desc);
|
PyStructSequence_InitType(&VersionInfoType, &version_info_desc);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue