summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/init.rst116
-rw-r--r--Doc/distutils/apiref.rst10
-rw-r--r--Doc/library/_winreg.rst5
-rw-r--r--Doc/library/basehttpserver.rst28
-rw-r--r--Doc/library/multiprocessing.rst4
-rw-r--r--Doc/library/os.path.rst24
-rw-r--r--Doc/library/os.rst9
-rw-r--r--Doc/library/pickle.rst9
-rw-r--r--Doc/library/shelve.rst2
-rw-r--r--Doc/library/socketserver.rst61
-rw-r--r--Doc/library/webbrowser.rst4
-rw-r--r--Doc/make.bat3
-rw-r--r--Lib/plistlib.py2
-rw-r--r--Lib/posixpath.py2
-rw-r--r--Lib/test/test_posixpath.py5
-rw-r--r--Lib/test/test_traceback.py29
-rw-r--r--Lib/traceback.py9
-rw-r--r--Misc/NEWS9
-rw-r--r--Modules/_sqlite/connection.c36
-rw-r--r--Modules/_sqlite/module.c2
-rw-r--r--Objects/bytearrayobject.c16
-rw-r--r--Objects/object.c6
-rw-r--r--Python/errors.c10
-rw-r--r--Python/getargs.c2
24 files changed, 255 insertions, 148 deletions
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index 077efbc..c2971e9 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -394,12 +394,12 @@ Thread State and the Global Interpreter Lock
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)
@@ -428,9 +428,9 @@ This is easy enough in most cases. Most code manipulating the global
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::
@@ -447,7 +447,7 @@ The :cmacro:`Py_BEGIN_ALLOW_THREADS` macro opens a new block and declares a
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::
@@ -479,7 +479,7 @@ There are some subtle differences; in particular, :cfunc:`PyEval_RestoreThread`
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
@@ -562,16 +562,16 @@ supports the creation of additional interpreters (using
.. 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.
@@ -582,7 +582,7 @@ supports the creation of additional interpreters (using
.. 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.
@@ -622,20 +622,20 @@ supports the creation of additional interpreters (using
.. 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()
@@ -679,60 +679,61 @@ example usage in the Python source distribution.
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()
@@ -763,14 +764,15 @@ created.
.. 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
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index b4887cf..20bb31a 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -1067,8 +1067,8 @@ This module contains some utility functions for operating on individual files.
.. 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)
@@ -1108,17 +1108,17 @@ other utility module.
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``
diff --git a/Doc/library/_winreg.rst b/Doc/library/_winreg.rst
index e9c0fa7..7876f85 100644
--- a/Doc/library/_winreg.rst
+++ b/Doc/library/_winreg.rst
@@ -252,9 +252,10 @@ This module offers the following functions:
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)
diff --git a/Doc/library/basehttpserver.rst b/Doc/library/basehttpserver.rst
index 64446f4..4662b4f 100644
--- a/Doc/library/basehttpserver.rst
+++ b/Doc/library/basehttpserver.rst
@@ -15,8 +15,6 @@
pair: HTTP; protocol
single: URL
single: httpd
-
-.. index::
module: SimpleHTTPServer
module: CGIHTTPServer
@@ -26,7 +24,8 @@ functioning Web servers. See the :mod:`SimpleHTTPServer` and
: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,
@@ -269,12 +268,31 @@ to a handler. Code to create and run the server looks like this::
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.
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index f6e223a..d39e649 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -1537,8 +1537,8 @@ with the :class:`Pool` class.
.. 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
diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst
index bc2220d..0e7f376 100644
--- a/Doc/library/os.path.rst
+++ b/Doc/library/os.path.rst
@@ -1,11 +1,9 @@
-
: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
@@ -18,6 +16,22 @@ write files see :func:`open`, and for accessing the filesystem see the
: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
@@ -190,9 +204,9 @@ write files see :func:`open`, and for accessing the filesystem see the
.. 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)
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index 309fac2..4d8fc4c 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -46,15 +46,6 @@ the :mod:`os` module, but using them is of course a threat to portability!
``'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
diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst
index a99dc86..f6b7ae4 100644
--- a/Doc/library/pickle.rst
+++ b/Doc/library/pickle.rst
@@ -458,6 +458,15 @@ Pickling and unpickling normal class instances
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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst
index b5e7eae..1afa19b 100644
--- a/Doc/library/shelve.rst
+++ b/Doc/library/shelve.rst
@@ -148,7 +148,7 @@ object)::
# 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
diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst
index a4f181b..078f216 100644
--- a/Doc/library/socketserver.rst
+++ b/Doc/library/socketserver.rst
@@ -129,15 +129,21 @@ another way to manage this.
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
@@ -148,32 +154,32 @@ Server Objects
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
@@ -181,22 +187,22 @@ Server Objects
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
@@ -205,17 +211,19 @@ The server classes support the following class variables:
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.
@@ -223,27 +231,27 @@ 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
@@ -251,31 +259,32 @@ users of the server object.
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
@@ -291,14 +300,14 @@ override any of the following methods. A new instance is created for each
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
@@ -317,7 +326,7 @@ request.
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.
diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst
index 4d819e6..56aba5a 100644
--- a/Doc/library/webbrowser.rst
+++ b/Doc/library/webbrowser.rst
@@ -55,6 +55,10 @@ The following functions are defined:
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.
diff --git a/Doc/make.bat b/Doc/make.bat
index 33d354c..2e2a2de 100644
--- a/Doc/make.bat
+++ b/Doc/make.bat
@@ -4,6 +4,7 @@ setlocal
set SVNROOT=http://svn.python.org/projects
if "%PYTHON%" EQU "" set PYTHON=..\pcbuild\python
if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe
+if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v
if "%1" EQU "" goto help
if "%1" EQU "html" goto build
@@ -51,7 +52,7 @@ if not exist build mkdir build
if not exist build\%1 mkdir build\%1
if not exist build\doctrees mkdir build\doctrees
cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%*
-if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp
+if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp
goto end
:end
diff --git a/Lib/plistlib.py b/Lib/plistlib.py
index 31d1e75..05a6ae8 100644
--- a/Lib/plistlib.py
+++ b/Lib/plistlib.py
@@ -1,4 +1,4 @@
-"""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.
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index 9fa53d0..4f3519b 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -262,7 +262,7 @@ def expanduser(path):
except KeyError:
return path
userhome = pwent.pw_dir
- userhome = userhome.rstrip('/')
+ userhome = userhome.rstrip('/') or userhome
return userhome + path[i:]
diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py
index 46ac067..e6f750a 100644
--- a/Lib/test/test_posixpath.py
+++ b/Lib/test/test_posixpath.py
@@ -345,6 +345,11 @@ class PosixPathTest(unittest.TestCase):
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):
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 0708f81..5cd08ee 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -8,16 +8,6 @@ from test.test_support import run_unittest, is_jython, Error
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
@@ -162,9 +152,24 @@ def test():
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'))
diff --git a/Lib/traceback.py b/Lib/traceback.py
index 3d877ee..ea3d51a 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -64,7 +64,7 @@ def print_tb(tb, limit=None, file=None):
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())
@@ -124,9 +124,8 @@ def print_exception(etype, value, tb, limit=None, file=None):
_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.
@@ -195,7 +194,7 @@ def format_exception_only(etype, value):
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
diff --git a/Misc/NEWS b/Misc/NEWS
index f518fa9..0addc8b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -14,6 +14,11 @@ Core and Builtins
- 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.)
@@ -95,6 +100,10 @@ Core and Builtins
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
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 9d6952e..8aa0882 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -168,8 +168,9 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
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();
@@ -585,9 +586,11 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
PyObject* py_func;
PyObject* py_retval = NULL;
+#ifdef WITH_THREAD
PyGILState_STATE threadstate;
threadstate = PyGILState_Ensure();
+#endif
py_func = (PyObject*)sqlite3_user_data(context);
@@ -609,7 +612,9 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
_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)
@@ -620,9 +625,11 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_
PyObject** aggregate_instance;
PyObject* stepmethod = NULL;
+#ifdef WITH_THREAD
PyGILState_STATE threadstate;
threadstate = PyGILState_Ensure();
+#endif
aggregate_class = (PyObject*)sqlite3_user_data(context);
@@ -669,7 +676,9 @@ error:
Py_XDECREF(stepmethod);
Py_XDECREF(function_result);
+#ifdef WITH_THREAD
PyGILState_Release(threadstate);
+#endif
}
void _pysqlite_final_callback(sqlite3_context* context)
@@ -678,9 +687,11 @@ 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);
@@ -708,7 +719,9 @@ error:
Py_XDECREF(*aggregate_instance);
Py_XDECREF(function_result);
+#ifdef WITH_THREAD
PyGILState_Release(threadstate);
+#endif
}
void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self)
@@ -803,9 +816,11 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co
{
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) {
@@ -825,7 +840,9 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co
Py_DECREF(ret);
}
+#ifdef WITH_THREAD
PyGILState_Release(gilstate);
+#endif
return rc;
}
@@ -833,9 +850,11 @@ static int _progress_handler(void* user_arg)
{
int rc;
PyObject *ret;
+#ifdef WITH_THREAD
PyGILState_STATE gilstate;
gilstate = PyGILState_Ensure();
+#endif
ret = PyObject_CallFunction((PyObject*)user_arg, "");
if (!ret) {
@@ -852,7 +871,9 @@ static int _progress_handler(void* user_arg)
Py_DECREF(ret);
}
+#ifdef WITH_THREAD
PyGILState_Release(gilstate);
+#endif
return rc;
}
@@ -907,6 +928,7 @@ PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, Py
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,
@@ -917,7 +939,7 @@ int pysqlite_check_thread(pysqlite_Connection* self)
}
}
-
+#endif
return 1;
}
@@ -1139,12 +1161,14 @@ pysqlite_collation_callback(
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;
@@ -1173,9 +1197,9 @@ finally:
Py_XDECREF(string1);
Py_XDECREF(string2);
Py_XDECREF(retval);
-
+#ifdef WITH_THREAD
PyGILState_Release(gilstate);
-
+#endif
return result;
}
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c
index cd28609..c16b7c7 100644
--- a/Modules/_sqlite/module.c
+++ b/Modules/_sqlite/module.c
@@ -445,7 +445,9 @@ PyMODINIT_FUNC init_sqlite3(void)
* 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())
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 34d9137..b5dd81b 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -1093,7 +1093,7 @@ bytes_dealloc(PyByteArrayObject *self)
{
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) {
@@ -2679,10 +2679,10 @@ bytes_extend(PyByteArrayObject *self, PyObject *arg)
/* 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)
@@ -3122,10 +3122,10 @@ Returns the size of B in memory, in bytes");
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 = {
diff --git a/Objects/object.c b/Objects/object.c
index daee6fb..e2ec93b 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -331,11 +331,17 @@ void _PyObject_Dump(PyObject* op)
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"
diff --git a/Python/errors.c b/Python/errors.c
index c88a190..615da19 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -219,7 +219,15 @@ finally:
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);
diff --git a/Python/getargs.c b/Python/getargs.c
index 544948b..d24857d 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -1108,7 +1108,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
!= 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);