Python-checkins
Threads by month
- ----- 2024 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
November 2018
- 2 participants
- 507 discussions
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
26 Nov '18
https://github.com/python/cpython/commit/d1cbc6f8a00cf881ced6238c5e652054e8…
commit: d1cbc6f8a00cf881ced6238c5e652054e8fdc30f
branch: master
author: Zackery Spytz <zspytz(a)gmail.com>
committer: Serhiy Storchaka <storchaka(a)gmail.com>
date: 2018-11-27T07:40:49+02:00
summary:
Include the highest pickle protocol in a couple of tests. (GH-10735)
test_reduce_ex() in test_array.py and
test_reversevaluesiterator_pickling() in test_dict.py weren't using
the highest pickle protocol.
files:
M Lib/test/test_array.py
M Lib/test/test_dict.py
diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py
index e9218f3dd68c..7f402f864471 100644
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -248,7 +248,7 @@ def test_reduce_ex(self):
a = array.array(self.typecode, self.example)
for protocol in range(3):
self.assertIs(a.__reduce_ex__(protocol)[0], array.array)
- for protocol in range(3, pickle.HIGHEST_PROTOCOL):
+ for protocol in range(3, pickle.HIGHEST_PROTOCOL + 1):
self.assertIs(a.__reduce_ex__(protocol)[0], array_reconstructor)
def test_pickle(self):
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 71fffe398f34..03afd5b2a6c7 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -1112,7 +1112,7 @@ def test_reverseitemiterator_pickling(self):
self.assertEqual(dict(it), data)
def test_reversevaluesiterator_pickling(self):
- for proto in range(pickle.HIGHEST_PROTOCOL):
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
data = {1:"a", 2:"b", 3:"c"}
# data.values() isn't picklable, only its iterator
it = reversed(data.values())
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
closes bpo-34212: Build core extension modules with Py_BUILD_CORE_BUILTIN. (GH-8712)
by Miss Islington (bot) 26 Nov '18
by Miss Islington (bot) 26 Nov '18
26 Nov '18
https://github.com/python/cpython/commit/716a8089b04095acaba493925751df194a…
commit: 716a8089b04095acaba493925751df194a4916bb
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-26T18:32:57-08:00
summary:
closes bpo-34212: Build core extension modules with Py_BUILD_CORE_BUILTIN. (GH-8712)
(cherry picked from commit da324d53d420347344236ff64cf5eb9b675d6f86)
Co-authored-by: E. M. Bray <erik.m.bray(a)gmail.com>
files:
M Makefile.pre.in
M Modules/makesetup
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 4c23c0e4114a..afbc8f8c9bea 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -107,6 +107,7 @@ ARFLAGS= @ARFLAGS@
CFLAGSFORSHARED=@CFLAGSFORSHARED@
# C flags used for building the interpreter object files
PY_STDMODULE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARED)
+PY_BUILTIN_MODULE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE_BUILTIN
PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE
# Strict or non-strict aliasing flags used to compile dtoa.c, see above
CFLAGS_ALIASING=@CFLAGS_ALIASING@
diff --git a/Modules/makesetup b/Modules/makesetup
index 020b19938c48..eac97ad1346c 100755
--- a/Modules/makesetup
+++ b/Modules/makesetup
@@ -233,7 +233,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' |
case $doconfig in
no) cc="$cc \$(CCSHARED) \$(PY_CFLAGS) \$(PY_CPPFLAGS)";;
*)
- cc="$cc \$(PY_STDMODULE_CFLAGS)";;
+ cc="$cc \$(PY_BUILTIN_MODULE_CFLAGS)";;
esac
rule="$obj: $src; $cc $cpps -c $src -o $obj"
echo "$rule" >>$rulesf
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
closes bpo-34212: Build core extension modules with Py_BUILD_CORE_BUILTIN. (GH-8712)
by Benjamin Peterson 26 Nov '18
by Benjamin Peterson 26 Nov '18
26 Nov '18
https://github.com/python/cpython/commit/da324d53d420347344236ff64cf5eb9b67…
commit: da324d53d420347344236ff64cf5eb9b675d6f86
branch: master
author: E. M. Bray <erik.m.bray(a)gmail.com>
committer: Benjamin Peterson <benjamin(a)python.org>
date: 2018-11-26T20:21:31-06:00
summary:
closes bpo-34212: Build core extension modules with Py_BUILD_CORE_BUILTIN. (GH-8712)
files:
M Makefile.pre.in
M Modules/makesetup
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 2c92db23489e..17007aef5623 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -106,6 +106,7 @@ ARFLAGS= @ARFLAGS@
CFLAGSFORSHARED=@CFLAGSFORSHARED@
# C flags used for building the interpreter object files
PY_STDMODULE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARED)
+PY_BUILTIN_MODULE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE_BUILTIN
PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE
# Strict or non-strict aliasing flags used to compile dtoa.c, see above
CFLAGS_ALIASING=@CFLAGS_ALIASING@
diff --git a/Modules/makesetup b/Modules/makesetup
index bf5ca3902b56..fefe3fd129ee 100755
--- a/Modules/makesetup
+++ b/Modules/makesetup
@@ -233,7 +233,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' |
case $doconfig in
no) cc="$cc \$(CCSHARED) \$(PY_CFLAGS) \$(PY_CPPFLAGS)";;
*)
- cc="$cc \$(PY_STDMODULE_CFLAGS)";;
+ cc="$cc \$(PY_BUILTIN_MODULE_CFLAGS)";;
esac
rule="$obj: $src; $cc $cpps -c $src -o $obj"
echo "$rule" >>$rulesf
1
0
https://github.com/python/cpython/commit/f2a9d5c8378cd7eca90b3b197e2cc0989d…
commit: f2a9d5c8378cd7eca90b3b197e2cc0989da55014
branch: master
author: Victor Stinner <vstinner(a)redhat.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-27T00:20:00+01:00
summary:
bpo-35134: Create Include/cpython/pystate.h (GH-10733)
Move pystate.h code surrounded by "#ifndef Py_LIMITED_API"
to a new Include/cpython/pystate.h header file.
files:
A Include/cpython/pystate.h
M Include/pystate.h
diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h
new file mode 100644
index 000000000000..78e9a5ed1013
--- /dev/null
+++ b/Include/cpython/pystate.h
@@ -0,0 +1,272 @@
+#ifndef Py_CPYTHON_PYSTATE_H
+# error "this header file must not be included directly"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
+
+/* Placeholders while working on the new configuration API
+ *
+ * See PEP 432 for final anticipated contents
+ */
+typedef struct {
+ int install_signal_handlers; /* Install signal handlers? -1 means unset */
+ PyObject *argv; /* sys.argv list, can be NULL */
+ PyObject *executable; /* sys.executable str */
+ PyObject *prefix; /* sys.prefix str */
+ PyObject *base_prefix; /* sys.base_prefix str, can be NULL */
+ PyObject *exec_prefix; /* sys.exec_prefix str */
+ PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */
+ PyObject *warnoptions; /* sys.warnoptions list, can be NULL */
+ PyObject *xoptions; /* sys._xoptions dict, can be NULL */
+ PyObject *module_search_path; /* sys.path list */
+ PyObject *pycache_prefix; /* sys.pycache_prefix str, can be NULL */
+} _PyMainInterpreterConfig;
+
+#define _PyMainInterpreterConfig_INIT \
+ (_PyMainInterpreterConfig){.install_signal_handlers = -1}
+/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */
+
+typedef struct _is {
+
+ struct _is *next;
+ struct _ts *tstate_head;
+
+ int64_t id;
+ int64_t id_refcount;
+ PyThread_type_lock id_mutex;
+
+ PyObject *modules;
+ PyObject *modules_by_index;
+ PyObject *sysdict;
+ PyObject *builtins;
+ PyObject *importlib;
+
+ /* Used in Python/sysmodule.c. */
+ int check_interval;
+
+ /* Used in Modules/_threadmodule.c. */
+ long num_threads;
+ /* Support for runtime thread stack size tuning.
+ A value of 0 means using the platform's default stack size
+ or the size specified by the THREAD_STACK_SIZE macro. */
+ /* Used in Python/thread.c. */
+ size_t pythread_stacksize;
+
+ PyObject *codec_search_path;
+ PyObject *codec_search_cache;
+ PyObject *codec_error_registry;
+ int codecs_initialized;
+ int fscodec_initialized;
+
+ _PyCoreConfig core_config;
+ _PyMainInterpreterConfig config;
+#ifdef HAVE_DLOPEN
+ int dlopenflags;
+#endif
+
+ PyObject *builtins_copy;
+ PyObject *import_func;
+ /* Initialized to PyEval_EvalFrameDefault(). */
+ _PyFrameEvalFunction eval_frame;
+
+ Py_ssize_t co_extra_user_count;
+ freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
+
+#ifdef HAVE_FORK
+ PyObject *before_forkers;
+ PyObject *after_forkers_parent;
+ PyObject *after_forkers_child;
+#endif
+ /* AtExit module */
+ void (*pyexitfunc)(PyObject *);
+ PyObject *pyexitmodule;
+
+ uint64_t tstate_next_unique_id;
+} PyInterpreterState;
+
+/* State unique per thread */
+
+/* Py_tracefunc return -1 when raising an exception, or 0 for success. */
+typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *);
+
+/* The following values are used for 'what' for tracefunc functions
+ *
+ * To add a new kind of trace event, also update "trace_init" in
+ * Python/sysmodule.c to define the Python level event name
+ */
+#define PyTrace_CALL 0
+#define PyTrace_EXCEPTION 1
+#define PyTrace_LINE 2
+#define PyTrace_RETURN 3
+#define PyTrace_C_CALL 4
+#define PyTrace_C_EXCEPTION 5
+#define PyTrace_C_RETURN 6
+#define PyTrace_OPCODE 7
+
+
+typedef struct _err_stackitem {
+ /* This struct represents an entry on the exception stack, which is a
+ * per-coroutine state. (Coroutine in the computer science sense,
+ * including the thread and generators).
+ * This ensures that the exception state is not impacted by "yields"
+ * from an except handler.
+ */
+ PyObject *exc_type, *exc_value, *exc_traceback;
+
+ struct _err_stackitem *previous_item;
+
+} _PyErr_StackItem;
+
+
+typedef struct _ts {
+ /* See Python/ceval.c for comments explaining most fields */
+
+ struct _ts *prev;
+ struct _ts *next;
+ PyInterpreterState *interp;
+
+ struct _frame *frame;
+ int recursion_depth;
+ char overflowed; /* The stack has overflowed. Allow 50 more calls
+ to handle the runtime error. */
+ char recursion_critical; /* The current calls must not cause
+ a stack overflow. */
+ int stackcheck_counter;
+
+ /* 'tracing' keeps track of the execution depth when tracing/profiling.
+ This is to prevent the actual trace/profile code from being recorded in
+ the trace/profile. */
+ int tracing;
+ int use_tracing;
+
+ Py_tracefunc c_profilefunc;
+ Py_tracefunc c_tracefunc;
+ PyObject *c_profileobj;
+ PyObject *c_traceobj;
+
+ /* The exception currently being raised */
+ PyObject *curexc_type;
+ PyObject *curexc_value;
+ PyObject *curexc_traceback;
+
+ /* The exception currently being handled, if no coroutines/generators
+ * are present. Always last element on the stack referred to be exc_info.
+ */
+ _PyErr_StackItem exc_state;
+
+ /* Pointer to the top of the stack of the exceptions currently
+ * being handled */
+ _PyErr_StackItem *exc_info;
+
+ PyObject *dict; /* Stores per-thread state */
+
+ int gilstate_counter;
+
+ PyObject *async_exc; /* Asynchronous exception to raise */
+ unsigned long thread_id; /* Thread id where this tstate was created */
+
+ int trash_delete_nesting;
+ PyObject *trash_delete_later;
+
+ /* Called when a thread state is deleted normally, but not when it
+ * is destroyed after fork().
+ * Pain: to prevent rare but fatal shutdown errors (issue 18808),
+ * Thread.join() must wait for the join'ed thread's tstate to be unlinked
+ * from the tstate chain. That happens at the end of a thread's life,
+ * in pystate.c.
+ * The obvious way doesn't quite work: create a lock which the tstate
+ * unlinking code releases, and have Thread.join() wait to acquire that
+ * lock. The problem is that we _are_ at the end of the thread's life:
+ * if the thread holds the last reference to the lock, decref'ing the
+ * lock will delete the lock, and that may trigger arbitrary Python code
+ * if there's a weakref, with a callback, to the lock. But by this time
+ * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest
+ * of C code can be allowed to run (in particular it must not be possible to
+ * release the GIL).
+ * So instead of holding the lock directly, the tstate holds a weakref to
+ * the lock: that's the value of on_delete_data below. Decref'ing a
+ * weakref is harmless.
+ * on_delete points to _threadmodule.c's static release_sentinel() function.
+ * After the tstate is unlinked, release_sentinel is called with the
+ * weakref-to-lock (on_delete_data) argument, and release_sentinel releases
+ * the indirectly held lock.
+ */
+ void (*on_delete)(void *);
+ void *on_delete_data;
+
+ int coroutine_origin_tracking_depth;
+
+ PyObject *coroutine_wrapper;
+ int in_coroutine_wrapper;
+
+ PyObject *async_gen_firstiter;
+ PyObject *async_gen_finalizer;
+
+ PyObject *context;
+ uint64_t context_ver;
+
+ /* Unique thread state id. */
+ uint64_t id;
+
+ /* XXX signal handlers should also be here */
+
+} PyThreadState;
+
+/* Get the current interpreter state.
+
+ Issue a fatal error if there no current Python thread state or no current
+ interpreter. It cannot return NULL.
+
+ The caller must hold the GIL.*/
+PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
+
+PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
+PyAPI_FUNC(void) _PyState_ClearModules(void);
+PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
+PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *);
+PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
+PyAPI_FUNC(void) _PyGILState_Reinit(void);
+
+/* Similar to PyThreadState_Get(), but don't issue a fatal error
+ * if it is NULL. */
+PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
+
+/* PyGILState */
+
+/* Helper/diagnostic function - return 1 if the current thread
+ currently holds the GIL, 0 otherwise.
+
+ The function returns 1 if _PyGILState_check_enabled is non-zero. */
+PyAPI_FUNC(int) PyGILState_Check(void);
+
+/* Get the single PyInterpreterState used by this process' GILState
+ implementation.
+
+ This function doesn't check for error. Return NULL before _PyGILState_Init()
+ is called and after _PyGILState_Fini() is called.
+
+ See also _PyInterpreterState_Get() and _PyInterpreterState_GET_UNSAFE(). */
+PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
+
+/* The implementation of sys._current_frames() Returns a dict mapping
+ thread id to that thread's current frame.
+*/
+PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void);
+
+/* Routines for advanced debuggers, requested by David Beazley.
+ Don't use unless you know what you are doing! */
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void);
+PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *);
+PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *);
+PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
+
+typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Include/pystate.h b/Include/pystate.h
index 58499ea35b47..cc479ff867a4 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -20,273 +20,31 @@ struct _ts; /* Forward */
struct _is; /* Forward */
struct _frame; /* Forward declaration for PyFrameObject. */
-#ifdef Py_LIMITED_API
typedef struct _is PyInterpreterState;
-#else
-typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
-
-/* Placeholders while working on the new configuration API
- *
- * See PEP 432 for final anticipated contents
- */
-typedef struct {
- int install_signal_handlers; /* Install signal handlers? -1 means unset */
- PyObject *argv; /* sys.argv list, can be NULL */
- PyObject *executable; /* sys.executable str */
- PyObject *prefix; /* sys.prefix str */
- PyObject *base_prefix; /* sys.base_prefix str, can be NULL */
- PyObject *exec_prefix; /* sys.exec_prefix str */
- PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */
- PyObject *warnoptions; /* sys.warnoptions list, can be NULL */
- PyObject *xoptions; /* sys._xoptions dict, can be NULL */
- PyObject *module_search_path; /* sys.path list */
- PyObject *pycache_prefix; /* sys.pycache_prefix str, can be NULL */
-} _PyMainInterpreterConfig;
-
-#define _PyMainInterpreterConfig_INIT \
- (_PyMainInterpreterConfig){.install_signal_handlers = -1}
-/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */
-
-typedef struct _is {
-
- struct _is *next;
- struct _ts *tstate_head;
-
- int64_t id;
- int64_t id_refcount;
- PyThread_type_lock id_mutex;
-
- PyObject *modules;
- PyObject *modules_by_index;
- PyObject *sysdict;
- PyObject *builtins;
- PyObject *importlib;
-
- /* Used in Python/sysmodule.c. */
- int check_interval;
-
- /* Used in Modules/_threadmodule.c. */
- long num_threads;
- /* Support for runtime thread stack size tuning.
- A value of 0 means using the platform's default stack size
- or the size specified by the THREAD_STACK_SIZE macro. */
- /* Used in Python/thread.c. */
- size_t pythread_stacksize;
-
- PyObject *codec_search_path;
- PyObject *codec_search_cache;
- PyObject *codec_error_registry;
- int codecs_initialized;
- int fscodec_initialized;
-
- _PyCoreConfig core_config;
- _PyMainInterpreterConfig config;
-#ifdef HAVE_DLOPEN
- int dlopenflags;
-#endif
-
- PyObject *builtins_copy;
- PyObject *import_func;
- /* Initialized to PyEval_EvalFrameDefault(). */
- _PyFrameEvalFunction eval_frame;
-
- Py_ssize_t co_extra_user_count;
- freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
-
-#ifdef HAVE_FORK
- PyObject *before_forkers;
- PyObject *after_forkers_parent;
- PyObject *after_forkers_child;
-#endif
- /* AtExit module */
- void (*pyexitfunc)(PyObject *);
- PyObject *pyexitmodule;
-
- uint64_t tstate_next_unique_id;
-} PyInterpreterState;
-#endif /* !Py_LIMITED_API */
-
/* State unique per thread */
-#ifndef Py_LIMITED_API
-/* Py_tracefunc return -1 when raising an exception, or 0 for success. */
-typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *);
-
-/* The following values are used for 'what' for tracefunc functions
- *
- * To add a new kind of trace event, also update "trace_init" in
- * Python/sysmodule.c to define the Python level event name
- */
-#define PyTrace_CALL 0
-#define PyTrace_EXCEPTION 1
-#define PyTrace_LINE 2
-#define PyTrace_RETURN 3
-#define PyTrace_C_CALL 4
-#define PyTrace_C_EXCEPTION 5
-#define PyTrace_C_RETURN 6
-#define PyTrace_OPCODE 7
-#endif /* Py_LIMITED_API */
-
-#ifdef Py_LIMITED_API
typedef struct _ts PyThreadState;
-#else
-
-typedef struct _err_stackitem {
- /* This struct represents an entry on the exception stack, which is a
- * per-coroutine state. (Coroutine in the computer science sense,
- * including the thread and generators).
- * This ensures that the exception state is not impacted by "yields"
- * from an except handler.
- */
- PyObject *exc_type, *exc_value, *exc_traceback;
-
- struct _err_stackitem *previous_item;
-
-} _PyErr_StackItem;
-
-
-typedef struct _ts {
- /* See Python/ceval.c for comments explaining most fields */
-
- struct _ts *prev;
- struct _ts *next;
- PyInterpreterState *interp;
-
- struct _frame *frame;
- int recursion_depth;
- char overflowed; /* The stack has overflowed. Allow 50 more calls
- to handle the runtime error. */
- char recursion_critical; /* The current calls must not cause
- a stack overflow. */
- int stackcheck_counter;
-
- /* 'tracing' keeps track of the execution depth when tracing/profiling.
- This is to prevent the actual trace/profile code from being recorded in
- the trace/profile. */
- int tracing;
- int use_tracing;
-
- Py_tracefunc c_profilefunc;
- Py_tracefunc c_tracefunc;
- PyObject *c_profileobj;
- PyObject *c_traceobj;
-
- /* The exception currently being raised */
- PyObject *curexc_type;
- PyObject *curexc_value;
- PyObject *curexc_traceback;
-
- /* The exception currently being handled, if no coroutines/generators
- * are present. Always last element on the stack referred to be exc_info.
- */
- _PyErr_StackItem exc_state;
-
- /* Pointer to the top of the stack of the exceptions currently
- * being handled */
- _PyErr_StackItem *exc_info;
-
- PyObject *dict; /* Stores per-thread state */
-
- int gilstate_counter;
-
- PyObject *async_exc; /* Asynchronous exception to raise */
- unsigned long thread_id; /* Thread id where this tstate was created */
-
- int trash_delete_nesting;
- PyObject *trash_delete_later;
-
- /* Called when a thread state is deleted normally, but not when it
- * is destroyed after fork().
- * Pain: to prevent rare but fatal shutdown errors (issue 18808),
- * Thread.join() must wait for the join'ed thread's tstate to be unlinked
- * from the tstate chain. That happens at the end of a thread's life,
- * in pystate.c.
- * The obvious way doesn't quite work: create a lock which the tstate
- * unlinking code releases, and have Thread.join() wait to acquire that
- * lock. The problem is that we _are_ at the end of the thread's life:
- * if the thread holds the last reference to the lock, decref'ing the
- * lock will delete the lock, and that may trigger arbitrary Python code
- * if there's a weakref, with a callback, to the lock. But by this time
- * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest
- * of C code can be allowed to run (in particular it must not be possible to
- * release the GIL).
- * So instead of holding the lock directly, the tstate holds a weakref to
- * the lock: that's the value of on_delete_data below. Decref'ing a
- * weakref is harmless.
- * on_delete points to _threadmodule.c's static release_sentinel() function.
- * After the tstate is unlinked, release_sentinel is called with the
- * weakref-to-lock (on_delete_data) argument, and release_sentinel releases
- * the indirectly held lock.
- */
- void (*on_delete)(void *);
- void *on_delete_data;
-
- int coroutine_origin_tracking_depth;
-
- PyObject *coroutine_wrapper;
- int in_coroutine_wrapper;
-
- PyObject *async_gen_firstiter;
- PyObject *async_gen_finalizer;
-
- PyObject *context;
- uint64_t context_ver;
-
- /* Unique thread state id. */
- uint64_t id;
-
- /* XXX signal handlers should also be here */
-
-} PyThreadState;
-#endif /* !Py_LIMITED_API */
-
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *);
PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *);
-#if !defined(Py_LIMITED_API)
-/* Get the current interpreter state.
-
- Issue a fatal error if there no current Python thread state or no current
- interpreter. It cannot return NULL.
-
- The caller must hold the GIL.*/
-PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
-#endif
-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
/* New in 3.7 */
PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *);
#endif
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
-#endif /* !Py_LIMITED_API */
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
/* New in 3.3 */
PyAPI_FUNC(int) PyState_AddModule(PyObject*, struct PyModuleDef*);
PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*);
#endif
PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _PyState_ClearModules(void);
-#endif
PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
-PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *);
-#endif /* !Py_LIMITED_API */
PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *);
PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
-#endif /* !Py_LIMITED_API */
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _PyGILState_Reinit(void);
-#endif /* !Py_LIMITED_API */
/* Get the current thread state.
@@ -309,12 +67,6 @@ PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);
See also PyThreadState_Get() and _PyThreadState_GET(). */
#define PyThreadState_GET() PyThreadState_Get()
-#ifndef Py_LIMITED_API
-/* Similar to PyThreadState_Get(), but don't issue a fatal error
- * if it is NULL. */
-PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
-#endif /* !Py_LIMITED_API */
-
PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);
PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void);
PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *);
@@ -365,41 +117,11 @@ PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE);
*/
PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void);
-#ifndef Py_LIMITED_API
-/* Helper/diagnostic function - return 1 if the current thread
- currently holds the GIL, 0 otherwise.
-
- The function returns 1 if _PyGILState_check_enabled is non-zero. */
-PyAPI_FUNC(int) PyGILState_Check(void);
-
-/* Get the single PyInterpreterState used by this process' GILState
- implementation.
- This function doesn't check for error. Return NULL before _PyGILState_Init()
- is called and after _PyGILState_Fini() is called.
-
- See also _PyInterpreterState_Get() and _PyInterpreterState_GET_UNSAFE(). */
-PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
-#endif /* !Py_LIMITED_API */
-
-
-/* The implementation of sys._current_frames() Returns a dict mapping
- thread id to that thread's current frame.
-*/
#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void);
-#endif
-
-/* Routines for advanced debuggers, requested by David Beazley.
- Don't use unless you know what you are doing! */
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);
-PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void);
-PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *);
-PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *);
-PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
-
-typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_);
+# define Py_CPYTHON_PYSTATE_H
+# include "cpython/pystate.h"
+# undef Py_CPYTHON_PYSTATE_H
#endif
#ifdef __cplusplus
1
0
https://github.com/python/cpython/commit/ffedd9ad2a8be4bf82a4d8f2bac3eaee5b…
commit: ffedd9ad2a8be4bf82a4d8f2bac3eaee5b44191e
branch: master
author: Victor Stinner <vstinner(a)redhat.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-27T00:12:26+01:00
summary:
bpo-35134: Create Include/cpython/dictobject.h (GH-10732)
* Move dictobject.h code surrounded by "#ifndef Py_LIMITED_API"
to a new Include/cpython/dictobject.h header file.
* Add PyAPI_FUNC() to _PyDictView_New().
* Reorganize dictobject.h: move views and iterators at the end.
files:
A Include/cpython/dictobject.h
M Include/dictobject.h
diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h
new file mode 100644
index 000000000000..4c7457cd0b26
--- /dev/null
+++ b/Include/cpython/dictobject.h
@@ -0,0 +1,93 @@
+#ifndef Py_CPYTHON_DICTOBJECT_H
+# error "this header file must not be included directly"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _dictkeysobject PyDictKeysObject;
+
+/* The ma_values pointer is NULL for a combined table
+ * or points to an array of PyObject* for a split table
+ */
+typedef struct {
+ PyObject_HEAD
+
+ /* Number of items in the dictionary */
+ Py_ssize_t ma_used;
+
+ /* Dictionary version: globally unique, value change each time
+ the dictionary is modified */
+ uint64_t ma_version_tag;
+
+ PyDictKeysObject *ma_keys;
+
+ /* If ma_values is NULL, the table is "combined": keys and values
+ are stored in ma_keys.
+
+ If ma_values is not NULL, the table is splitted:
+ keys are stored in ma_keys and values are stored in ma_values */
+ PyObject **ma_values;
+} PyDictObject;
+
+PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
+ Py_hash_t hash);
+PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
+ struct _Py_Identifier *key);
+PyAPI_FUNC(PyObject *) PyDict_SetDefault(
+ PyObject *mp, PyObject *key, PyObject *defaultobj);
+PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
+ PyObject *item, Py_hash_t hash);
+PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key,
+ Py_hash_t hash);
+PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key,
+ int (*predicate)(PyObject *value));
+PyDictKeysObject *_PyDict_NewKeysForClass(void);
+PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *);
+PyAPI_FUNC(int) _PyDict_Next(
+ PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
+
+/* Get the number of items of a dictionary. */
+#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used)
+PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash);
+PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
+PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
+PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
+Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
+PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);
+PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *);
+PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *);
+PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
+#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
+
+PyAPI_FUNC(int) PyDict_ClearFreeList(void);
+
+/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0,
+ the first occurrence of a key wins, if override is 1, the last occurrence
+ of a key wins, if override is 2, a KeyError with conflicting key as
+ argument is raised.
+*/
+PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override);
+PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key);
+PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item);
+
+PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key);
+PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out);
+
+int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
+PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
+
+/* _PyDictView */
+
+typedef struct {
+ PyObject_HEAD
+ PyDictObject *dv_dict;
+} _PyDictViewObject;
+
+PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *);
+PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Include/dictobject.h b/Include/dictobject.h
index c0f24df7d265..b37573ad48c0 100644
--- a/Include/dictobject.h
+++ b/Include/dictobject.h
@@ -4,7 +4,6 @@
extern "C" {
#endif
-
/* Dictionary object type -- mapping from hashable object to object */
/* The distribution includes a separate file, Objects/dictnotes.txt,
@@ -13,119 +12,26 @@ extern "C" {
tuning dictionaries, and several ideas for possible optimizations.
*/
-#ifndef Py_LIMITED_API
-
-typedef struct _dictkeysobject PyDictKeysObject;
-
-/* The ma_values pointer is NULL for a combined table
- * or points to an array of PyObject* for a split table
- */
-typedef struct {
- PyObject_HEAD
-
- /* Number of items in the dictionary */
- Py_ssize_t ma_used;
-
- /* Dictionary version: globally unique, value change each time
- the dictionary is modified */
- uint64_t ma_version_tag;
-
- PyDictKeysObject *ma_keys;
-
- /* If ma_values is NULL, the table is "combined": keys and values
- are stored in ma_keys.
-
- If ma_values is not NULL, the table is splitted:
- keys are stored in ma_keys and values are stored in ma_values */
- PyObject **ma_values;
-} PyDictObject;
-
-typedef struct {
- PyObject_HEAD
- PyDictObject *dv_dict;
-} _PyDictViewObject;
-
-#endif /* Py_LIMITED_API */
-
PyAPI_DATA(PyTypeObject) PyDict_Type;
-PyAPI_DATA(PyTypeObject) PyDictIterKey_Type;
-PyAPI_DATA(PyTypeObject) PyDictIterValue_Type;
-PyAPI_DATA(PyTypeObject) PyDictIterItem_Type;
-PyAPI_DATA(PyTypeObject) PyDictRevIterKey_Type;
-PyAPI_DATA(PyTypeObject) PyDictRevIterItem_Type;
-PyAPI_DATA(PyTypeObject) PyDictRevIterValue_Type;
-PyAPI_DATA(PyTypeObject) PyDictKeys_Type;
-PyAPI_DATA(PyTypeObject) PyDictItems_Type;
-PyAPI_DATA(PyTypeObject) PyDictValues_Type;
#define PyDict_Check(op) \
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS)
#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
-#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type)
-#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type)
-#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type)
-/* This excludes Values, since they are not sets. */
-# define PyDictViewSet_Check(op) \
- (PyDictKeys_Check(op) || PyDictItems_Check(op))
-
PyAPI_FUNC(PyObject *) PyDict_New(void);
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
- Py_hash_t hash);
-#endif
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
- struct _Py_Identifier *key);
-PyAPI_FUNC(PyObject *) PyDict_SetDefault(
- PyObject *mp, PyObject *key, PyObject *defaultobj);
-#endif
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
- PyObject *item, Py_hash_t hash);
-#endif
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key,
- Py_hash_t hash);
-PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key,
- int (*predicate)(PyObject *value));
-#endif
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
PyAPI_FUNC(int) PyDict_Next(
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
-#ifndef Py_LIMITED_API
-PyDictKeysObject *_PyDict_NewKeysForClass(void);
-PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *);
-PyAPI_FUNC(int) _PyDict_Next(
- PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
-PyObject *_PyDictView_New(PyObject *, PyTypeObject *);
-#endif
PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
-#ifndef Py_LIMITED_API
-/* Get the number of items of a dictionary. */
-#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used)
-PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash);
-PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
-PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
-PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
-Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
-PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);
-PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *);
-PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *);
-PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
-#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
-
-PyAPI_FUNC(int) PyDict_ClearFreeList(void);
-#endif
/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
@@ -136,18 +42,8 @@ PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
dict.update(other) is equivalent to PyDict_Merge(dict, other, 1).
*/
PyAPI_FUNC(int) PyDict_Merge(PyObject *mp,
- PyObject *other,
- int override);
-
-#ifndef Py_LIMITED_API
-/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0,
- the first occurrence of a key wins, if override is 1, the last occurrence
- of a key wins, if override is 2, a KeyError with conflicting key as
- argument is raised.
-*/
-PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override);
-PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
-#endif
+ PyObject *other,
+ int override);
/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing
iterable objects of length 2. If override is true, the last occurrence
@@ -155,25 +51,41 @@ PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1).
*/
PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
- PyObject *seq2,
- int override);
+ PyObject *seq2,
+ int override);
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key);
-#endif /* !Py_LIMITED_API */
PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item);
-#endif /* !Py_LIMITED_API */
PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key);
-PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out);
+/* Dictionary (keys, values, items) views */
+
+PyAPI_DATA(PyTypeObject) PyDictKeys_Type;
+PyAPI_DATA(PyTypeObject) PyDictValues_Type;
+PyAPI_DATA(PyTypeObject) PyDictItems_Type;
+
+#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type)
+#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type)
+#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type)
+/* This excludes Values, since they are not sets. */
+# define PyDictViewSet_Check(op) \
+ (PyDictKeys_Check(op) || PyDictItems_Check(op))
+
+/* Dictionary (key, value, items) iterators */
-int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
-PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
+PyAPI_DATA(PyTypeObject) PyDictIterKey_Type;
+PyAPI_DATA(PyTypeObject) PyDictIterValue_Type;
+PyAPI_DATA(PyTypeObject) PyDictIterItem_Type;
+
+PyAPI_DATA(PyTypeObject) PyDictRevIterKey_Type;
+PyAPI_DATA(PyTypeObject) PyDictRevIterItem_Type;
+PyAPI_DATA(PyTypeObject) PyDictRevIterValue_Type;
+
+
+#ifndef Py_LIMITED_API
+# define Py_CPYTHON_DICTOBJECT_H
+# include "cpython/dictobject.h"
+# undef Py_CPYTHON_DICTOBJECT_H
#endif
#ifdef __cplusplus
1
0
https://github.com/python/cpython/commit/dd12aa0aea733820807ec4f99e4e476064…
commit: dd12aa0aea733820807ec4f99e4e476064a0ee41
branch: master
author: Victor Stinner <vstinner(a)redhat.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-27T00:12:05+01:00
summary:
bpo-35134: Create Include/cpython/pylifecycle.h (GH-10731)
Move pylifecycle.h code surrounded by "#ifndef Py_LIMITED_API"
to a new Include/cpython/pylifecycle.h header file.
files:
A Include/cpython/pylifecycle.h
M Include/pylifecycle.h
diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h
new file mode 100644
index 000000000000..3009c4f10d3a
--- /dev/null
+++ b/Include/cpython/pylifecycle.h
@@ -0,0 +1,99 @@
+#ifndef Py_CPYTHON_PYLIFECYCLE_H
+# error "this header file must not be included directly"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Only used by applications that embed the interpreter and need to
+ * override the standard encoding determination mechanism
+ */
+PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
+ const char *errors);
+
+/* PEP 432 Multi-phase initialization API (Private while provisional!) */
+
+PyAPI_FUNC(_PyInitError) _Py_InitializeCore(
+ PyInterpreterState **interp,
+ const _PyCoreConfig *);
+PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
+
+
+PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(
+ _PyMainInterpreterConfig *config,
+ const _PyCoreConfig *core_config);
+PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *);
+PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy(
+ _PyMainInterpreterConfig *config,
+ const _PyMainInterpreterConfig *config2);
+/* Used by _testcapi.get_main_config() */
+PyAPI_FUNC(PyObject*) _PyMainInterpreterConfig_AsDict(
+ const _PyMainInterpreterConfig *config);
+
+PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(
+ PyInterpreterState *interp,
+ const _PyMainInterpreterConfig *);
+
+/* Initialization and finalization */
+
+PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig(
+ const _PyCoreConfig *config);
+PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalInitError(_PyInitError err);
+
+/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
+ * exit functions.
+ */
+PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(PyObject *), PyObject *);
+
+/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */
+PyAPI_FUNC(void) _Py_RestoreSignals(void);
+
+PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
+
+PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *);
+
+PyAPI_FUNC(const char *) _Py_gitidentifier(void);
+PyAPI_FUNC(const char *) _Py_gitversion(void);
+
+/* Internal -- various one-time initializations */
+PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void);
+PyAPI_FUNC(_PyInitError) _PySys_BeginInit(PyObject **sysmod);
+PyAPI_FUNC(int) _PySys_EndInit(PyObject *sysdict, PyInterpreterState *interp);
+PyAPI_FUNC(_PyInitError) _PyImport_Init(PyInterpreterState *interp);
+PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod);
+PyAPI_FUNC(_PyInitError) _PyImportHooks_Init(void);
+PyAPI_FUNC(int) _PyFloat_Init(void);
+PyAPI_FUNC(int) PyByteArray_Init(void);
+PyAPI_FUNC(_PyInitError) _Py_HashRandomization_Init(const _PyCoreConfig *);
+
+/* Various internal finalizers */
+
+PyAPI_FUNC(void) PyMethod_Fini(void);
+PyAPI_FUNC(void) PyFrame_Fini(void);
+PyAPI_FUNC(void) PyCFunction_Fini(void);
+PyAPI_FUNC(void) PyDict_Fini(void);
+PyAPI_FUNC(void) PyTuple_Fini(void);
+PyAPI_FUNC(void) PyList_Fini(void);
+PyAPI_FUNC(void) PySet_Fini(void);
+PyAPI_FUNC(void) PyBytes_Fini(void);
+PyAPI_FUNC(void) PyByteArray_Fini(void);
+PyAPI_FUNC(void) PyFloat_Fini(void);
+PyAPI_FUNC(void) PyOS_FiniInterrupts(void);
+PyAPI_FUNC(void) PySlice_Fini(void);
+PyAPI_FUNC(void) PyAsyncGen_Fini(void);
+
+PyAPI_FUNC(int) _Py_IsFinalizing(void);
+
+/* Random */
+PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size);
+PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size);
+
+/* Legacy locale support */
+PyAPI_FUNC(void) _Py_CoerceLegacyLocale(int warn);
+PyAPI_FUNC(int) _Py_LegacyLocaleDetected(void);
+PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
index 93fb26b43fe8..5419bc943240 100644
--- a/Include/pylifecycle.h
+++ b/Include/pylifecycle.h
@@ -7,47 +7,10 @@
extern "C" {
#endif
-#ifndef Py_LIMITED_API
-/* Only used by applications that embed the interpreter and need to
- * override the standard encoding determination mechanism
- */
-PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
- const char *errors);
-#endif
-
-
-#ifndef Py_LIMITED_API
-/* PEP 432 Multi-phase initialization API (Private while provisional!) */
-PyAPI_FUNC(_PyInitError) _Py_InitializeCore(
- PyInterpreterState **interp,
- const _PyCoreConfig *);
-PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
-
-
-PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(
- _PyMainInterpreterConfig *config,
- const _PyCoreConfig *core_config);
-PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *);
-PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy(
- _PyMainInterpreterConfig *config,
- const _PyMainInterpreterConfig *config2);
-/* Used by _testcapi.get_main_config() */
-PyAPI_FUNC(PyObject*) _PyMainInterpreterConfig_AsDict(
- const _PyMainInterpreterConfig *config);
-
-PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(
- PyInterpreterState *interp,
- const _PyMainInterpreterConfig *);
-#endif
/* Initialization and finalization */
PyAPI_FUNC(void) Py_Initialize(void);
PyAPI_FUNC(void) Py_InitializeEx(int);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig(
- const _PyCoreConfig *config);
-PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalInitError(_PyInitError err);
-#endif
PyAPI_FUNC(void) Py_Finalize(void);
PyAPI_FUNC(int) Py_FinalizeEx(void);
PyAPI_FUNC(int) Py_IsInitialized(void);
@@ -60,20 +23,10 @@ PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *);
/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
* exit functions.
*/
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(PyObject *), PyObject *);
-#endif
PyAPI_FUNC(int) Py_AtExit(void (*func)(void));
PyAPI_FUNC(void) _Py_NO_RETURN Py_Exit(int);
-/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _Py_RestoreSignals(void);
-
-PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
-#endif
-
/* Bootstrap __main__ (defined in Modules/main.c) */
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
@@ -84,9 +37,6 @@ PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *);
PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *);
-#endif
PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void);
PyAPI_FUNC(wchar_t *) Py_GetPrefix(void);
@@ -103,43 +53,6 @@ PyAPI_FUNC(const char *) Py_GetPlatform(void);
PyAPI_FUNC(const char *) Py_GetCopyright(void);
PyAPI_FUNC(const char *) Py_GetCompiler(void);
PyAPI_FUNC(const char *) Py_GetBuildInfo(void);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(const char *) _Py_gitidentifier(void);
-PyAPI_FUNC(const char *) _Py_gitversion(void);
-#endif
-
-/* Internal -- various one-time initializations */
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void);
-PyAPI_FUNC(_PyInitError) _PySys_BeginInit(PyObject **sysmod);
-PyAPI_FUNC(int) _PySys_EndInit(PyObject *sysdict, PyInterpreterState *interp);
-PyAPI_FUNC(_PyInitError) _PyImport_Init(PyInterpreterState *interp);
-PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod);
-PyAPI_FUNC(_PyInitError) _PyImportHooks_Init(void);
-PyAPI_FUNC(int) _PyFloat_Init(void);
-PyAPI_FUNC(int) PyByteArray_Init(void);
-PyAPI_FUNC(_PyInitError) _Py_HashRandomization_Init(const _PyCoreConfig *);
-#endif
-
-/* Various internal finalizers */
-
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) PyMethod_Fini(void);
-PyAPI_FUNC(void) PyFrame_Fini(void);
-PyAPI_FUNC(void) PyCFunction_Fini(void);
-PyAPI_FUNC(void) PyDict_Fini(void);
-PyAPI_FUNC(void) PyTuple_Fini(void);
-PyAPI_FUNC(void) PyList_Fini(void);
-PyAPI_FUNC(void) PySet_Fini(void);
-PyAPI_FUNC(void) PyBytes_Fini(void);
-PyAPI_FUNC(void) PyByteArray_Fini(void);
-PyAPI_FUNC(void) PyFloat_Fini(void);
-PyAPI_FUNC(void) PyOS_FiniInterrupts(void);
-PyAPI_FUNC(void) PySlice_Fini(void);
-PyAPI_FUNC(void) PyAsyncGen_Fini(void);
-
-PyAPI_FUNC(int) _Py_IsFinalizing(void);
-#endif /* !Py_LIMITED_API */
/* Signals */
typedef void (*PyOS_sighandler_t)(int);
@@ -147,16 +60,9 @@ PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int);
PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t);
#ifndef Py_LIMITED_API
-/* Random */
-PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size);
-PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size);
-#endif /* !Py_LIMITED_API */
-
-/* Legacy locale support */
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _Py_CoerceLegacyLocale(int warn);
-PyAPI_FUNC(int) _Py_LegacyLocaleDetected(void);
-PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category);
+# define Py_CPYTHON_PYLIFECYCLE_H
+# include "cpython/pylifecycle.h"
+# undef Py_CPYTHON_PYLIFECYCLE_H
#endif
#ifdef __cplusplus
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
bpo-35308: Fix regression where BROWSER env var is not respected. (GH-10693)
by Miss Islington (bot) 26 Nov '18
by Miss Islington (bot) 26 Nov '18
26 Nov '18
https://github.com/python/cpython/commit/2a37f013ec81099a6156160ce66803b260…
commit: 2a37f013ec81099a6156160ce66803b2609bb7f4
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-26T13:49:28-08:00
summary:
bpo-35308: Fix regression where BROWSER env var is not respected. (GH-10693)
Regression introduced in e3ce695 and 25b804a, where the old parameter
update_tryorder to _synthesize was first ignored, then given the opposite
value in the attempt to fix bpo-31014.
(cherry picked from commit 8c281ed403fd915284d5bba2405d7c47f8195066)
Co-authored-by: Zhiming Wang <i(a)zhimingwang.org>
files:
A Misc/NEWS.d/next/Library/2018-11-24-10-33-42.bpo-35308.9--2iy.rst
M Lib/test/test_webbrowser.py
M Lib/webbrowser.py
diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py
index 71f2e27467ee..519a9432abe0 100644
--- a/Lib/test/test_webbrowser.py
+++ b/Lib/test/test_webbrowser.py
@@ -309,6 +309,24 @@ def test_environment(self):
webbrowser = support.import_fresh_module('webbrowser')
webbrowser.get()
+ def test_environment_preferred(self):
+ webbrowser = support.import_fresh_module('webbrowser')
+ try:
+ webbrowser.get()
+ least_preferred_browser = webbrowser.get(webbrowser._tryorder[-1]).name
+ except (webbrowser.Error, AttributeError, IndexError) as err:
+ self.skipTest(str(err))
+
+ with support.EnvironmentVarGuard() as env:
+ env["BROWSER"] = least_preferred_browser
+ webbrowser = support.import_fresh_module('webbrowser')
+ self.assertEqual(webbrowser.get().name, least_preferred_browser)
+
+ with support.EnvironmentVarGuard() as env:
+ env["BROWSER"] = sys.executable
+ webbrowser = support.import_fresh_module('webbrowser')
+ self.assertEqual(webbrowser.get().name, sys.executable)
+
if __name__=='__main__':
unittest.main()
diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py
index 1e27c83fd947..82bff835fdd0 100755
--- a/Lib/webbrowser.py
+++ b/Lib/webbrowser.py
@@ -86,7 +86,7 @@ def open_new_tab(url):
return open(url, 2)
-def _synthesize(browser, *, preferred=True):
+def _synthesize(browser, *, preferred=False):
"""Attempt to synthesize a controller base on existing controllers.
This is useful to create a controller when a user specifies a path to
@@ -563,7 +563,7 @@ def register_standard_browsers():
# and prepend to _tryorder
for cmdline in userchoices:
if cmdline != '':
- cmd = _synthesize(cmdline, preferred=False)
+ cmd = _synthesize(cmdline, preferred=True)
if cmd[1] is None:
register(cmdline, None, GenericBrowser(cmdline), preferred=True)
diff --git a/Misc/NEWS.d/next/Library/2018-11-24-10-33-42.bpo-35308.9--2iy.rst b/Misc/NEWS.d/next/Library/2018-11-24-10-33-42.bpo-35308.9--2iy.rst
new file mode 100644
index 000000000000..a33fe2e4812b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-11-24-10-33-42.bpo-35308.9--2iy.rst
@@ -0,0 +1,2 @@
+Fix regression in ``webbrowser`` where default browsers may be preferred
+over browsers in the ``BROWSER`` environment variable.
1
0
https://github.com/python/cpython/commit/4060283fcec7bb2bde4eb3c42b0a6ec99c…
commit: 4060283fcec7bb2bde4eb3c42b0a6ec99cf1d391
branch: master
author: Victor Stinner <vstinner(a)redhat.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-26T22:42:04+01:00
summary:
bpo-35134: Create Include/cpython/abstract.h (GH-10728)
Move abstract.h code surrounded by "#ifndef Py_LIMITED_API"
to a new Include/cpython/abstract.h header file.
files:
A Include/cpython/abstract.h
M Include/abstract.h
diff --git a/Include/abstract.h b/Include/abstract.h
index 85550a34ca26..79002a76a8c8 100644
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -138,9 +138,6 @@ extern "C" {
#ifdef PY_SSIZE_T_CLEAN
# define PyObject_CallFunction _PyObject_CallFunction_SizeT
# define PyObject_CallMethod _PyObject_CallMethod_SizeT
-# ifndef Py_LIMITED_API
-# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT
-# endif /* !Py_LIMITED_API */
#endif
@@ -155,123 +152,6 @@ extern "C" {
PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable,
PyObject *args, PyObject *kwargs);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject*) _PyStack_AsTuple(
- PyObject *const *stack,
- Py_ssize_t nargs);
-
-PyAPI_FUNC(PyObject*) _PyStack_AsTupleSlice(
- PyObject *const *stack,
- Py_ssize_t nargs,
- Py_ssize_t start,
- Py_ssize_t end);
-
-/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
- format to a Python dictionary ("kwargs" dict).
-
- The type of kwnames keys is not checked. The final function getting
- arguments is responsible to check if all keys are strings, for example using
- PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
-
- Duplicate keys are merged using the last value. If duplicate keys must raise
- an exception, the caller is responsible to implement an explicit keys on
- kwnames. */
-PyAPI_FUNC(PyObject *) _PyStack_AsDict(
- PyObject *const *values,
- PyObject *kwnames);
-
-/* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple).
-
- Return 0 on success, raise an exception and return -1 on error.
-
- Write the new stack into *p_stack. If *p_stack is differen than args, it
- must be released by PyMem_Free().
-
- The stack uses borrowed references.
-
- The type of keyword keys is not checked, these checks should be done
- later (ex: _PyArg_ParseStackAndKeywords). */
-PyAPI_FUNC(int) _PyStack_UnpackDict(
- PyObject *const *args,
- Py_ssize_t nargs,
- PyObject *kwargs,
- PyObject *const **p_stack,
- PyObject **p_kwnames);
-
-/* Suggested size (number of positional arguments) for arrays of PyObject*
- allocated on a C stack to avoid allocating memory on the heap memory. Such
- array is used to pass positional arguments to call functions of the
- _PyObject_FastCall() family.
-
- The size is chosen to not abuse the C stack and so limit the risk of stack
- overflow. The size is also chosen to allow using the small stack for most
- function calls of the Python standard library. On 64-bit CPU, it allocates
- 40 bytes on the stack. */
-#define _PY_FASTCALL_SMALL_STACK 5
-
-/* Return 1 if callable supports FASTCALL calling convention for positional
- arguments: see _PyObject_FastCallDict() and _PyObject_FastCallKeywords() */
-PyAPI_FUNC(int) _PyObject_HasFastCall(PyObject *callable);
-
-/* Call the callable object 'callable' with the "fast call" calling convention:
- args is a C array for positional arguments (nargs is the number of
- positional arguments), kwargs is a dictionary for keyword arguments.
-
- If nargs is equal to zero, args can be NULL. kwargs can be NULL.
- nargs must be greater or equal to zero.
-
- Return the result on success. Raise an exception on return NULL on
- error. */
-PyAPI_FUNC(PyObject *) _PyObject_FastCallDict(
- PyObject *callable,
- PyObject *const *args,
- Py_ssize_t nargs,
- PyObject *kwargs);
-
-/* Call the callable object 'callable' with the "fast call" calling convention:
- args is a C array for positional arguments followed by values of
- keyword arguments. Keys of keyword arguments are stored as a tuple
- of strings in kwnames. nargs is the number of positional parameters at
- the beginning of stack. The size of kwnames gives the number of keyword
- values in the stack after positional arguments.
-
- kwnames must only contains str strings, no subclass, and all keys must
- be unique.
-
- If nargs is equal to zero and there is no keyword argument (kwnames is
- NULL or its size is zero), args can be NULL.
-
- Return the result on success. Raise an exception and return NULL on
- error. */
-PyAPI_FUNC(PyObject *) _PyObject_FastCallKeywords(
- PyObject *callable,
- PyObject *const *args,
- Py_ssize_t nargs,
- PyObject *kwnames);
-
-#define _PyObject_FastCall(func, args, nargs) \
- _PyObject_FastCallDict((func), (args), (nargs), NULL)
-
-#define _PyObject_CallNoArg(func) \
- _PyObject_FastCallDict((func), NULL, 0, NULL)
-
-PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
- PyObject *callable,
- PyObject *obj,
- PyObject *args,
- PyObject *kwargs);
-
-PyAPI_FUNC(PyObject *) _PyObject_FastCall_Prepend(
- PyObject *callable,
- PyObject *obj,
- PyObject *const *args,
- Py_ssize_t nargs);
-
-PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable,
- PyObject *result,
- const char *where);
-#endif /* Py_LIMITED_API */
-
/* Call a callable Python object 'callable', with arguments given by the
tuple 'args'. If no arguments are needed, then 'args' can be *NULL*.
@@ -309,14 +189,6 @@ PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj,
const char *name,
const char *format, ...);
-#ifndef Py_LIMITED_API
-/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
- as the method name. */
-PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
- _Py_Identifier *name,
- const char *format, ...);
-#endif /* !Py_LIMITED_API */
-
PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable,
const char *format,
...);
@@ -326,13 +198,6 @@ PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *obj,
const char *format,
...);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj,
- _Py_Identifier *name,
- const char *format,
- ...);
-#endif /* !Py_LIMITED_API */
-
/* Call a callable Python object 'callable' with a variable number of C
arguments. The C arguments are provided as PyObject* values, terminated
by a NULL.
@@ -357,13 +222,6 @@ PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs(
PyObject *name,
...);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
- PyObject *obj,
- struct _Py_Identifier *name,
- ...);
-#endif /* !Py_LIMITED_API */
-
/* Implemented elsewhere:
@@ -418,16 +276,6 @@ PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o);
PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o);
#define PyObject_Length PyObject_Size
-
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
-
-/* Guess the size of object 'o' using len(o) or o.__length_hint__().
- If neither of those return a non-negative value, then return the default
- value. If one of the calls fails, this function returns -1. */
-PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
-#endif
-
/* Return element of 'o' corresponding to the object 'key'. Return NULL
on failure.
@@ -505,78 +353,6 @@ PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj,
/* === New Buffer API ============================================ */
-#ifndef Py_LIMITED_API
-
-/* Return 1 if the getbuffer function is available, otherwise return 0. */
-#define PyObject_CheckBuffer(obj) \
- (((obj)->ob_type->tp_as_buffer != NULL) && \
- ((obj)->ob_type->tp_as_buffer->bf_getbuffer != NULL))
-
-/* This is a C-API version of the getbuffer function call. It checks
- to make sure object has the required function pointer and issues the
- call.
-
- Returns -1 and raises an error on failure and returns 0 on success. */
-PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
- int flags);
-
-/* Get the memory area pointed to by the indices for the buffer given.
- Note that view->ndim is the assumed size of indices. */
-PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices);
-
-/* Return the implied itemsize of the data-format area from a
- struct-style description. */
-PyAPI_FUNC(int) PyBuffer_SizeFromFormat(const char *);
-
-/* Implementation in memoryobject.c */
-PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view,
- Py_ssize_t len, char order);
-
-PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf,
- Py_ssize_t len, char order);
-
-/* Copy len bytes of data from the contiguous chunk of memory
- pointed to by buf into the buffer exported by obj. Return
- 0 on success and return -1 and raise a PyBuffer_Error on
- error (i.e. the object does not have a buffer interface or
- it is not working).
-
- If fort is 'F', then if the object is multi-dimensional,
- then the data will be copied into the array in
- Fortran-style (first dimension varies the fastest). If
- fort is 'C', then the data will be copied into the array
- in C-style (last dimension varies the fastest). If fort
- is 'A', then it does not matter and the copy will be made
- in whatever way is more efficient. */
-PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src);
-
-/* Copy the data from the src buffer to the buffer of destination. */
-PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort);
-
-/*Fill the strides array with byte-strides of a contiguous
- (Fortran-style if fort is 'F' or C-style otherwise)
- array of the given shape with the given number of bytes
- per element. */
-PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims,
- Py_ssize_t *shape,
- Py_ssize_t *strides,
- int itemsize,
- char fort);
-
-/* Fills in a buffer-info structure correctly for an exporter
- that can only share a contiguous chunk of memory of
- "unsigned bytes" of the given length.
-
- Returns 0 on success and -1 (with raising an error) on error. */
-PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf,
- Py_ssize_t len, int readonly,
- int flags);
-
-/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */
-PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view);
-
-#endif /* Py_LIMITED_API */
-
/* Takes an arbitrary object and returns the result of calling
obj.__format__(format_spec). */
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj,
@@ -594,11 +370,6 @@ PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *);
This function always succeeds. */
PyAPI_FUNC(int) PyIter_Check(PyObject *);
-#ifndef Py_LIMITED_API
-#define PyIter_Check(obj) \
- ((obj)->ob_type->tp_iternext != NULL && \
- (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented)
-#endif
/* Takes an iterator object and calls its tp_iternext slot,
returning the next value.
@@ -719,11 +490,6 @@ PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2);
/* Returns 1 if obj is an index integer (has the nb_index slot of the
tp_as_number structure filled in), and 0 otherwise. */
PyAPI_FUNC(int) PyIndex_Check(PyObject *);
-#ifndef Py_LIMITED_API
-#define PyIndex_Check(obj) \
- ((obj)->ob_type->tp_as_number != NULL && \
- (obj)->ob_type->tp_as_number->nb_index != NULL)
-#endif
/* Returns the object 'o' converted to a Python int, or NULL with an exception
raised on failure. */
@@ -930,13 +696,6 @@ PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m);
#define PySequence_Fast_GET_ITEM(o, i)\
(PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i))
-/* Assume tp_as_sequence and sq_item exist and that 'i' does not
- need to be corrected for a negative index. */
-#ifndef Py_LIMITED_API
-#define PySequence_ITEM(o, i)\
- ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
-#endif
-
/* Return a pointer to the underlying item array for
an object retured by PySequence_Fast */
#define PySequence_Fast_ITEMS(sf) \
@@ -956,27 +715,6 @@ PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value);
Use __contains__ if possible, else _PySequence_IterSearch(). */
PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob);
-#ifndef Py_LIMITED_API
-#define PY_ITERSEARCH_COUNT 1
-#define PY_ITERSEARCH_INDEX 2
-#define PY_ITERSEARCH_CONTAINS 3
-
-/* Iterate over seq.
-
- Result depends on the operation:
-
- PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if
- error.
- PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of
- obj in seq; set ValueError and return -1 if none found;
- also return -1 on error.
- PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on
- error. */
-PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
- PyObject *obj, int operation);
-#endif
-
-
/* For DLL-level backwards compatibility */
#undef PySequence_In
/* Determine if the sequence 'o' contains 'value'. If an item in 'o' is equal
@@ -1095,26 +833,11 @@ PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass);
/* issubclass(object, typeorclass) */
PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass);
-
#ifndef Py_LIMITED_API
-PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
-
-PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
-
-PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
-
-PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
-
-/* For internal use by buffer API functions */
-PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
- const Py_ssize_t *shape);
-PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
- const Py_ssize_t *shape);
-
-/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
-PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
-#endif /* !Py_LIMITED_API */
-
+# define Py_CPYTHON_ABSTRACTOBJECT_H
+# include "cpython/abstract.h"
+# undef Py_CPYTHON_ABSTRACTOBJECT_H
+#endif
#ifdef __cplusplus
}
diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h
new file mode 100644
index 000000000000..0e002659f6bf
--- /dev/null
+++ b/Include/cpython/abstract.h
@@ -0,0 +1,281 @@
+#ifndef Py_CPYTHON_ABSTRACTOBJECT_H
+# error "this header file must not be included directly"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* === Object Protocol ================================================== */
+
+#ifdef PY_SSIZE_T_CLEAN
+# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT
+#endif
+
+PyAPI_FUNC(PyObject*) _PyStack_AsTuple(
+ PyObject *const *stack,
+ Py_ssize_t nargs);
+
+PyAPI_FUNC(PyObject*) _PyStack_AsTupleSlice(
+ PyObject *const *stack,
+ Py_ssize_t nargs,
+ Py_ssize_t start,
+ Py_ssize_t end);
+
+/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
+ format to a Python dictionary ("kwargs" dict).
+
+ The type of kwnames keys is not checked. The final function getting
+ arguments is responsible to check if all keys are strings, for example using
+ PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
+
+ Duplicate keys are merged using the last value. If duplicate keys must raise
+ an exception, the caller is responsible to implement an explicit keys on
+ kwnames. */
+PyAPI_FUNC(PyObject *) _PyStack_AsDict(
+ PyObject *const *values,
+ PyObject *kwnames);
+
+/* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple).
+
+ Return 0 on success, raise an exception and return -1 on error.
+
+ Write the new stack into *p_stack. If *p_stack is differen than args, it
+ must be released by PyMem_Free().
+
+ The stack uses borrowed references.
+
+ The type of keyword keys is not checked, these checks should be done
+ later (ex: _PyArg_ParseStackAndKeywords). */
+PyAPI_FUNC(int) _PyStack_UnpackDict(
+ PyObject *const *args,
+ Py_ssize_t nargs,
+ PyObject *kwargs,
+ PyObject *const **p_stack,
+ PyObject **p_kwnames);
+
+/* Suggested size (number of positional arguments) for arrays of PyObject*
+ allocated on a C stack to avoid allocating memory on the heap memory. Such
+ array is used to pass positional arguments to call functions of the
+ _PyObject_FastCall() family.
+
+ The size is chosen to not abuse the C stack and so limit the risk of stack
+ overflow. The size is also chosen to allow using the small stack for most
+ function calls of the Python standard library. On 64-bit CPU, it allocates
+ 40 bytes on the stack. */
+#define _PY_FASTCALL_SMALL_STACK 5
+
+/* Return 1 if callable supports FASTCALL calling convention for positional
+ arguments: see _PyObject_FastCallDict() and _PyObject_FastCallKeywords() */
+PyAPI_FUNC(int) _PyObject_HasFastCall(PyObject *callable);
+
+/* Call the callable object 'callable' with the "fast call" calling convention:
+ args is a C array for positional arguments (nargs is the number of
+ positional arguments), kwargs is a dictionary for keyword arguments.
+
+ If nargs is equal to zero, args can be NULL. kwargs can be NULL.
+ nargs must be greater or equal to zero.
+
+ Return the result on success. Raise an exception on return NULL on
+ error. */
+PyAPI_FUNC(PyObject *) _PyObject_FastCallDict(
+ PyObject *callable,
+ PyObject *const *args,
+ Py_ssize_t nargs,
+ PyObject *kwargs);
+
+/* Call the callable object 'callable' with the "fast call" calling convention:
+ args is a C array for positional arguments followed by values of
+ keyword arguments. Keys of keyword arguments are stored as a tuple
+ of strings in kwnames. nargs is the number of positional parameters at
+ the beginning of stack. The size of kwnames gives the number of keyword
+ values in the stack after positional arguments.
+
+ kwnames must only contains str strings, no subclass, and all keys must
+ be unique.
+
+ If nargs is equal to zero and there is no keyword argument (kwnames is
+ NULL or its size is zero), args can be NULL.
+
+ Return the result on success. Raise an exception and return NULL on
+ error. */
+PyAPI_FUNC(PyObject *) _PyObject_FastCallKeywords(
+ PyObject *callable,
+ PyObject *const *args,
+ Py_ssize_t nargs,
+ PyObject *kwnames);
+
+#define _PyObject_FastCall(func, args, nargs) \
+ _PyObject_FastCallDict((func), (args), (nargs), NULL)
+
+#define _PyObject_CallNoArg(func) \
+ _PyObject_FastCallDict((func), NULL, 0, NULL)
+
+PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
+ PyObject *callable,
+ PyObject *obj,
+ PyObject *args,
+ PyObject *kwargs);
+
+PyAPI_FUNC(PyObject *) _PyObject_FastCall_Prepend(
+ PyObject *callable,
+ PyObject *obj,
+ PyObject *const *args,
+ Py_ssize_t nargs);
+
+PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable,
+ PyObject *result,
+ const char *where);
+
+/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
+ as the method name. */
+PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
+ _Py_Identifier *name,
+ const char *format, ...);
+
+PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj,
+ _Py_Identifier *name,
+ const char *format,
+ ...);
+
+PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
+ PyObject *obj,
+ struct _Py_Identifier *name,
+ ...);
+
+PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
+
+/* Guess the size of object 'o' using len(o) or o.__length_hint__().
+ If neither of those return a non-negative value, then return the default
+ value. If one of the calls fails, this function returns -1. */
+PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
+
+/* === New Buffer API ============================================ */
+
+/* Return 1 if the getbuffer function is available, otherwise return 0. */
+#define PyObject_CheckBuffer(obj) \
+ (((obj)->ob_type->tp_as_buffer != NULL) && \
+ ((obj)->ob_type->tp_as_buffer->bf_getbuffer != NULL))
+
+/* This is a C-API version of the getbuffer function call. It checks
+ to make sure object has the required function pointer and issues the
+ call.
+
+ Returns -1 and raises an error on failure and returns 0 on success. */
+PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
+ int flags);
+
+/* Get the memory area pointed to by the indices for the buffer given.
+ Note that view->ndim is the assumed size of indices. */
+PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices);
+
+/* Return the implied itemsize of the data-format area from a
+ struct-style description. */
+PyAPI_FUNC(int) PyBuffer_SizeFromFormat(const char *);
+
+/* Implementation in memoryobject.c */
+PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view,
+ Py_ssize_t len, char order);
+
+PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf,
+ Py_ssize_t len, char order);
+
+/* Copy len bytes of data from the contiguous chunk of memory
+ pointed to by buf into the buffer exported by obj. Return
+ 0 on success and return -1 and raise a PyBuffer_Error on
+ error (i.e. the object does not have a buffer interface or
+ it is not working).
+
+ If fort is 'F', then if the object is multi-dimensional,
+ then the data will be copied into the array in
+ Fortran-style (first dimension varies the fastest). If
+ fort is 'C', then the data will be copied into the array
+ in C-style (last dimension varies the fastest). If fort
+ is 'A', then it does not matter and the copy will be made
+ in whatever way is more efficient. */
+PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src);
+
+/* Copy the data from the src buffer to the buffer of destination. */
+PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort);
+
+/*Fill the strides array with byte-strides of a contiguous
+ (Fortran-style if fort is 'F' or C-style otherwise)
+ array of the given shape with the given number of bytes
+ per element. */
+PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims,
+ Py_ssize_t *shape,
+ Py_ssize_t *strides,
+ int itemsize,
+ char fort);
+
+/* Fills in a buffer-info structure correctly for an exporter
+ that can only share a contiguous chunk of memory of
+ "unsigned bytes" of the given length.
+
+ Returns 0 on success and -1 (with raising an error) on error. */
+PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf,
+ Py_ssize_t len, int readonly,
+ int flags);
+
+/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */
+PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view);
+
+/* ==== Iterators ================================================ */
+
+#define PyIter_Check(obj) \
+ ((obj)->ob_type->tp_iternext != NULL && \
+ (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented)
+
+/* === Number Protocol ================================================== */
+
+#define PyIndex_Check(obj) \
+ ((obj)->ob_type->tp_as_number != NULL && \
+ (obj)->ob_type->tp_as_number->nb_index != NULL)
+
+/* === Sequence protocol ================================================ */
+
+/* Assume tp_as_sequence and sq_item exist and that 'i' does not
+ need to be corrected for a negative index. */
+#define PySequence_ITEM(o, i)\
+ ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
+
+#define PY_ITERSEARCH_COUNT 1
+#define PY_ITERSEARCH_INDEX 2
+#define PY_ITERSEARCH_CONTAINS 3
+
+/* Iterate over seq.
+
+ Result depends on the operation:
+
+ PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if
+ error.
+ PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of
+ obj in seq; set ValueError and return -1 if none found;
+ also return -1 on error.
+ PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on
+ error. */
+PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
+ PyObject *obj, int operation);
+
+/* === Mapping protocol ================================================= */
+
+PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
+
+PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
+
+PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
+
+PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
+
+/* For internal use by buffer API functions */
+PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
+ const Py_ssize_t *shape);
+PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
+ const Py_ssize_t *shape);
+
+/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
+PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
+
+#ifdef __cplusplus
+}
+#endif
1
0
![](https://secure.gravatar.com/avatar/cc7737cd64a84f1b5c61a160798e97ee.jpg?s=120&d=mm&r=g)
bpo-35308: Fix regression where BROWSER env var is not respected. (GH-10693)
by Serhiy Storchaka 26 Nov '18
by Serhiy Storchaka 26 Nov '18
26 Nov '18
https://github.com/python/cpython/commit/8c281ed403fd915284d5bba2405d7c47f8…
commit: 8c281ed403fd915284d5bba2405d7c47f8195066
branch: master
author: Zhiming Wang <i(a)zhimingwang.org>
committer: Serhiy Storchaka <storchaka(a)gmail.com>
date: 2018-11-26T23:29:45+02:00
summary:
bpo-35308: Fix regression where BROWSER env var is not respected. (GH-10693)
Regression introduced in e3ce695 and 25b804a, where the old parameter
update_tryorder to _synthesize was first ignored, then given the opposite
value in the attempt to fix bpo-31014.
files:
A Misc/NEWS.d/next/Library/2018-11-24-10-33-42.bpo-35308.9--2iy.rst
M Lib/test/test_webbrowser.py
M Lib/webbrowser.py
diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py
index 71f2e27467ee..519a9432abe0 100644
--- a/Lib/test/test_webbrowser.py
+++ b/Lib/test/test_webbrowser.py
@@ -309,6 +309,24 @@ def test_environment(self):
webbrowser = support.import_fresh_module('webbrowser')
webbrowser.get()
+ def test_environment_preferred(self):
+ webbrowser = support.import_fresh_module('webbrowser')
+ try:
+ webbrowser.get()
+ least_preferred_browser = webbrowser.get(webbrowser._tryorder[-1]).name
+ except (webbrowser.Error, AttributeError, IndexError) as err:
+ self.skipTest(str(err))
+
+ with support.EnvironmentVarGuard() as env:
+ env["BROWSER"] = least_preferred_browser
+ webbrowser = support.import_fresh_module('webbrowser')
+ self.assertEqual(webbrowser.get().name, least_preferred_browser)
+
+ with support.EnvironmentVarGuard() as env:
+ env["BROWSER"] = sys.executable
+ webbrowser = support.import_fresh_module('webbrowser')
+ self.assertEqual(webbrowser.get().name, sys.executable)
+
if __name__=='__main__':
unittest.main()
diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py
index 1e27c83fd947..82bff835fdd0 100755
--- a/Lib/webbrowser.py
+++ b/Lib/webbrowser.py
@@ -86,7 +86,7 @@ def open_new_tab(url):
return open(url, 2)
-def _synthesize(browser, *, preferred=True):
+def _synthesize(browser, *, preferred=False):
"""Attempt to synthesize a controller base on existing controllers.
This is useful to create a controller when a user specifies a path to
@@ -563,7 +563,7 @@ def register_standard_browsers():
# and prepend to _tryorder
for cmdline in userchoices:
if cmdline != '':
- cmd = _synthesize(cmdline, preferred=False)
+ cmd = _synthesize(cmdline, preferred=True)
if cmd[1] is None:
register(cmdline, None, GenericBrowser(cmdline), preferred=True)
diff --git a/Misc/NEWS.d/next/Library/2018-11-24-10-33-42.bpo-35308.9--2iy.rst b/Misc/NEWS.d/next/Library/2018-11-24-10-33-42.bpo-35308.9--2iy.rst
new file mode 100644
index 000000000000..a33fe2e4812b
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-11-24-10-33-42.bpo-35308.9--2iy.rst
@@ -0,0 +1,2 @@
+Fix regression in ``webbrowser`` where default browsers may be preferred
+over browsers in the ``BROWSER`` environment variable.
1
0
https://github.com/python/cpython/commit/5a8c240b1d97de0bd6ced2a57cbcf26da1…
commit: 5a8c240b1d97de0bd6ced2a57cbcf26da19c1fcc
branch: master
author: Victor Stinner <vstinner(a)redhat.com>
committer: GitHub <noreply(a)github.com>
date: 2018-11-26T22:11:25+01:00
summary:
bpo-35134: Add Include/cpython/pyerrors.h (GH-10727)
Move pyerrors.h code surrounded by "#ifndef Py_LIMITED_API"
to a new Include/cpython/pyerrors.h header file.
files:
A Include/cpython/pyerrors.h
M Include/pyerrors.h
diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h
new file mode 100644
index 000000000000..0b43d7528b97
--- /dev/null
+++ b/Include/cpython/pyerrors.h
@@ -0,0 +1,176 @@
+#ifndef Py_CPYTHON_ERRORS_H
+# error "this header file must not be included directly"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Error objects */
+
+/* PyException_HEAD defines the initial segment of every exception class. */
+#define PyException_HEAD PyObject_HEAD PyObject *dict;\
+ PyObject *args; PyObject *traceback;\
+ PyObject *context; PyObject *cause;\
+ char suppress_context;
+
+typedef struct {
+ PyException_HEAD
+} PyBaseExceptionObject;
+
+typedef struct {
+ PyException_HEAD
+ PyObject *msg;
+ PyObject *filename;
+ PyObject *lineno;
+ PyObject *offset;
+ PyObject *text;
+ PyObject *print_file_and_line;
+} PySyntaxErrorObject;
+
+typedef struct {
+ PyException_HEAD
+ PyObject *msg;
+ PyObject *name;
+ PyObject *path;
+} PyImportErrorObject;
+
+typedef struct {
+ PyException_HEAD
+ PyObject *encoding;
+ PyObject *object;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ PyObject *reason;
+} PyUnicodeErrorObject;
+
+typedef struct {
+ PyException_HEAD
+ PyObject *code;
+} PySystemExitObject;
+
+typedef struct {
+ PyException_HEAD
+ PyObject *myerrno;
+ PyObject *strerror;
+ PyObject *filename;
+ PyObject *filename2;
+#ifdef MS_WINDOWS
+ PyObject *winerror;
+#endif
+ Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */
+} PyOSErrorObject;
+
+typedef struct {
+ PyException_HEAD
+ PyObject *value;
+} PyStopIterationObject;
+
+/* Compatibility typedefs */
+typedef PyOSErrorObject PyEnvironmentErrorObject;
+#ifdef MS_WINDOWS
+typedef PyOSErrorObject PyWindowsErrorObject;
+#endif
+
+/* Error handling definitions */
+
+PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *);
+_PyErr_StackItem *_PyErr_GetTopmostException(PyThreadState *tstate);
+
+/* Context manipulation (PEP 3134) */
+
+PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
+
+/* */
+
+#define PyExceptionClass_Name(x) (((PyTypeObject*)(x))->tp_name)
+
+/* Convenience functions */
+
+#ifdef MS_WINDOWS
+PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename(
+ PyObject *, const Py_UNICODE *) Py_DEPRECATED(3.3);
+#endif /* MS_WINDOWS */
+
+/* Like PyErr_Format(), but saves current exception as __context__ and
+ __cause__.
+ */
+PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause(
+ PyObject *exception,
+ const char *format, /* ASCII-encoded string */
+ ...
+ );
+
+#ifdef MS_WINDOWS
+/* XXX redeclare to use WSTRING */
+PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename(
+ int, const Py_UNICODE *) Py_DEPRECATED(3.3);
+
+PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename(
+ PyObject *,int, const Py_UNICODE *) Py_DEPRECATED(3.3);
+#endif
+
+/* In exceptions.c */
+
+/* Helper that attempts to replace the current exception with one of the
+ * same type but with a prefix added to the exception text. The resulting
+ * exception description looks like:
+ *
+ * prefix (exc_type: original_exc_str)
+ *
+ * Only some exceptions can be safely replaced. If the function determines
+ * it isn't safe to perform the replacement, it will leave the original
+ * unmodified exception in place.
+ *
+ * Returns a borrowed reference to the new exception (if any), NULL if the
+ * existing exception was left in place.
+ */
+PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause(
+ const char *prefix_format, /* ASCII-encoded string */
+ ...
+ );
+
+/* In signalmodule.c */
+
+int PySignal_SetWakeupFd(int fd);
+
+/* Support for adding program text to SyntaxErrors */
+
+PyAPI_FUNC(void) PyErr_SyntaxLocationObject(
+ PyObject *filename,
+ int lineno,
+ int col_offset);
+
+PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject(
+ PyObject *filename,
+ int lineno);
+
+/* Create a UnicodeEncodeError object */
+PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create(
+ const char *encoding, /* UTF-8 encoded string */
+ const Py_UNICODE *object,
+ Py_ssize_t length,
+ Py_ssize_t start,
+ Py_ssize_t end,
+ const char *reason /* UTF-8 encoded string */
+ ) Py_DEPRECATED(3.3);
+
+/* Create a UnicodeTranslateError object */
+PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create(
+ const Py_UNICODE *object,
+ Py_ssize_t length,
+ Py_ssize_t start,
+ Py_ssize_t end,
+ const char *reason /* UTF-8 encoded string */
+ ) Py_DEPRECATED(3.3);
+PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create(
+ PyObject *object,
+ Py_ssize_t start,
+ Py_ssize_t end,
+ const char *reason /* UTF-8 encoded string */
+ );
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Include/pyerrors.h b/Include/pyerrors.h
index 808e0def06b4..efe1c49d2d08 100644
--- a/Include/pyerrors.h
+++ b/Include/pyerrors.h
@@ -4,82 +4,10 @@
extern "C" {
#endif
-/* Error objects */
-
-#ifndef Py_LIMITED_API
-/* PyException_HEAD defines the initial segment of every exception class. */
-#define PyException_HEAD PyObject_HEAD PyObject *dict;\
- PyObject *args; PyObject *traceback;\
- PyObject *context; PyObject *cause;\
- char suppress_context;
-
-typedef struct {
- PyException_HEAD
-} PyBaseExceptionObject;
-
-typedef struct {
- PyException_HEAD
- PyObject *msg;
- PyObject *filename;
- PyObject *lineno;
- PyObject *offset;
- PyObject *text;
- PyObject *print_file_and_line;
-} PySyntaxErrorObject;
-
-typedef struct {
- PyException_HEAD
- PyObject *msg;
- PyObject *name;
- PyObject *path;
-} PyImportErrorObject;
-
-typedef struct {
- PyException_HEAD
- PyObject *encoding;
- PyObject *object;
- Py_ssize_t start;
- Py_ssize_t end;
- PyObject *reason;
-} PyUnicodeErrorObject;
-
-typedef struct {
- PyException_HEAD
- PyObject *code;
-} PySystemExitObject;
-
-typedef struct {
- PyException_HEAD
- PyObject *myerrno;
- PyObject *strerror;
- PyObject *filename;
- PyObject *filename2;
-#ifdef MS_WINDOWS
- PyObject *winerror;
-#endif
- Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */
-} PyOSErrorObject;
-
-typedef struct {
- PyException_HEAD
- PyObject *value;
-} PyStopIterationObject;
-
-/* Compatibility typedefs */
-typedef PyOSErrorObject PyEnvironmentErrorObject;
-#ifdef MS_WINDOWS
-typedef PyOSErrorObject PyWindowsErrorObject;
-#endif
-#endif /* !Py_LIMITED_API */
-
/* Error handling definitions */
PyAPI_FUNC(void) PyErr_SetNone(PyObject *);
PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *);
-_PyErr_StackItem *_PyErr_GetTopmostException(PyThreadState *tstate);
-#endif
PyAPI_FUNC(void) PyErr_SetString(
PyObject *exception,
const char *string /* decoded from utf-8 */
@@ -129,9 +57,6 @@ PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *);
/* Context manipulation (PEP 3134) */
PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *);
PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
-#endif
/* */
@@ -143,9 +68,6 @@ PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
PyType_FastSubclass((x)->ob_type, Py_TPFLAGS_BASE_EXC_SUBCLASS)
PyAPI_FUNC(const char *) PyExceptionClass_Name(PyObject *);
-#ifndef Py_LIMITED_API
-#define PyExceptionClass_Name(x) (((PyTypeObject*)(x))->tp_name)
-#endif
#define PyExceptionInstance_Class(x) ((PyObject*)((x)->ob_type))
@@ -253,10 +175,6 @@ PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename(
PyObject *exc,
const char *filename /* decoded from the filesystem encoding */
);
-#if defined(MS_WINDOWS) && !defined(Py_LIMITED_API)
-PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename(
- PyObject *, const Py_UNICODE *) Py_DEPRECATED(3.3);
-#endif /* MS_WINDOWS */
PyAPI_FUNC(PyObject *) PyErr_Format(
PyObject *exception,
@@ -270,27 +188,11 @@ PyAPI_FUNC(PyObject *) PyErr_FormatV(
va_list vargs);
#endif
-#ifndef Py_LIMITED_API
-/* Like PyErr_Format(), but saves current exception as __context__ and
- __cause__.
- */
-PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause(
- PyObject *exception,
- const char *format, /* ASCII-encoded string */
- ...
- );
-#endif
-
#ifdef MS_WINDOWS
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename(
int ierr,
const char *filename /* decoded from the filesystem encoding */
);
-#ifndef Py_LIMITED_API
-/* XXX redeclare to use WSTRING */
-PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename(
- int, const Py_UNICODE *) Py_DEPRECATED(3.3);
-#endif
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int);
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject(
PyObject *,int, PyObject *);
@@ -303,10 +205,6 @@ PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename(
int ierr,
const char *filename /* decoded from the filesystem encoding */
);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename(
- PyObject *,int, const Py_UNICODE *) Py_DEPRECATED(3.3);
-#endif
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int);
#endif /* MS_WINDOWS */
@@ -333,37 +231,11 @@ PyAPI_FUNC(PyObject *) PyErr_NewExceptionWithDoc(
const char *name, const char *doc, PyObject *base, PyObject *dict);
PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *);
-/* In exceptions.c */
-#ifndef Py_LIMITED_API
-/* Helper that attempts to replace the current exception with one of the
- * same type but with a prefix added to the exception text. The resulting
- * exception description looks like:
- *
- * prefix (exc_type: original_exc_str)
- *
- * Only some exceptions can be safely replaced. If the function determines
- * it isn't safe to perform the replacement, it will leave the original
- * unmodified exception in place.
- *
- * Returns a borrowed reference to the new exception (if any), NULL if the
- * existing exception was left in place.
- */
-PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause(
- const char *prefix_format, /* ASCII-encoded string */
- ...
- );
-#endif
-
/* In signalmodule.c */
PyAPI_FUNC(int) PyErr_CheckSignals(void);
PyAPI_FUNC(void) PyErr_SetInterrupt(void);
-/* In signalmodule.c */
-#ifndef Py_LIMITED_API
-int PySignal_SetWakeupFd(int fd);
-#endif
-
/* Support for adding program text to SyntaxErrors */
PyAPI_FUNC(void) PyErr_SyntaxLocation(
const char *filename, /* decoded from the filesystem encoding */
@@ -372,20 +244,9 @@ PyAPI_FUNC(void) PyErr_SyntaxLocationEx(
const char *filename, /* decoded from the filesystem encoding */
int lineno,
int col_offset);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(void) PyErr_SyntaxLocationObject(
- PyObject *filename,
- int lineno,
- int col_offset);
-#endif
PyAPI_FUNC(PyObject *) PyErr_ProgramText(
const char *filename, /* decoded from the filesystem encoding */
int lineno);
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject(
- PyObject *filename,
- int lineno);
-#endif
/* The following functions are used to create and modify unicode
exceptions from C */
@@ -400,35 +261,6 @@ PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_Create(
const char *reason /* UTF-8 encoded string */
);
-/* create a UnicodeEncodeError object */
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create(
- const char *encoding, /* UTF-8 encoded string */
- const Py_UNICODE *object,
- Py_ssize_t length,
- Py_ssize_t start,
- Py_ssize_t end,
- const char *reason /* UTF-8 encoded string */
- ) Py_DEPRECATED(3.3);
-#endif
-
-/* create a UnicodeTranslateError object */
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create(
- const Py_UNICODE *object,
- Py_ssize_t length,
- Py_ssize_t start,
- Py_ssize_t end,
- const char *reason /* UTF-8 encoded string */
- ) Py_DEPRECATED(3.3);
-PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create(
- PyObject *object,
- Py_ssize_t start,
- Py_ssize_t end,
- const char *reason /* UTF-8 encoded string */
- );
-#endif
-
/* get the encoding attribute */
PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *);
PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetEncoding(PyObject *);
@@ -502,6 +334,12 @@ PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...)
PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
Py_GCC_ATTRIBUTE((format(printf, 3, 0)));
+#ifndef Py_LIMITED_API
+# define Py_CPYTHON_ERRORS_H
+# include "cpython/pyerrors.h"
+# undef Py_CPYTHON_ERRORS_H
+#endif
+
#ifdef __cplusplus
}
#endif
1
0