]> granicus.if.org Git - python/commitdiff
Issue #10089: Add support for arbitrary -X options on the command-line.
authorAntoine Pitrou <solipsis@pitrou.net>
Thu, 21 Oct 2010 13:42:28 +0000 (13:42 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Thu, 21 Oct 2010 13:42:28 +0000 (13:42 +0000)
They can be retrieved through a new attribute `sys._xoptions`.

Doc/c-api/sys.rst
Doc/data/refcounts.dat
Doc/library/sys.rst
Doc/using/cmdline.rst
Include/sysmodule.h
Lib/test/test_cmd_line.py
Misc/NEWS
Modules/main.c
Python/getopt.c
Python/sysmodule.c

index 232cec032e888b5847b431f7b6a35fcb59619a2f..252bd1ad0604126a3b8540b8e379c4797ded7fd0 100644 (file)
@@ -127,6 +127,21 @@ accessible to C code.  They all work with the current interpreter thread's
 
    .. 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:
 
index 2dc7084297a9ccbe4c44915fe900df0c9ba906f3..f2a87670dbd237b5e83ac423a624f1c0ff109248 100644 (file)
@@ -1305,6 +1305,9 @@ PyString_AsEncodedString:const char*:errors::
 PySys_AddWarnOption:void:::
 PySys_AddWarnOption:char*:s::
 
+PySys_AddXOption:void:::
+PySys_AddXOption:const wchar_t*:s::
+
 PySys_GetFile:FILE*:::
 PySys_GetFile:char*:name::
 PySys_GetFile:FILE*:def::
@@ -1312,6 +1315,8 @@ PySys_GetFile:FILE*:def::
 PySys_GetObject:PyObject*::0:
 PySys_GetObject:char*:name::
 
+PySys_GetXOptions:PyObject*::0:
+
 PySys_SetArgv:int:::
 PySys_SetArgv:int:argc::
 PySys_SetArgv:char**:argv::
index 23fdb09d39cea7cf68321fe33f4cc1ae92088dd0..bf8e0d01642c7203efc54728a6be25be01c83fe0 100644 (file)
@@ -975,6 +975,30 @@ always available.
    module for informational purposes; modifying this value has no effect on the
    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
 
 .. [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 .
index 7da1954b25a81341c0fcabaea4a5080c5509830c..6f3cfbe2949bda3f93fe720af3f0d5ea477ec08a 100644 (file)
@@ -321,6 +321,17 @@ Miscellaneous options
 
    .. 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
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -330,11 +341,6 @@ Options you shouldn't use
 
 .. _Jython: http://jython.org
 
-.. cmdoption:: -X
-
-    Reserved for alternative implementations of Python to use for their own
-    purposes.
-
 .. _using-on-envvars:
 
 Environment variables
index e43f378f6e35265791ceb1b8803c057b99168437..c00901b1798aa8ae54757d015d22b97cc59be6d8 100644 (file)
@@ -27,6 +27,9 @@ PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *);
 PyAPI_FUNC(void) PySys_AddWarnOptionUnicode(PyObject *);
 PyAPI_FUNC(int) PySys_HasWarnOptions(void);
 
+PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *);
+PyAPI_FUNC(PyObject *) PySys_GetXOptions(void);
+
 #ifdef __cplusplus
 }
 #endif
index c864cdd4bb4384f305a9aa1eb799a1f80cf60ac4..0ddc8131f686b7e2656565c48ca0e40982ab6231 100644 (file)
@@ -67,6 +67,15 @@ class CmdLineTest(unittest.TestCase):
         rc, out, err = assert_python_ok('-vv')
         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):
         # Test expected operation of the '-m' switch
         # Switch needs an argument
index 265b88147e1aad0f217c67375cdabd1e6c3b0932..caf1b49a7d0802acd863ffb9c9ed24d569743f4a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.2 Beta 1?
 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
   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
index 7df883c8bb7d0e0fca5a51d41116d486d958d7a5..008b6a4d10efceecdc298eea11da06ba8a4391d6 100644 (file)
@@ -47,7 +47,7 @@ static wchar_t **orig_argv;
 static int  orig_argc;
 
 /* command line options */
-#define BASE_OPTS L"bBc:dEhiJm:OsStuvVW:xX?"
+#define BASE_OPTS L"bBc:dEhiJm:OsStuvVW:xX:?"
 
 #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\
          also PYTHONWARNINGS=arg\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 = "\
 file   : program read from script file\n\
@@ -407,8 +408,6 @@ Py_Main(int argc, wchar_t **argv)
             skipfirstline = 1;
             break;
 
-        /* case 'X': reserved for implementation-specific arguments */
-
         case 'h':
         case '?':
             help++;
@@ -422,6 +421,10 @@ Py_Main(int argc, wchar_t **argv)
             PySys_AddWarnOption(_PyOS_optarg);
             break;
 
+        case 'X':
+            PySys_AddXOption(_PyOS_optarg);
+            break;
+
         /* This space reserved for other options */
 
         default:
index 5147320af2829db0a713c9c02cadc249c0a26cb0..064a1874ea5860719e0bc7d88e7c68cfca6a23a4 100644 (file)
@@ -89,12 +89,6 @@ int _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring)
         return '_';
     }
 
-    if (option == 'X') {
-        fprintf(stderr,
-          "-X is reserved for implementation-specific arguments\n");
-        return '_';
-    }
-
     if ((ptr = wcschr(optstring, option)) == NULL) {
         if (_PyOS_opterr)
           fprintf(stderr, "Unknown option: -%c\n", (char)option);
index 033c9d5e564122b76a2ff181faff3a5efe0e5d99..2530cc07aac8b6a4d427b45006f42e22ed791fd3 100644 (file)
@@ -1086,6 +1086,61 @@ PySys_HasWarnOptions(void)
     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.
    Two literals concatenated works just fine.  If you have a K&R compiler
    or other abomination that however *does* understand longer strings,
@@ -1535,6 +1590,11 @@ _PySys_Init(void)
         PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
     }
 
+    v = get_xoptions();
+    if (v != NULL) {
+        PyDict_SetItemString(sysdict, "_xoptions", v);
+    }
+
     /* version_info */
     if (VersionInfoType.tp_name == 0)
         PyStructSequence_InitType(&VersionInfoType, &version_info_desc);