diff options
author | Georg Brandl <georg@python.org> | 2009-04-05 21:26:31 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2009-04-05 21:26:31 (GMT) |
commit | e9b912164b9ef4b2cc4c350bcf4e212b2e9b3b73 (patch) | |
tree | 7a5418f065b1d7c07a396634b8d89145250bff3f | |
parent | 958980190cd04b819d592dd6654df72cd1df3edd (diff) | |
download | cpython-e9b912164b9ef4b2cc4c350bcf4e212b2e9b3b73.zip cpython-e9b912164b9ef4b2cc4c350bcf4e212b2e9b3b73.tar.gz cpython-e9b912164b9ef4b2cc4c350bcf4e212b2e9b3b73.tar.bz2 |
Merged revisions 71058,71149-71150,71212,71214-71216,71222,71225,71234,71237-71238,71240-71241,71243,71249,71251 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r71058 | georg.brandl | 2009-04-02 20:09:04 +0200 (Do, 02 Apr 2009) | 3 lines
PyErr_NormalizeException may not set an error, so convert the PyErr_SetObject
call on hitting the recursion limit into just assigning it to the arguments provided.
........
r71149 | georg.brandl | 2009-04-04 15:42:39 +0200 (Sa, 04 Apr 2009) | 1 line
#5642: clarify map() compatibility to the builtin.
........
r71150 | georg.brandl | 2009-04-04 15:45:49 +0200 (Sa, 04 Apr 2009) | 1 line
#5601: clarify that webbrowser is not meant for file names.
........
r71212 | georg.brandl | 2009-04-05 12:24:20 +0200 (So, 05 Apr 2009) | 1 line
#1742837: expand HTTP server docs, and fix SocketServer ones to document methods as methods, not functions.
........
r71214 | georg.brandl | 2009-04-05 12:29:57 +0200 (So, 05 Apr 2009) | 1 line
Normalize spelling of Mac OS X.
........
r71215 | georg.brandl | 2009-04-05 12:32:26 +0200 (So, 05 Apr 2009) | 1 line
Avoid sure signs of a diseased mind.
........
r71216 | georg.brandl | 2009-04-05 12:41:02 +0200 (So, 05 Apr 2009) | 1 line
#1718017: document the relation of os.path and the posixpath, ntpath etc. modules better.
........
r71222 | georg.brandl | 2009-04-05 13:07:14 +0200 (So, 05 Apr 2009) | 1 line
#5615: make it possible to configure --without-threads again.
........
r71225 | georg.brandl | 2009-04-05 13:54:07 +0200 (So, 05 Apr 2009) | 1 line
#5580: no need to use parentheses when converterr() argument is actually a type description.
........
r71234 | georg.brandl | 2009-04-05 15:16:35 +0200 (So, 05 Apr 2009) | 1 line
Whitespace normalization.
........
r71237 | georg.brandl | 2009-04-05 16:24:52 +0200 (So, 05 Apr 2009) | 1 line
#1326077: fix traceback formatting of SyntaxErrors. This fixes two differences with formatting coming from Python: a) the reproduction of location details in the error message if no line text is given, b) the prefixing of the last line by one space.
........
r71238 | georg.brandl | 2009-04-05 16:25:41 +0200 (So, 05 Apr 2009) | 1 line
Add NEWS entry for r71237.
........
r71240 | georg.brandl | 2009-04-05 16:40:06 +0200 (So, 05 Apr 2009) | 1 line
#5370: doc update about unpickling objects with custom __getattr__ etc. methods.
........
r71241 | georg.brandl | 2009-04-05 16:48:49 +0200 (So, 05 Apr 2009) | 1 line
#5471: fix expanduser() for $HOME set to "/".
........
r71243 | georg.brandl | 2009-04-05 17:14:29 +0200 (So, 05 Apr 2009) | 1 line
#5432: make plistlib docstring a raw string, since it contains examples with backslash escapes.
........
r71249 | georg.brandl | 2009-04-05 18:30:43 +0200 (So, 05 Apr 2009) | 1 line
#5444: adapt make.bat to new htmlhelp output file name.
........
r71251 | georg.brandl | 2009-04-05 19:17:42 +0200 (So, 05 Apr 2009) | 1 line
#5298: clarify docs about GIL by using more consistent wording.
........
-rw-r--r-- | Doc/c-api/init.rst | 116 | ||||
-rw-r--r-- | Doc/distutils/apiref.rst | 10 | ||||
-rw-r--r-- | Doc/library/_winreg.rst | 5 | ||||
-rw-r--r-- | Doc/library/basehttpserver.rst | 28 | ||||
-rw-r--r-- | Doc/library/multiprocessing.rst | 4 | ||||
-rw-r--r-- | Doc/library/os.path.rst | 24 | ||||
-rw-r--r-- | Doc/library/os.rst | 9 | ||||
-rw-r--r-- | Doc/library/pickle.rst | 9 | ||||
-rw-r--r-- | Doc/library/shelve.rst | 2 | ||||
-rw-r--r-- | Doc/library/socketserver.rst | 61 | ||||
-rw-r--r-- | Doc/library/webbrowser.rst | 4 | ||||
-rw-r--r-- | Doc/make.bat | 3 | ||||
-rw-r--r-- | Lib/plistlib.py | 2 | ||||
-rw-r--r-- | Lib/posixpath.py | 2 | ||||
-rw-r--r-- | Lib/test/test_posixpath.py | 5 | ||||
-rw-r--r-- | Lib/test/test_traceback.py | 29 | ||||
-rw-r--r-- | Lib/traceback.py | 9 | ||||
-rw-r--r-- | Misc/NEWS | 9 | ||||
-rw-r--r-- | Modules/_sqlite/connection.c | 36 | ||||
-rw-r--r-- | Modules/_sqlite/module.c | 2 | ||||
-rw-r--r-- | Objects/bytearrayobject.c | 16 | ||||
-rw-r--r-- | Objects/object.c | 6 | ||||
-rw-r--r-- | Python/errors.c | 10 | ||||
-rw-r--r-- | Python/getargs.c | 2 |
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 @@ -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); |