single: lock, interpreter
The Python interpreter is not fully thread safe. In order to support
-multi-threaded Python programs, there's a global lock that must be held by the
-current thread before it can safely access Python objects. Without the lock,
-even the simplest operations could cause problems in a multi-threaded program:
-for example, when two threads simultaneously increment the reference count of
-the same object, the reference count could end up being incremented only once
-instead of twice.
+multi-threaded Python programs, there's a global lock, called the :dfn:`global
+interpreter lock` or :dfn:`GIL`, that must be held by the current thread before
+it can safely access Python objects. Without the lock, even the simplest
+operations could cause problems in a multi-threaded program: for example, when
+two threads simultaneously increment the reference count of the same object, the
+reference count could end up being incremented only once instead of twice.
.. index:: single: setcheckinterval() (in module sys)
interpreter lock has the following simple structure::
Save the thread state in a local variable.
- Release the interpreter lock.
+ Release the global interpreter lock.
...Do some blocking I/O operation...
- Reacquire the interpreter lock.
+ Reacquire the global interpreter lock.
Restore the thread state from the local variable.
This is so common that a pair of macros exists to simplify it::
hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the
block. Another advantage of using these two macros is that when Python is
compiled without thread support, they are defined empty, thus saving the thread
-state and lock manipulations.
+state and GIL manipulations.
When thread support is enabled, the block above expands to the following code::
saves and restores the value of the global variable :cdata:`errno`, since the
lock manipulation does not guarantee that :cdata:`errno` is left alone. Also,
when thread support is disabled, :cfunc:`PyEval_SaveThread` and
-:cfunc:`PyEval_RestoreThread` don't manipulate the lock; in this case,
+:cfunc:`PyEval_RestoreThread` don't manipulate the GIL; in this case,
:cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available.
This is done so that dynamically loaded extensions compiled with thread support
enabled can be loaded by an interpreter that was compiled with disabled thread
.. index:: module: thread
- When only the main thread exists, no lock operations are needed. This is a
+ When only the main thread exists, no GIL operations are needed. This is a
common situation (most Python programs do not use threads), and the lock
- operations slow the interpreter down a bit. Therefore, the lock is not created
- initially. This situation is equivalent to having acquired the lock: when
- there is only a single thread, all object accesses are safe. Therefore, when
- this function initializes the lock, it also acquires it. Before the Python
- :mod:`thread` module creates a new thread, knowing that either it has the lock
- or the lock hasn't been created yet, it calls :cfunc:`PyEval_InitThreads`. When
- this call returns, it is guaranteed that the lock has been created and that the
- calling thread has acquired it.
+ operations slow the interpreter down a bit. Therefore, the lock is not
+ created initially. This situation is equivalent to having acquired the lock:
+ when there is only a single thread, all object accesses are safe. Therefore,
+ when this function initializes the global interpreter lock, it also acquires
+ it. Before the Python :mod:`thread` module creates a new thread, knowing
+ that either it has the lock or the lock hasn't been created yet, it calls
+ :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that
+ the lock has been created and that the calling thread has acquired it.
It is **not** safe to call this function when it is unknown which thread (if
any) currently has the global interpreter lock.
.. cfunction:: int PyEval_ThreadsInitialized()
Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This
- function can be called without holding the lock, and therefore can be used to
+ function can be called without holding the GIL, and therefore can be used to
avoid calls to the locking API when running single-threaded. This function is
not available when thread support is disabled at compile time.
.. cfunction:: PyThreadState* PyEval_SaveThread()
- Release the interpreter lock (if it has been created and thread support is
- enabled) and reset the thread state to *NULL*, returning the previous thread
- state (which is not *NULL*). If the lock has been created, the current thread
- must have acquired it. (This function is available even when thread support is
- disabled at compile time.)
+ Release the global interpreter lock (if it has been created and thread
+ support is enabled) and reset the thread state to *NULL*, returning the
+ previous thread state (which is not *NULL*). If the lock has been created,
+ the current thread must have acquired it. (This function is available even
+ when thread support is disabled at compile time.)
.. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate)
- Acquire the interpreter lock (if it has been created and thread support is
- enabled) and set the thread state to *tstate*, which must not be *NULL*. If the
- lock has been created, the current thread must not have acquired it, otherwise
- deadlock ensues. (This function is available even when thread support is
- disabled at compile time.)
+ Acquire the global interpreter lock (if it has been created and thread
+ support is enabled) and set the thread state to *tstate*, which must not be
+ *NULL*. If the lock has been created, the current thread must not have
+ acquired it, otherwise deadlock ensues. (This function is available even
+ when thread support is disabled at compile time.)
.. cfunction:: void PyEval_ReInitThreads()
declaration. It is a no-op when thread support is disabled at compile time.
All of the following functions are only available when thread support is enabled
-at compile time, and must be called only when the interpreter lock has been
-created.
+at compile time, and must be called only when the global interpreter lock has
+been created.
.. cfunction:: PyInterpreterState* PyInterpreterState_New()
- Create a new interpreter state object. The interpreter lock need not be held,
- but may be held if it is necessary to serialize calls to this function.
+ Create a new interpreter state object. The global interpreter lock need not
+ be held, but may be held if it is necessary to serialize calls to this
+ function.
.. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp)
- Reset all information in an interpreter state object. The interpreter lock must
- be held.
+ Reset all information in an interpreter state object. The global interpreter
+ lock must be held.
.. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp)
- Destroy an interpreter state object. The interpreter lock need not be held.
- The interpreter state must have been reset with a previous call to
+ Destroy an interpreter state object. The global interpreter lock need not be
+ held. The interpreter state must have been reset with a previous call to
:cfunc:`PyInterpreterState_Clear`.
.. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp)
- Create a new thread state object belonging to the given interpreter object. The
- interpreter lock need not be held, but may be held if it is necessary to
- serialize calls to this function.
+ Create a new thread state object belonging to the given interpreter object.
+ The global interpreter lock need not be held, but may be held if it is
+ necessary to serialize calls to this function.
.. cfunction:: void PyThreadState_Clear(PyThreadState *tstate)
- Reset all information in a thread state object. The interpreter lock must be
- held.
+ Reset all information in a thread state object. The global interpreter lock
+ must be held.
.. cfunction:: void PyThreadState_Delete(PyThreadState *tstate)
- Destroy a thread state object. The interpreter lock need not be held. The
- thread state must have been reset with a previous call to
+ Destroy a thread state object. The global interpreter lock need not be held.
+ The thread state must have been reset with a previous call to
:cfunc:`PyThreadState_Clear`.
.. cfunction:: PyThreadState* PyThreadState_Get()
- Return the current thread state. The interpreter lock must be held. When the
- current thread state is *NULL*, this issues a fatal error (so that the caller
- needn't check for *NULL*).
+ Return the current thread state. The global interpreter lock must be held.
+ When the current thread state is *NULL*, this issues a fatal error (so that
+ the caller needn't check for *NULL*).
.. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate)
Swap the current thread state with the thread state given by the argument
- *tstate*, which may be *NULL*. The interpreter lock must be held.
+ *tstate*, which may be *NULL*. The global interpreter lock must be held.
.. cfunction:: PyObject* PyThreadState_GetDict()
.. cfunction:: PyGILState_STATE PyGILState_Ensure()
- Ensure that the current thread is ready to call the Python C API regardless of
- the current state of Python, or of its thread lock. This may be called as many
- times as desired by a thread as long as each call is matched with a call to
- :cfunc:`PyGILState_Release`. In general, other thread-related APIs may be used
- between :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls as long
- as the thread state is restored to its previous state before the Release(). For
- example, normal usage of the :cmacro:`Py_BEGIN_ALLOW_THREADS` and
- :cmacro:`Py_END_ALLOW_THREADS` macros is acceptable.
+ Ensure that the current thread is ready to call the Python C API regardless
+ of the current state of Python, or of the global interpreter lock. This may
+ be called as many times as desired by a thread as long as each call is
+ matched with a call to :cfunc:`PyGILState_Release`. In general, other
+ thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and
+ :cfunc:`PyGILState_Release` calls as long as the thread state is restored to
+ its previous state before the Release(). For example, normal usage of the
+ :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is
+ acceptable.
The return value is an opaque "handle" to the thread state when
:cfunc:`PyGILState_Ensure` was called, and must be passed to
.. warning::
- Handles cross-device moves on Unix using :func:`copy_file`. What about other
- systems???
+ Handles cross-device moves on Unix using :func:`copy_file`. What about
+ other systems?
.. function:: write_file(filename, contents)
For non-POSIX platforms, currently just returns ``sys.platform``.
- For MacOS X systems the OS version reflects the minimal version on which
+ For Mac OS X systems the OS version reflects the minimal version on which
binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET``
during the build of Python), not the OS version of the current system.
- For universal binary builds on MacOS X the architecture value reflects
+ For universal binary builds on Mac OS X the architecture value reflects
the univeral binary status instead of the architecture of the current
processor. For 32-bit universal binaries the architecture is ``fat``,
for 64-bit universal binaries the architecture is ``fat64``, and
for 4-way universal binaries the architecture is ``universal``.
- Examples of returned values on MacOS X:
+ Examples of returned values on Mac OS X:
* ``macosx-10.3-ppc``
associated. If this parameter is ``None`` or empty, the function retrieves the
value set by the :func:`SetValue` method for the key identified by *key*.
- Values in the registry have name, type, and data components. This method
+ Values in the registry have name, type, and data components. This method
retrieves the data for a key's first value that has a NULL name. But the
- underlying API call doesn't return the type, Lame Lame Lame, DO NOT USE THIS!!!
+ underlying API call doesn't return the type, so always use
+ :func:`QueryValueEx` if possible.
.. function:: QueryValueEx(key, value_name)
pair: HTTP; protocol
single: URL
single: httpd
-
-.. index::
module: SimpleHTTPServer
module: CGIHTTPServer
:mod:`CGIHTTPServer` modules.
The first class, :class:`HTTPServer`, is a :class:`SocketServer.TCPServer`
-subclass. It creates and listens at the HTTP socket, dispatching the requests
+subclass, and therefore implements the :class:`SocketServer.BaseServer`
+interface. It creates and listens at the HTTP socket, dispatching the requests
to a handler. Code to create and run the server looks like this::
def run(server_class=BaseHTTPServer.HTTPServer,
performed on the client's IP address.
+More examples
+-------------
+
+To create a server that doesn't run forever, but until some condition is
+fulfilled::
+
+ def run_while_true(server_class=BaseHTTPServer.HTTPServer,
+ handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
+ """
+ This assumes that keep_running() is a function of no arguments which
+ is tested initially and after each request. If its return value
+ is true, the server continues.
+ """
+ server_address = ('', 8000)
+ httpd = server_class(server_address, handler_class)
+ while keep_running():
+ httpd.handle_request()
+
+
.. seealso::
Module :mod:`CGIHTTPServer`
Extended request handler that supports CGI scripts.
Module :mod:`SimpleHTTPServer`
- Basic request handler that limits response to files actually under the document
- root.
+ Basic request handler that limits response to files actually under the
+ document root.
.. method:: map(func, iterable[, chunksize])
- A parallel equivalent of the :func:`map` builtin function. It blocks till
- the result is ready.
+ A parallel equivalent of the :func:`map` builtin function (it supports only
+ one *iterable* argument though). It blocks till the result is ready.
This method chops the iterable into a number of chunks which it submits to
the process pool as separate tasks. The (approximate) size of these
-
:mod:`os.path` --- Common pathname manipulations
================================================
.. module:: os.path
:synopsis: Operations on pathnames.
-
.. index:: single: path; operations
This module implements some useful functions on pathnames. To read or
:func:`splitunc` and :func:`ismount` do handle them correctly.
+.. note::
+
+ Since different operating systems have different path name conventions, there
+ are several versions of this module in the standard library. The
+ :mod:`os.path` module is always the path module suitable for the operating
+ system Python is running on, and therefore usable for local paths. However,
+ you can also import and use the individual modules if you want to manipulate
+ a path that is *always* in one of the different formats. They all have the
+ same interface:
+
+ * :mod:`posixpath` for UNIX-style paths
+ * :mod:`ntpath` for Windows paths
+ * :mod:`macpath` for old-style MacOS paths
+ * :mod:`os2emxpath` for OS/2 EMX paths
+
+
.. function:: abspath(path)
Return a normalized absolutized version of the pathname *path*. On most
.. function:: normcase(path)
- Normalize the case of a pathname. On Unix and MacOSX, this returns the path unchanged; on
- case-insensitive filesystems, it converts the path to lowercase. On Windows, it
- also converts forward slashes to backward slashes.
+ Normalize the case of a pathname. On Unix and Mac OS X, this returns the
+ path unchanged; on case-insensitive filesystems, it converts the path to
+ lowercase. On Windows, it also converts forward slashes to backward slashes.
.. function:: normpath(path)
``'ce'``, ``'java'``, ``'riscos'``.
-.. data:: path
-
- The corresponding operating system dependent standard module for pathname
- operations, such as :mod:`posixpath` or :mod:`ntpath`. Thus, given the proper
- imports, ``os.path.split(file)`` is equivalent to but more portable than
- ``posixpath.split(file)``. Note that this is also an importable module: it may
- be imported directly as :mod:`os.path`.
-
-
.. _os-procinfo:
Process Parameters
For :term:`new-style class`\es, if :meth:`__getstate__` returns a false
value, the :meth:`__setstate__` method will not be called.
+.. note::
+
+ At unpickling time, some methods like :meth:`__getattr__`,
+ :meth:`__getattribute__`, or :meth:`__setattr__` may be called upon the
+ instance. In case those methods rely on some internal invariant being
+ true, the type should implement either :meth:`__getinitargs__` or
+ :meth:`__getnewargs__` to establish such an invariant; otherwise, neither
+ :meth:`__new__` nor :meth:`__init__` will be called.
+
Pickling and unpickling extension types
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# as d was opened WITHOUT writeback=True, beware:
d['xx'] = range(4) # this works as expected, but...
- d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)!!!
+ d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)!
# having opened d without writeback=True, you need to code carefully:
temp = d['xx'] # extracts the copy
Server Objects
--------------
+.. class:: BaseServer
-.. function:: fileno()
+ This is the superclass of all Server objects in the module. It defines the
+ interface, given below, but does not implement most of the methods, which is
+ done in subclasses.
+
+
+.. method:: BaseServer.fileno()
Return an integer file descriptor for the socket on which the server is
listening. This function is most commonly passed to :func:`select.select`, to
allow monitoring multiple servers in the same process.
-.. function:: handle_request()
+.. method:: BaseServer.handle_request()
Process a single request. This function calls the following methods in
order: :meth:`get_request`, :meth:`verify_request`, and
will return.
-.. function:: serve_forever(poll_interval=0.5)
+.. method:: BaseServer.serve_forever(poll_interval=0.5)
Handle requests until an explicit :meth:`shutdown` request. Polls for
shutdown every *poll_interval* seconds.
-.. function:: shutdown()
+.. method:: BaseServer.shutdown()
Tells the :meth:`serve_forever` loop to stop and waits until it does.
.. versionadded:: 2.6
-.. data:: address_family
+.. attribute:: BaseServer.address_family
The family of protocols to which the server's socket belongs.
Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`.
-.. data:: RequestHandlerClass
+.. attribute:: BaseServer.RequestHandlerClass
The user-provided request handler class; an instance of this class is created
for each request.
-.. data:: server_address
+.. attribute:: BaseServer.server_address
The address on which the server is listening. The format of addresses varies
depending on the protocol family; see the documentation for the socket module
the address, and an integer port number: ``('127.0.0.1', 80)``, for example.
-.. data:: socket
+.. attribute:: BaseServer.socket
The socket object on which the server will listen for incoming requests.
+
The server classes support the following class variables:
.. XXX should class variables be covered before instance variables, or vice versa?
-
-.. data:: allow_reuse_address
+.. attribute:: BaseServer.allow_reuse_address
Whether the server will allow the reuse of an address. This defaults to
:const:`False`, and can be set in subclasses to change the policy.
-.. data:: request_queue_size
+.. attribute:: BaseServer.request_queue_size
The size of the request queue. If it takes a long time to process a single
request, any requests that arrive while the server is busy are placed into a
value is usually 5, but this can be overridden by subclasses.
-.. data:: socket_type
+.. attribute:: BaseServer.socket_type
The type of socket used by the server; :const:`socket.SOCK_STREAM` and
:const:`socket.SOCK_DGRAM` are two common values.
-.. data:: timeout
+
+.. attribute:: BaseServer.timeout
Timeout duration, measured in seconds, or :const:`None` if no timeout is
desired. If :meth:`handle_request` receives no incoming requests within the
timeout period, the :meth:`handle_timeout` method is called.
+
There are various server methods that can be overridden by subclasses of base
server classes like :class:`TCPServer`; these methods aren't useful to external
users of the server object.
.. XXX should the default implementations of these be documented, or should
it be assumed that the user will look at SocketServer.py?
-
-.. function:: finish_request()
+.. method:: BaseServer.finish_request()
Actually processes the request by instantiating :attr:`RequestHandlerClass` and
calling its :meth:`handle` method.
-.. function:: get_request()
+.. method:: BaseServer.get_request()
Must accept a request from the socket, and return a 2-tuple containing the *new*
socket object to be used to communicate with the client, and the client's
address.
-.. function:: handle_error(request, client_address)
+.. method:: BaseServer.handle_error(request, client_address)
This function is called if the :attr:`RequestHandlerClass`'s :meth:`handle`
method raises an exception. The default action is to print the traceback to
standard output and continue handling further requests.
-.. function:: handle_timeout()
+
+.. method:: BaseServer.handle_timeout()
This function is called when the :attr:`timeout` attribute has been set to a
value other than :const:`None` and the timeout period has passed with no
to collect the status of any child processes that have exited, while
in threading servers this method does nothing.
-.. function:: process_request(request, client_address)
+
+.. method:: BaseServer.process_request(request, client_address)
Calls :meth:`finish_request` to create an instance of the
:attr:`RequestHandlerClass`. If desired, this function can create a new process
or thread to handle the request; the :class:`ForkingMixIn` and
:class:`ThreadingMixIn` classes do this.
+
.. Is there any point in documenting the following two functions?
What would the purpose of overriding them be: initializing server
instance variables, adding new network families?
-
-.. function:: server_activate()
+.. method:: BaseServer.server_activate()
Called by the server's constructor to activate the server. The default behavior
just :meth:`listen`\ s to the server's socket. May be overridden.
-.. function:: server_bind()
+.. method:: BaseServer.server_bind()
Called by the server's constructor to bind the socket to the desired address.
May be overridden.
-.. function:: verify_request(request, client_address)
+.. method:: BaseServer.verify_request(request, client_address)
Must return a Boolean value; if the value is :const:`True`, the request will be
processed, and if it's :const:`False`, the request will be denied. This function
request.
-.. function:: finish()
+.. method:: RequestHandler.finish()
Called after the :meth:`handle` method to perform any clean-up actions
required. The default implementation does nothing. If :meth:`setup` or
:meth:`handle` raise an exception, this function will not be called.
-.. function:: handle()
+.. method:: RequestHandler.handle()
This function must do all the work required to service a request. The
default implementation does nothing. Several instance attributes are
data or return data to the client.
-.. function:: setup()
+.. method:: RequestHandler.setup()
Called before the :meth:`handle` method to perform any initialization actions
required. The default implementation does nothing.
under many window managers this will occur regardless of the setting of this
variable).
+ Note that on some platforms, trying to open a filename using this function,
+ may work and start the operating system's associated program. However, this
+ is neither supported nor portable.
+
.. versionchanged:: 2.5
*new* can now be 2.
set SVNROOT=http://svn.python.org/projects\r
if "%PYTHON%" EQU "" set PYTHON=..\pcbuild\python\r
if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe\r
+if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v\r
\r
if "%1" EQU "" goto help\r
if "%1" EQU "html" goto build\r
if not exist build\%1 mkdir build\%1\r
if not exist build\doctrees mkdir build\doctrees\r
cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%*\r
-if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp\r
+if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp\r
goto end\r
\r
:end\r
-"""plistlib.py -- a tool to generate and parse MacOSX .plist files.
+r"""plistlib.py -- a tool to generate and parse MacOSX .plist files.
The PropertyList (.plist) file format is a simple XML pickle supporting
basic object types, like dictionaries, lists, numbers and strings.
except KeyError:
return path
userhome = pwent.pw_dir
- userhome = userhome.rstrip('/')
+ userhome = userhome.rstrip('/') or userhome
return userhome + path[i:]
self.assert_(isinstance(posixpath.expanduser("~root/"), basestring))
self.assert_(isinstance(posixpath.expanduser("~foo/"), basestring))
+ orig_home = os.environ['HOME']
+ os.environ['HOME'] = '/'
+ self.assertEqual(posixpath.expanduser("~"), "/")
+ os.environ['HOME'] = orig_home
+
self.assertRaises(TypeError, posixpath.expanduser)
def test_expandvars(self):
import traceback
-try:
- raise KeyError
-except KeyError:
- type_, value, tb = sys.exc_info()
- file_ = StringIO()
- traceback_print(tb, file_)
- example_traceback = file_.getvalue()
-else:
- raise Error("unable to create test traceback string")
-
class TracebackCases(unittest.TestCase):
# For now, a very minimal set of tests. I want to be sure that
class TracebackFormatTests(unittest.TestCase):
- def test_traceback_indentation(self):
+ def test_traceback_format(self):
+ try:
+ raise KeyError('blah')
+ except KeyError:
+ type_, value, tb = sys.exc_info()
+ traceback_fmt = 'Traceback (most recent call last):\n' + \
+ ''.join(traceback.format_tb(tb))
+ file_ = StringIO()
+ traceback_print(tb, file_)
+ python_fmt = file_.getvalue()
+ else:
+ raise Error("unable to create test traceback string")
+
+ # Make sure that Python and the traceback module format the same thing
+ self.assertEquals(traceback_fmt, python_fmt)
+
# Make sure that the traceback is properly indented.
- tb_lines = example_traceback.splitlines()
+ tb_lines = python_fmt.splitlines()
self.assertEquals(len(tb_lines), 3)
banner, location, source_line = tb_lines
self.assert_(banner.startswith('Traceback'))
filename = co.co_filename
name = co.co_name
_print(file,
- ' File "%s", line %d, in %s' % (filename,lineno,name))
+ ' File "%s", line %d, in %s' % (filename, lineno, name))
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, f.f_globals)
if line: _print(file, ' ' + line.strip())
_print(file, 'Traceback (most recent call last):')
print_tb(tb, limit, file)
lines = format_exception_only(etype, value)
- for line in lines[:-1]:
- _print(file, line, ' ')
- _print(file, lines[-1], '')
+ for line in lines:
+ _print(file, line, '')
def format_exception(etype, value, tb, limit = None):
"""Format a stack trace and the exception information.
caretspace = ((c.isspace() and c or ' ') for c in caretspace)
# only three spaces to account for offset1 == pos 0
lines.append(' %s^\n' % ''.join(caretspace))
- value = msg
+ value = msg
lines.append(_format_final_exc_line(stype, value))
return lines
- xrange() is now registered as a Sequence.
+- Fix a problem in PyErr_NormalizeException that leads to "undetected errors"
+ when hitting the recursion limit under certain circumstances.
+
+- Issue #1665206: Remove the last eager import in _warnings.c and make it lazy.
+
- Issue #4034: Fix weird attribute error messages of the traceback object. (As a
result traceback.__members__ no longer exists.)
Library
-------
+- Issue 5471: Fix os.path.expanduser() for $HOME set to '/'.
+
+- Issue 1326077: fix the formatting of SyntaxErrors by the traceback module.
+
- Issue 1726172: fix IndexError in the case of and empty response in ftplib.
- In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on
self->detect_types = detect_types;
self->timeout = timeout;
(void)sqlite3_busy_timeout(self->db, (int)(timeout*1000));
-
+#ifdef WITH_THREAD
self->thread_ident = PyThread_get_thread_ident();
+#endif
self->check_same_thread = check_same_thread;
self->function_pinboard = PyDict_New();
PyObject* py_func;
PyObject* py_retval = NULL;
+#ifdef WITH_THREAD
PyGILState_STATE threadstate;
threadstate = PyGILState_Ensure();
+#endif
py_func = (PyObject*)sqlite3_user_data(context);
_sqlite3_result_error(context, "user-defined function raised exception", -1);
}
+#ifdef WITH_THREAD
PyGILState_Release(threadstate);
+#endif
}
static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params)
PyObject** aggregate_instance;
PyObject* stepmethod = NULL;
+#ifdef WITH_THREAD
PyGILState_STATE threadstate;
threadstate = PyGILState_Ensure();
+#endif
aggregate_class = (PyObject*)sqlite3_user_data(context);
Py_XDECREF(stepmethod);
Py_XDECREF(function_result);
+#ifdef WITH_THREAD
PyGILState_Release(threadstate);
+#endif
}
void _pysqlite_final_callback(sqlite3_context* context)
PyObject** aggregate_instance;
PyObject* aggregate_class;
+#ifdef WITH_THREAD
PyGILState_STATE threadstate;
threadstate = PyGILState_Ensure();
+#endif
aggregate_class = (PyObject*)sqlite3_user_data(context);
Py_XDECREF(*aggregate_instance);
Py_XDECREF(function_result);
+#ifdef WITH_THREAD
PyGILState_Release(threadstate);
+#endif
}
void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self)
{
PyObject *ret;
int rc;
+#ifdef WITH_THREAD
PyGILState_STATE gilstate;
gilstate = PyGILState_Ensure();
+#endif
ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source);
if (!ret) {
Py_DECREF(ret);
}
+#ifdef WITH_THREAD
PyGILState_Release(gilstate);
+#endif
return rc;
}
{
int rc;
PyObject *ret;
+#ifdef WITH_THREAD
PyGILState_STATE gilstate;
gilstate = PyGILState_Ensure();
+#endif
ret = PyObject_CallFunction((PyObject*)user_arg, "");
if (!ret) {
Py_DECREF(ret);
}
+#ifdef WITH_THREAD
PyGILState_Release(gilstate);
+#endif
return rc;
}
int pysqlite_check_thread(pysqlite_Connection* self)
{
+#ifdef WITH_THREAD
if (self->check_same_thread) {
if (PyThread_get_thread_ident() != self->thread_ident) {
PyErr_Format(pysqlite_ProgrammingError,
}
}
-
+#endif
return 1;
}
PyObject* callback = (PyObject*)context;
PyObject* string1 = 0;
PyObject* string2 = 0;
+#ifdef WITH_THREAD
PyGILState_STATE gilstate;
-
+#endif
PyObject* retval = NULL;
int result = 0;
-
+#ifdef WITH_THREAD
gilstate = PyGILState_Ensure();
+#endif
if (PyErr_Occurred()) {
goto finally;
Py_XDECREF(string1);
Py_XDECREF(string2);
Py_XDECREF(retval);
-
+#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-
+#endif
return result;
}
* threads have already been initialized.
* (see pybsddb-users mailing list post on 2002-08-07)
*/
+#ifdef WITH_THREAD
PyEval_InitThreads();
+#endif
error:
if (PyErr_Occurred())
{
if (self->ob_exports > 0) {
PyErr_SetString(PyExc_SystemError,
- "deallocated bytearray object has exported buffers");
+ "deallocated bytearray object has exported buffers");
PyErr_Print();
}
if (self->ob_bytes != 0) {
/* Try to determine the length of the argument. 32 is abitrary. */
buf_size = _PyObject_LengthHint(arg, 32);
- if (buf_size == -1) {
- Py_DECREF(it);
- return NULL;
- }
+ if (buf_size == -1) {
+ Py_DECREF(it);
+ return NULL;
+ }
bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
if (bytes_obj == NULL)
static PyObject *
bytes_sizeof(PyByteArrayObject *self)
{
- Py_ssize_t res;
+ Py_ssize_t res;
- res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
- return PyInt_FromSsize_t(res);
+ res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
+ return PyInt_FromSsize_t(res);
}
static PySequenceMethods bytes_as_sequence = {
if (op == NULL)
fprintf(stderr, "NULL\n");
else {
+#ifdef WITH_THREAD
PyGILState_STATE gil;
+#endif
fprintf(stderr, "object : ");
+#ifdef WITH_THREAD
gil = PyGILState_Ensure();
+#endif
(void)PyObject_Print(op, stderr, 0);
+#ifdef WITH_THREAD
PyGILState_Release(gil);
+#endif
/* XXX(twouters) cast refcount to long until %zd is
universally available */
fprintf(stderr, "\n"
tstate = PyThreadState_GET();
if (++tstate->recursion_depth > Py_GetRecursionLimit()) {
--tstate->recursion_depth;
- PyErr_SetObject(PyExc_RuntimeError, PyExc_RecursionErrorInst);
+ /* throw away the old exception... */
+ Py_DECREF(*exc);
+ Py_DECREF(*val);
+ /* ... and use the recursion error instead */
+ *exc = PyExc_RuntimeError;
+ *val = PyExc_RecursionErrorInst;
+ Py_INCREF(*exc);
+ Py_INCREF(*val);
+ /* just keeping the old traceback */
return;
}
PyErr_NormalizeException(exc, val, tb);
!= size) {
Py_DECREF(s);
return converterr(
- "(encoded string without NULL bytes)",
+ "encoded string without NULL bytes",
arg, msgbuf, bufsize);
}
*buffer = PyMem_NEW(char, size + 1);