From pje at users.sourceforge.net Wed Sep 1 00:00:40 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Wed Sep 1 00:33:04 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25905 Modified Files: pep-0333.txt Log Message: Major clarifications and some minor semantic changes; see http://mail.python.org/pipermail/web-sig/2004-August/000730.htm for a complete summary of the changes and their rationales. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- pep-0333.txt 30 Aug 2004 03:04:59 -0000 1.3 +++ pep-0333.txt 31 Aug 2004 22:00:28 -0000 1.4 @@ -53,7 +53,7 @@ However, since no existing servers or frameworks support WSGI, there is little immediate reward for an author who implements WSGI support. -Thus, WSGI *must* be easy to implement, so that an author's initial +Thus, WSGI **must** be easy to implement, so that an author's initial investment in the interface can be reasonably low. Thus, simplicity of implementation on *both* the server and framework @@ -146,17 +146,23 @@ """Simplest possible application object""" status = '200 OK' headers = [('Content-type','text/plain')] - write = start_response(status, headers) - write('Hello world!\n') + start_response(status, headers) + return ['Hello world!\n'] class AppClass: - """Much the same thing, but as a class + """Produce the same output, but using a class - (Note: 'AppClass' is the "application", so calling it - returns an instance of 'AppClass', which is the iterable - return value of the "application callable", as required - by the spec.) + (Note: 'AppClass' is the "application" here, so calling it + returns an instance of 'AppClass', which is then the iterable + return value of the "application callable" as required by + the spec. + + If we wanted to use *instances* of 'AppClass' as application + objects instead, we would have to implement a '__call__' + method, which would be invoked to execute the application, + and we would need to create an instance for use by the + server or gateway. """ def __init__(self, environ, start_response): @@ -167,10 +173,7 @@ status = '200 OK' headers = [('Content-type','text/plain')] self.start(status, headers) - yield "Hello world!\n" - for i in range(1,11): - yield "Extra line %s\n" % i Throughout this specification, we will use the term "a callable" to mean "a function, method, class, or an instance with a ``__call__`` @@ -200,22 +203,26 @@ environ['wsgi.multiprocess'] = True environ['wsgi.last_call'] = True + def write(data): + sys.stdout.write(data) + sys.stdout.flush() + def start_response(status,headers): - write = sys.stdout.write - write("Status: %s\r\n" % status) + + sys.stdout.write("Status: %s\r\n" % status) for key,val in headers: - write("%s: %s\r\n" % (key,val)) - write("\r\n") + sys.stdout.write("%s: %s\r\n" % (key,val)) + sys.stdout.write("\r\n") + return write result = application(environ, start_response) - if result is not None: - try: - for data in result: - sys.stdout.write(data) - finally: - if hasattr(result,'close'): - result.close() + try: + for data in result: + write(data) + finally: + if hasattr(result,'close'): + result.close() In the next section, we will specify the precise semantics that these illustrations are examples of. @@ -227,12 +234,12 @@ The application object must accept two positional arguments. For the sake of illustration, we have named them ``environ`` and ``start_response``, but they are not required to have these names. -A server or gateway *must* invoke the application object using +A server or gateway **must** invoke the application object using positional (not keyword) arguments. (E.g. by calling ``result = application(environ,start_response)`` as shown above.) The ``environ`` parameter is a dictionary object, containing CGI-style -environment variables. This object *must* be a builtin Python +environment variables. This object **must** be a builtin Python dictionary (*not* a subclass, ``UserDict`` or other dictionary emulation), and the application is allowed to modify the dictionary in any way it desires. The dictionary must also include certain @@ -243,7 +250,7 @@ The ``start_response`` parameter is a callable accepting two positional arguments. For the sake of illustration, we have named them ``status`` and ``headers``, but they are not required to have -these names, and the application *must* invoke the ``start_response`` +these names, and the application **must** invoke the ``start_response`` callable using positional arguments (e.g. ``start_response(status,headers)``). @@ -252,21 +259,31 @@ tuples describing the HTTP response header. This ``start_response`` callable must return a ``write(body_data)`` callable that takes one positional parameter: a string to be written as part of the HTTP -response body. +response body. (Note: the ``write()`` callable is provided only +to support certain existing frameworks' imperative output APIs; +it should not be used by new applications or frameworks. See +the `Buffering and Streaming`_ section for more details.) -The application object may return either ``None`` (indicating that -there is no additional output), or it may return a non-empty -iterable yielding strings. (For example, it could be a -generator-iterator that yields strings, or it could be a -sequence such as a list of strings.) The server or gateway will -treat the strings yielded by the iterable as if they had been -passed to the ``write()`` method. If a call to ``len(iterable)`` -succeeds, the server must be able to rely on the result being -accurate. That is, if the iterable returned by the application -provides a working ``__len__()`` method, it *must* return an -accurate result. +The application object must return an iterable yielding strings. +(For example, it could be a generator-iterator that yields strings, +or it could be a sequence such as a list of strings.) The server +or gateway must transmit these strings to the client in an +unbuffered fashion, completing the transmission of each string +before requesting another one. (See the `Buffering and Streaming`_ +section below for more on how application output must be handled.) -If the returned iterable has a ``fileno`` attribute, the server *may* +The server or gateway must not modify supplied strings in any way; +they must be treated as binary byte sequences with no character +interpretation, line ending changes, or other modification. The +application is responsible for ensuring that the string(s) to be +written are in a format suitable for the client. + +If a call to ``len(iterable)`` succeeds, the server must be able +to rely on the result being accurate. That is, if the iterable +returned by the application provides a working ``__len__()`` +method, it **must** return an accurate result. + +If the returned iterable has a ``fileno`` attribute, the server **may** assume that this is a ``fileno()`` method returning an operating system file descriptor, and that it is allowed to read directly from that descriptor up to the end of the file, and/or use any appropriate @@ -275,20 +292,36 @@ transmission with the file's current position, and end at the end of the file. -Finally, if the application returned an iterable, and the iterable has -a ``close()`` method, the server or gateway *must* call that method -upon completion of the current request, whether the request was -completed normally, or terminated early due to an error. (This is to -support resource release by the application. This protocol is -intended to support PEP 325, and also the simple case of an -application returning an open text file.) +Note that an application **must not** return an iterable with a +``fileno`` attribute if it is anything other than a method returning +an **operating system file descriptor**. "File-like" objects +that do not possess a true operating system file descriptor number +are expressly forbidden. Servers running on platforms where file +descriptors do not exist, or where there is no meaningful API for +accelerating transmission from a file descriptor should ignore the +``fileno`` attribute. -(Note: the application *must* invoke the ``start_response()`` callable -before the iterable yields its first body string, so that the server -can send headers before any body content. However, this invocation -*may* be performed by the iterable's first iteration, so servers *must -not* assume that ``start_response()`` has been called before they -begin iterating over the iterable.) +If the iterable returned by the application has a ``close()`` method, +the server or gateway **must** call that method upon completion of the +current request, whether the request was completed normally, or +terminated early due to an error. (This is to support resource release +by the application. This protocol is intended to support PEP 325, and +also other simple cases such as an application returning an open text +file.) + +(Note: the application **must** invoke the ``start_response()`` +callable before the iterable yields its first body string, so that the +server can send the headers before any body content. However, this +invocation **may** be performed by the iterable's first iteration, so +servers **must not** assume that ``start_response()`` has been called +before they begin iterating over the iterable.) + +Finally, servers **must not** directly use any other attributes of +the iterable returned by the application. For example, it the +iterable is a file object, it may have a ``read()`` method, but +the server **must not** utilize it. Only attributes specified +here, or accessed via e.g. the PEP 234 iteration APIs are +acceptable. ``environ`` Variables @@ -296,8 +329,8 @@ The ``environ`` dictionary is required to contain these CGI environment variables, as defined by the Common Gateway Interface -specification [2]_. The following variables *must* be present, but -*may* be an empty string, if there is no more appropriate value for +specification [2]_. The following variables **must** be present, but +**may** be an empty string, if there is no more appropriate value for them: * ``REQUEST_METHOD`` @@ -446,11 +479,11 @@ example, to minimize intermingling of data from multiple processes writing to the same error log.) -The methods listed in the table above *must* be supported by all +The methods listed in the table above **must** be supported by all servers conforming to this specification. Applications conforming -to this specification *must not* use any other methods or attributes +to this specification **must not** use any other methods or attributes of the ``input`` or ``errors`` objects. In particular, applications -*must not* attempt to close these streams, even if they possess +**must not** attempt to close these streams, even if they possess ``close()`` methods. @@ -462,36 +495,46 @@ (As with all WSGI callables, the arguments must be supplied positionally, not by keyword.) The ``start_response`` callable is used to begin the HTTP response, and it must return a -``write(body_data)`` callable. +``write(body_data)`` callable (see the `Buffering and Streaming`_ +section, below). The ``status`` argument is an HTTP "status" string like ``"200 OK"`` -or ``"404 Not Found"``. The string *must* be pure 7-bit ASCII, +or ``"404 Not Found"``. The string **must** be pure 7-bit ASCII, containing no control characters. It must not be terminated with a carriage return or linefeed. -The ``headers`` argument is a sequence of -``(header_name,header_value)`` tuples. Each ``header_name`` must be a -valid HTTP header name, without a trailing colon or other punctuation. -Each ``header_value`` *must not* include *any* control characters, -including carriage returns or linefeeds, either embedded or at the -end. (These requirements are to minimize the complexity of any -parsing that must be performed by servers, gateways, and intermediate -response processors that need to inspect or modify response headers.) +The ``headers`` argument is a list of ``(header_name,header_value)`` +tuples. It must be a Python list; i.e. ``type(headers) is +ListType)``, and the server **may** change its contents in any way +it desires. Each ``header_name`` must be a valid HTTP header name, +without a trailing colon or other punctuation. Each ``header_value`` +**must not** include *any* control characters, including carriage +returns or linefeeds, either embedded or at the end. (These +requirements are to minimize the complexity of any parsing that must +be performed by servers, gateways, and intermediate response +processors that need to inspect or modify response headers.) In general, the server or gateway is responsible for ensuring that correct headers are sent to the client: if the application omits a needed header, the server or gateway *should* add it. For example, the HTTP ``Date:`` and ``Server:`` headers would normally be supplied -by the server or gateway. If the application supplies a header that -the server would ordinarily supply, or that contradicts the server's -intended behavior (e.g. supplying a different ``Connection:`` header), -the server or gateway *may* discard the conflicting header, provided -that its action is recorded for the benefit of the application author. +by the server or gateway. (A reminder for server/gateway authors: HTTP header names are case-insensitive, so be sure to take that into consideration when examining application-supplied headers!) +If the application supplies headers that would affect the persistence +of the client's connection (e.g. ``Connection:``, "keep-alives", etc.), +the server or gateway is permitted to discard or modify these headers, +if the server cannot or will not conform to the application's requested +semantics. E.g., if the application requests a persistent connection +but the server wishes transience, or vice versa. + +However, if a server or gateway discards or overrides any application +header for any reason, it **must** record this action in a log (such as +the ``wsgi.errors`` log) for the benefit of the application author. + Handling the ``Content-Length`` Header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -510,64 +553,102 @@ by the iterable. And, if the server and client both support HTTP/1.1 "chunked -encoding" [3]_, then the server *may* use chunked encoding to send +encoding" [3]_, then the server **may** use chunked encoding to send a chunk for each ``write()`` call or string yielded by the iterable, thus generating a ``Content-Length`` header for each chunk. This allows the server to keep the client connection alive, if it wishes -to do so. Note that the server *must* comply fully with RFC 2616 when -doing this, or else fall back to one of the other strategies for +to do so. Note that the server **must** comply fully with RFC 2616 +when doing this, or else fall back to one of the other strategies for dealing with the absence of ``Content-Length``. -The ``write()`` Callable ------------------------- - -The return value of the ``start_response()`` callable is a -one-argument `write()`` callable, that accepts strings to write as -part of the HTTP response body. The server or gateway must -not modify supplied strings in any way; they must be treated -as binary byte sequences with no character interpretation, line -ending changes, or other modification. The application is responsible -for ensuring that the string(s) to be written are in a format suitable -for the client. - -Note that the purpose of the ``write()`` callable is primarily to -support existing application frameworks that support a streaming -"push" API. Therefore, strings passed to ``write()`` *must* be sent -to the client *as soon as possible*; they must *not* be buffered -unless the buffer will be emptied in parallel with the application's -continuing execution (e.g. by a separate I/O thread). If the server -or gateway does not have a separate I/O thread available, it *must* -finish writing the supplied string before it returns from each -``write()`` invocation. - -If the application returns an iterable, each string produced by the -iterable must be treated as though it had been passed to ``write()``, -with the data sent in an "as soon as possible" manner. That is, -the iterable should not be asked for a new string until the previous -string has been sent to the client, or is buffered for such sending -by a parallel thread. +Buffering and Streaming +----------------------- -Notice that these rules discourage the generation of content before a -client is ready for it, in excess of the buffer sizes provided by the -server and operating system. For this reason, some applications may -wish to buffer data internally before passing any of it to ``write()`` -or yielding it from an iterator, in order to avoid waiting for the -client to catch up with their output. This approach may yield better -throughput for dynamically generated pages of moderate size, since the -application is then freed for other tasks. +Generally speaking, applications will achieve the best throughput +by buffering their (modestly-sized) output and sending it all at +once. When this is the case, applications **should** simply +return a single-element iterable containing their entire output as +a single string. -In addition to improved performance, buffering all of an application's +(In addition to improved performance, buffering all of an application's output has an advantage for error handling: the buffered output can -be thrown away and replaced by an error page, rather than dumping an +be discarded and replaced by an error page, rather than dumping an error message in the middle of some partially-completed output. For this and other reasons, many existing Python frameworks already accumulate their output for a single write, unless the application explicitly requests streaming, or the expected output is larger than -practical for buffering (e.g. multi-megabyte PDFs). So, these -application frameworks are already a natural fit for the WSGI -streaming model: for most requests they will only call ``write()`` -once anyway! +practical for buffering (e.g. multi-megabyte PDFs).) + +For large files, however, or for specialized uses of HTTP streaming +(such as multipart "server push"), an application may need to provide +output in smaller blocks (e.g. to avoid loading a large file into +memory). It's also sometimes the case that part of a response may +be time-consuming to produce, but it would be useful to send ahead the +portion of the response that precedes it. + +In these cases, applications **should** return an iterator (usually +a generator-iterator) that produces the output in a block-by-block +fashion. These blocks may be broken to coincide with mulitpart +boundaries (for "server push"), or just before time-consuming +tasks (such as reading another block of an on-disk file). + +WSGI servers and gateways **must not** delay the transmission +of any block; they **must** either fully transmit the block to +the client, or guarantee that they will continue transmission +even while the application is producing its next block. A +server/gateway may provide this guarantee in one of two ways: + +1. Send the entire block to the operating system (and request + that any O/S buffers be flushed) before returning control + to the application, OR + +2. Use a different thread to ensure that the block continues + to be transmitted while the application produces the next + block. + +By providing this guarantee, WSGI allows applications to ensure +that transmission will not become stalled at an arbitrary point +in their output data. This is critical for proper functioning +of e.g. multipart "server push" streaming, where data between +multipart boundaries should be transmitted in full to the client. + + +The ``write()`` Callable +~~~~~~~~~~~~~~~~~~~~~~~~ + +Some existing application framework APIs support unbuffered +output in a different manner than WSGI. Specifically, they +provide a "write" function or method of some kind to write +an unbuffered block of data, or else they provide a buffered +"write" function and a "flush" mechanism to flush the buffer. + +Unfortunately, such APIs cannot be implemented in terms of +WSGI's "iterable" application return value, unless threads +or other special mechanisms are used. + +Therefore, to allow these frameworks to continue using an +imperative API, WSGI includes a special ``write()`` callable, +returned by the ``start_response`` callable. + +New WSGI applications and frameworks **should not** use the +``write()`` callable if it is possible to avoid doing so. The +``write()`` callable is strictly a hack to support existing +frameworks' imperative APIs. In general, applications +should either be internally buffered, or produce iterable output. + +The ``write()`` callable is returned by the ``start_response()`` +callable, and it accepts a single parameter: a string to be +written as part of the HTTP response body, that is treated exactly +as though it had been yielded by the output iterable. In other +words, before ``write()`` returns, it must guarantee that the +passed-in string was either completely sent to the client, or +that it is buffered for transmission while the application +proceeds forward. + +An application **may** return a non-empty iterable even if it +invokes ``write()``, and that output must be treated normally +by the server or gateway. Implementation/Application Notes @@ -594,7 +675,7 @@ -------------- Servers *should* trap and log exceptions raised by -applications, and *may* continue to execute, or attempt to shut down +applications, and **may** continue to execute, or attempt to shut down gracefully. Applications *should* avoid allowing exceptions to escape their execution scope, since the result of uncaught exceptions is server-defined. @@ -687,6 +768,48 @@ a possibility. +Supporting Older (<2.2) Versions of Python +------------------------------------------ + +Some servers, gateways, or applications may wish to support older +(<2.2) versions of Python. This is especially important if Jython +is a target platform, since as of this writing a production-ready +version of Jython 2.2 is not yet available. + +For servers and gateways, this is relatively straightforward: +servers and gateways targeting pre-2.2 versions of Python must +simply restrict themselves to using only a standard "for" loop to +iterate over any iterable returned by an application. This is the +only way to ensure source-level compatibility with both the pre-2.2 +iterator protocol (discussed further below) and "today's" iterator +protocol (see PEP 234). + +(Note that this technique necessarily applies only to servers, +gateways, or middleware that are written in Python. Discussion of +how to use iterator protocol(s) correctly from other languages is +outside the scope of this PEP.) + +For applications, supporting pre-2.2 versions of Python is slightly +more complex: + +* You may not return a file object and expect it to work as an iterable, + since before Python 2.2, files were not iterable. + +* If you return an iterable, it **must** implement the pre-2.2 iterator + protocol. That is, provide a ``__getitem__`` method that accepts + an integer key, and raises ``IndexError`` when exhausted. + +Finally, middleware that wishes to support pre-2.2 versions of Python, +and iterates over application return values or itself returns an +iterable (or both), must follow the appropriate recommendations above. + +(Note: It should go without saying that to support pre-2.2 versions +of Python, any server, gateway, application, or middleware must also +use only language features available in the target version, use +1 and 0 instead of ``True`` and ``False``, etc.) + + + Server Extension APIs --------------------- @@ -710,7 +833,7 @@ frameworks to function almost entirely as middleware of various kinds. So, to provide maximum compatibility, servers and gateways that -provide extension APIs that replace some WSGI functionality, *must* +provide extension APIs that replace some WSGI functionality, **must** design those APIs so that they are invoked using the portion of the API that they replace. For example, an extension API to access HTTP request headers must require the application to pass in its current @@ -747,9 +870,9 @@ HTTP 1.1 Expect/Continue ------------------------ -Servers and gateways *must* provide transparent support for HTTP 1.1's -"expect/continue" mechanism, if they implement HTTP 1.1. This may be -done in any of several ways: +Servers and gateways **must** provide transparent support for HTTP +1.1's "expect/continue" mechanism, if they implement HTTP 1.1. This +may be done in any of several ways: 1. Reject all client requests containing an ``Expect: 100-continue`` header with a "417 Expectation failed" error. Such requests will @@ -918,71 +1041,28 @@ Open Issues =========== -The format of the ``headers`` passed to the ``start_response`` -callable has seen some debate. Currently, it is a sequence of tuples, -but other formats have been suggested, such as a dictionary of lists, -or an ``email.Message`` object (from the Python standard library's -``email`` package). For various practical reasons, the "dictionary of -lists" approach has been ruled out, but ``email.Message`` is still a -candidate, as it provides several advantages for many middleware -developers and some application or framework developers, without an -excessive burden to anyone else. - -Specifically, ``email.Message`` objects offer a mutable data -structure, (not unlike a case-insensitive dictionary) for containing -MIME headers, such as those used in an HTTP response. This makes it -very easy to modify headers, or add multi-valued headers such as -``Set-Cookie`` headers. If the ``headers`` passed to -``start_response`` were an ``email.Message``, then it would be easy -for middleware and servers to modify response headers, e.g. to supply -defaults for missing headers. It also leads to cleaner-looking -application code in some cases, e.g.:: - - from email.Message import Message - - def application(environ, start_response): - headers = Message() - headers.set_type("text/plain") - headers.add_header("Set-Cookie", "FOO=BAR", path="/foobar") - start("200 OK", headers)("Hello world!") - -Some have pointed out that this requires the developers of existing -frameworks to convert whatever header format they use to an -``email.Message``. But this is only relevant if the format they -already use is a list of name/value pairs: in all other cases they -would have to perform some conversion anyway. - -In the event that the ``email.Message`` format is *not* chosen, -however, application developers will still have the option of using it -as a helper class. For example, the code below works with the current -WSGI spec, by passing the message object's ``items()`` (a list of -tuples) to ``start_response()``:: - - def application(environ, start_response): - headers = Message() - headers.set_type("text/plain") - headers.add_header("Set-Cookie", "FOO=BAR", path="/foobar") - start_response("200 OK", headers.items())("Hello world!") - -But this doesn't help middleware authors, who would have to convert -the response headers into a ``Message`` object and back again if they -needed to modify the headers. - -One other issue that's been brought up in relation to -``email.Message`` is that its ``set_type()`` method also sets a -``MIME-Version`` header. In order to comply properly with the MIME -and HTTP specifications, it would then be necessary for server/gateway -authors to ensure the presence of a ``Content-Transfer-Encoding``, -e.g.:: - - if ('MIME-Version' in headers and - 'Content-Transfer-Encoding' not in headers - ): - headers['Content-Transfer-Encoding'] = "8bit" - -Also, ``email.Message`` has various features unrelated to HTTP or WSGI -that should not be used, and might be distracting or confusing to -authors. +* Some persons have requested information about whether the + ``HTTP_AUTHENTICATION`` header may be provided by the server. + That is, some web servers do not supply this information to + e.g. CGI applications, and they would like the application + to know that this is the case so it can use alternative + means of authentication. + +* Error handling: strategies for effective error handling are + currently in discussion on the Web-SIG mailing list. In + particular, a mechanism for specifying what errors an + application or middleware should *not* trap (because they + indicate that the request should be aborted), and mechanisms + for servers, gateways, and middleware to handle exceptions + occurring at various phases of the response processing. + +* Byte strings: future versions of Python may replace today's + 8-bit strings with some kind of "byte array" type. Some sort + of future-proofing would be good to have, and strategies for + this should be discussed on Web-SIG and Python-Dev. Nearly + every string in WSGI is potentially affected by this, although + some contexts should perhaps continue to allow strings as long as + they're pure ASCII. Acknowledgements From fdrake at users.sourceforge.net Wed Sep 1 06:05:10 2004 From: fdrake at users.sourceforge.net (fdrake@users.sourceforge.net) Date: Wed Sep 1 06:05:13 2004 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew24.tex, 1.95, 1.96 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20881 Modified Files: whatsnew24.tex Log Message: - add missing \end{seealso} - wrap long line Index: whatsnew24.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew24.tex,v retrieving revision 1.95 retrieving revision 1.96 diff -u -d -r1.95 -r1.96 --- whatsnew24.tex 31 Aug 2004 13:57:02 -0000 1.95 +++ whatsnew24.tex 1 Sep 2004 04:05:08 -0000 1.96 @@ -699,7 +699,10 @@ relative import. This part of the PEP is not yet implemented. \begin{seealso} -\seepep{328}{Imports: Multi-Line and Absolute/Relative}{Written by Aahz. Multi-line imports were implemented by Dima Dorfman.} +\seepep{328}{Imports: Multi-Line and Absolute/Relative} + {Written by Aahz. Multi-line imports were implemented by + Dima Dorfman.} +\end{seealso} %====================================================================== From pje at users.sourceforge.net Wed Sep 1 06:59:23 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Wed Sep 1 06:59:26 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28642 Modified Files: pep-0333.txt Log Message: More formatting fixes Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- pep-0333.txt 31 Aug 2004 22:00:28 -0000 1.4 +++ pep-0333.txt 1 Sep 2004 04:59:21 -0000 1.5 @@ -204,16 +204,14 @@ environ['wsgi.last_call'] = True def write(data): - sys.stdout.write(data) + sys.stdout.write(data) sys.stdout.flush() def start_response(status,headers): - sys.stdout.write("Status: %s\r\n" % status) for key,val in headers: sys.stdout.write("%s: %s\r\n" % (key,val)) sys.stdout.write("\r\n") - return write result = application(environ, start_response) @@ -333,30 +331,30 @@ **may** be an empty string, if there is no more appropriate value for them: - * ``REQUEST_METHOD`` +* ``REQUEST_METHOD`` - * ``SCRIPT_NAME`` (The initial portion of the request URL's "path" - that corresponds to the application object, so that the application - knows its virtual "location".) +* ``SCRIPT_NAME`` (The initial portion of the request URL's "path" + that corresponds to the application object, so that the application + knows its virtual "location".) - * ``PATH_INFO`` (The remainder of the request URL's "path", - designating the virtual "location" of the request's target within - the application) +* ``PATH_INFO`` (The remainder of the request URL's "path", + designating the virtual "location" of the request's target within + the application) - * ``QUERY_STRING`` +* ``QUERY_STRING`` - * ``CONTENT_TYPE`` +* ``CONTENT_TYPE`` - * ``CONTENT_LENGTH`` +* ``CONTENT_LENGTH`` - * ``SERVER_NAME`` and ``SERVER_PORT`` (which, when combined with - ``SCRIPT_NAME`` and ``PATH_INFO``, should complete the URL. Note, - however, that ``HTTP_HOST``, if present, should be used in - preference to ``SERVER_NAME`` for constructing the URL. See the - `URL Reconstruction`_ section below for more detail.) +* ``SERVER_NAME`` and ``SERVER_PORT`` (which, when combined with + ``SCRIPT_NAME`` and ``PATH_INFO``, should complete the URL. Note, + however, that ``HTTP_HOST``, if present, should be used in + preference to ``SERVER_NAME`` for constructing the URL. See the + `URL Reconstruction`_ section below for more detail.) - * Variables corresponding to the client-supplied HTTP headers (i.e., - variables whose names begin with ``"HTTP_"``). +* Variables corresponding to the client-supplied HTTP headers (i.e., + variables whose names begin with ``"HTTP_"``). In general, a server or gateway should attempt to provide as many other CGI variables as are applicable, including e.g. the nonstandard @@ -752,16 +750,16 @@ respect to some server(s). Such "middleware" components can perform such functions as: - * Routing a request to different application objects based on the - target URL, after rewriting the ``environ`` accordingly. +* Routing a request to different application objects based on the + target URL, after rewriting the ``environ`` accordingly. - * Allowing multiple applications or frameworks to run side-by-side - in the same process +* Allowing multiple applications or frameworks to run side-by-side + in the same process - * Load balancing and remote processing, by forwarding requests and - responses over a network +* Load balancing and remote processing, by forwarding requests and + responses over a network - * Perform content postprocessing, such as applying XSL stylesheets +* Perform content postprocessing, such as applying XSL stylesheets Given the existence of applications and servers conforming to this specification, the appearance of such reusable middleware becomes @@ -874,18 +872,18 @@ 1.1's "expect/continue" mechanism, if they implement HTTP 1.1. This may be done in any of several ways: - 1. Reject all client requests containing an ``Expect: 100-continue`` - header with a "417 Expectation failed" error. Such requests will - not be forwarded to an application object. +1. Reject all client requests containing an ``Expect: 100-continue`` + header with a "417 Expectation failed" error. Such requests will + not be forwarded to an application object. - 2. Respond to requests containing an ``Expect: 100-continue`` request - with an immediate "100 Continue" response, and proceed normally. +2. Respond to requests containing an ``Expect: 100-continue`` request + with an immediate "100 Continue" response, and proceed normally. - 3. Proceed with the request normally, but provide the application - with a ``wsgi.input`` stream that will send the "100 Continue" - response if/when the application first attempts to read from the - input stream. The read request must then remain blocked until the - client responds. +3. Proceed with the request normally, but provide the application + with a ``wsgi.input`` stream that will send the "100 Continue" + response if/when the application first attempts to read from the + input stream. The read request must then remain blocked until the + client responds. Note that this behavior restriction does not apply for HTTP 1.0 requests, or for requests that are not directed to an application @@ -1071,18 +1069,18 @@ Thanks go to the many folks on the Web-SIG mailing list whose thoughtful feedback made this revised draft possible. Especially: - * Gregory "Grisha" Trubetskoy, author of ``mod_python``, who beat up - on the first draft as not offering any advantages over "plain old - CGI", thus encouraging me to look for a better approach. +* Gregory "Grisha" Trubetskoy, author of ``mod_python``, who beat up + on the first draft as not offering any advantages over "plain old + CGI", thus encouraging me to look for a better approach. - * Ian Bicking, who helped nag me into properly specifying the - multithreading and multiprocess options, as well as badgering me to - provide a mechanism for servers to supply custom extension data to - an application. +* Ian Bicking, who helped nag me into properly specifying the + multithreading and multiprocess options, as well as badgering me to + provide a mechanism for servers to supply custom extension data to + an application. - * Tony Lownds, who came up with the concept of a ``start_response`` - function that took the status and headers, returning a ``write`` - function. +* Tony Lownds, who came up with the concept of a ``start_response`` + function that took the status and headers, returning a ``write`` + function. References From anthony at interlink.com.au Wed Sep 1 07:11:31 2004 From: anthony at interlink.com.au (Anthony Baxter) Date: Wed Sep 1 08:16:01 2004 Subject: [Python-checkins] Freezing for alpha3 - trunk FROZEN from 2004-09-01 13:00 UTC Message-ID: <41355A03.6070405@interlink.com.au> I plan to start alpha3 in about 24 hours time. From about 12 hours from now, the trunk should be considered frozen - that's starting at about 1700 UTC on 2004-09-01. If your name isn't Anthony, Fred or Martin, please do NOT check in while we're doing the release. Really. Really, really, really. I'm cc'ing python-checkins as well this time, as a few folks missed this last time. The trunk will stay frozen until about 6 hours or so after the release is done - this makes it easier for me to do an emergency brown-paper-bag release in the case of a cockup Thanks, Anthony From rhettinger at users.sourceforge.net Wed Sep 1 09:02:45 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 1 09:02:48 2004 Subject: [Python-checkins] python/dist/src/Include object.h,2.128,2.129 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13289/Include Modified Files: object.h Log Message: SF patch #1020188: Use Py_CLEAR where necessary to avoid crashes (Contributed by Dima Dorfman) Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.128 retrieving revision 2.129 diff -u -d -r2.128 -r2.129 --- object.h 22 Jul 2004 01:46:43 -0000 2.128 +++ object.h 1 Sep 2004 07:02:42 -0000 2.129 @@ -623,7 +623,7 @@ #define Py_CLEAR(op) \ do { \ if (op) { \ - PyObject *tmp = (op); \ + PyObject *tmp = (PyObject *)(op); \ (op) = NULL; \ Py_DECREF(tmp); \ } \ From rhettinger at users.sourceforge.net Wed Sep 1 09:03:00 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 1 09:03:04 2004 Subject: [Python-checkins] python/dist/src/Modules itertoolsmodule.c, 1.34, 1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13289/Modules Modified Files: itertoolsmodule.c Log Message: SF patch #1020188: Use Py_CLEAR where necessary to avoid crashes (Contributed by Dima Dorfman) Index: itertoolsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- itertoolsmodule.c 15 Jul 2004 05:32:47 -0000 1.34 +++ itertoolsmodule.c 1 Sep 2004 07:02:43 -0000 1.35 @@ -250,8 +250,7 @@ r = gbo->currvalue; gbo->currvalue = NULL; - Py_DECREF(gbo->currkey); - gbo->currkey = NULL; + Py_CLEAR(gbo->currkey); return r; } From rhettinger at users.sourceforge.net Wed Sep 1 09:03:03 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 1 09:03:06 2004 Subject: [Python-checkins] python/dist/src/Objects enumobject.c, 1.17, 1.18 genobject.c, 1.3, 1.4 iterobject.c, 1.18, 1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13289/Objects Modified Files: enumobject.c genobject.c iterobject.c Log Message: SF patch #1020188: Use Py_CLEAR where necessary to avoid crashes (Contributed by Dima Dorfman) Index: enumobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/enumobject.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- enumobject.c 25 Aug 2004 19:42:12 -0000 1.17 +++ enumobject.c 1 Sep 2004 07:02:44 -0000 1.18 @@ -230,10 +230,7 @@ PyErr_Clear(); } ro->index = -1; - if (ro->seq != NULL) { - Py_DECREF(ro->seq); - ro->seq = NULL; - } + Py_CLEAR(ro->seq); return NULL; } Index: genobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/genobject.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- genobject.c 27 Jun 2004 15:43:12 -0000 1.3 +++ genobject.c 1 Sep 2004 07:02:44 -0000 1.4 @@ -51,8 +51,7 @@ * may keep a chain of frames alive or it could create a reference * cycle. */ assert(f->f_back != NULL); - Py_DECREF(f->f_back); - f->f_back = NULL; + Py_CLEAR(f->f_back); /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ Index: iterobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- iterobject.c 12 Apr 2004 18:10:01 -0000 1.18 +++ iterobject.c 1 Sep 2004 07:02:44 -0000 1.19 @@ -192,18 +192,14 @@ return result; /* Common case, fast path */ Py_DECREF(result); if (ok > 0) { - Py_DECREF(it->it_callable); - it->it_callable = NULL; - Py_DECREF(it->it_sentinel); - it->it_sentinel = NULL; + Py_CLEAR(it->it_callable); + Py_CLEAR(it->it_sentinel); } } else if (PyErr_ExceptionMatches(PyExc_StopIteration)) { PyErr_Clear(); - Py_DECREF(it->it_callable); - it->it_callable = NULL; - Py_DECREF(it->it_sentinel); - it->it_sentinel = NULL; + Py_CLEAR(it->it_callable); + Py_CLEAR(it->it_sentinel); } } return NULL; From tim_one at users.sourceforge.net Wed Sep 1 15:10:34 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed Sep 1 15:10:37 2004 Subject: [Python-checkins] python/dist/src/Lib _MozillaCookieJar.py, 1.2, 1.3 os.py, 1.80, 1.81 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11454/Lib Modified Files: _MozillaCookieJar.py os.py Log Message: Whitespace normalization. Index: _MozillaCookieJar.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/_MozillaCookieJar.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- _MozillaCookieJar.py 31 Aug 2004 11:38:12 -0000 1.2 +++ _MozillaCookieJar.py 1 Sep 2004 13:10:31 -0000 1.3 @@ -2,7 +2,7 @@ import re, time, logging -from cookielib import (reraise_unmasked_exceptions, FileCookieJar, Cookie, +from cookielib import (reraise_unmasked_exceptions, FileCookieJar, Cookie, MISSING_FILENAME_TEXT) class MozillaCookieJar(FileCookieJar): Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.80 retrieving revision 1.81 diff -u -d -r1.80 -r1.81 --- os.py 31 Aug 2004 11:38:12 -0000 1.80 +++ os.py 1 Sep 2004 13:10:31 -0000 1.81 @@ -130,7 +130,7 @@ raise ImportError, 'no os specific module found' sys.modules['os.path'] = path -from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, +from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, devnull) del _names From tim_one at users.sourceforge.net Wed Sep 1 15:10:34 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed Sep 1 15:10:38 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_optparse.py, 1.7, 1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11454/Lib/test Modified Files: test_optparse.py Log Message: Whitespace normalization. Index: test_optparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_optparse.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- test_optparse.py 31 Aug 2004 11:38:12 -0000 1.7 +++ test_optparse.py 1 Sep 2004 13:10:32 -0000 1.8 @@ -17,9 +17,9 @@ from pprint import pprint from test import test_support -from optparse import (make_option, Option, IndentedHelpFormatter, - TitledHelpFormatter, OptionParser, OptionContainer, OptionGroup, - SUPPRESS_HELP, SUPPRESS_USAGE, OptionError, OptionConflictError, +from optparse import (make_option, Option, IndentedHelpFormatter, + TitledHelpFormatter, OptionParser, OptionContainer, OptionGroup, + SUPPRESS_HELP, SUPPRESS_USAGE, OptionError, OptionConflictError, BadOptionError, OptionValueError, _match_abbrev) class BaseTest(unittest.TestCase): From pje at users.sourceforge.net Wed Sep 1 15:44:11 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Wed Sep 1 15:44:14 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17715 Modified Files: pep-0333.txt Log Message: Move 'fileno()' support to a separate section, where it should be easier to see it's an optional and platform-specific extension, not an excuse to return "file-like" objects instead of iterables. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- pep-0333.txt 1 Sep 2004 04:59:21 -0000 1.5 +++ pep-0333.txt 1 Sep 2004 13:44:07 -0000 1.6 @@ -281,24 +281,6 @@ returned by the application provides a working ``__len__()`` method, it **must** return an accurate result. -If the returned iterable has a ``fileno`` attribute, the server **may** -assume that this is a ``fileno()`` method returning an operating -system file descriptor, and that it is allowed to read directly from -that descriptor up to the end of the file, and/or use any appropriate -operating system facilities (e.g. the ``sendfile()`` system call) to -transmit the file's contents. If the server does this, it must begin -transmission with the file's current position, and end at the end of -the file. - -Note that an application **must not** return an iterable with a -``fileno`` attribute if it is anything other than a method returning -an **operating system file descriptor**. "File-like" objects -that do not possess a true operating system file descriptor number -are expressly forbidden. Servers running on platforms where file -descriptors do not exist, or where there is no meaningful API for -accelerating transmission from a file descriptor should ignore the -``fileno`` attribute. - If the iterable returned by the application has a ``close()`` method, the server or gateway **must** call that method upon completion of the current request, whether the request was completed normally, or @@ -865,6 +847,41 @@ being bypassed by applications using those extensions! +Optional Platform-Specific File Handling +---------------------------------------- + +If the application-returned iterable has a ``fileno`` attribute, +the server or gateway **may** assume that this is a ``fileno()`` +method returning an operating system file descriptor, and that it is +allowed to read directly from that descriptor up to the end of the +file, and/or use any appropriate operating system facilities (e.g. +the ``sendfile()`` system call) to transmit the file's contents. If +the server does this, it must begin transmission with the file's +current position, and end at the end of the file. + +Note that an application **must not** return an iterable with a +``fileno`` attribute if it is anything other than a method returning +an **operating system file descriptor**. "File-like" objects +that do not possess a true operating system file descriptor number +are expressly. Servers running on platforms where file +descriptors do not exist, or where there is no meaningful API for +accelerating transmission from a file descriptor should ignore the +``fileno`` attribute. + +On platforms that possess some analagous mechanism for fast +transmission of static files or pipes, a server or gateway **may** +offer a similar extension using a different method name, returning +an object of the appropriate type for that platform. Such servers +**should** document the method name to be used and the type of +object that it should return. + +Please note that this optional extension does not excuse the +application from returning an iterable object. Returning an object +that is not iterable -- even if it implements ``fileno()`` or is +"file-like" -- is not acceptable, and will be rejected by servers +and gateways that do not support this optional extension. + + HTTP 1.1 Expect/Continue ------------------------ From akuchling at users.sourceforge.net Wed Sep 1 16:04:53 2004 From: akuchling at users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed Sep 1 16:04:56 2004 Subject: [Python-checkins] python/dist/src/Lib asyncore.py,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20591 Modified Files: asyncore.py Log Message: [Bug #1011606] Only check file descriptors for exceptional conditions if the fd is readable or writable Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.60 retrieving revision 1.61 diff -u -d -r1.60 -r1.61 --- asyncore.py 13 Aug 2004 20:06:57 -0000 1.60 +++ asyncore.py 1 Sep 2004 14:04:51 -0000 1.61 @@ -107,11 +107,14 @@ if map: r = []; w = []; e = [] for fd, obj in map.items(): - e.append(fd) - if obj.readable(): + is_r = obj.readable() + is_w = obj.writable() + if is_r: r.append(fd) - if obj.writable(): + if is_w: w.append(fd) + if is_r or is_w: + e.append(fd) if [] == r == w == e: time.sleep(timeout) else: @@ -151,12 +154,15 @@ pollster = select.poll() if map: for fd, obj in map.items(): - flags = select.POLLERR | select.POLLHUP | select.POLLNVAL + flags = 0 if obj.readable(): flags |= select.POLLIN | select.POLLPRI if obj.writable(): flags |= select.POLLOUT if flags: + # Only check for exceptions if object was either readable + # or writable. + flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL pollster.register(fd, flags) try: r = pollster.poll(timeout) From loewis at users.sourceforge.net Wed Sep 1 16:51:09 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed Sep 1 16:51:14 2004 Subject: [Python-checkins] python/dist/src/Tools/msi msi.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/msi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29422 Modified Files: msi.py Log Message: Conditionalize Tcl feature Index: msi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/msi/msi.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- msi.py 30 Aug 2004 09:22:30 -0000 1.4 +++ msi.py 1 Sep 2004 14:51:06 -0000 1.5 @@ -22,6 +22,8 @@ # goes into file name and ProductCode. Defaults to # current_version.day for Snapshot, current_version otherwise full_current_version = None +# Is Tcl available at all? +have_tcl = True try: from config import * @@ -762,7 +764,8 @@ ext_feature = Feature(db, "Extensions", "Register Extensions", "Make this Python installation the default Python installation", 3, parent = default_feature) - tcltk = Feature(db, "TclTk", "Tcl/Tk", "Tkinter, IDLE, pydoc", 5, + if have_tcl: + tcltk = Feature(db, "TclTk", "Tcl/Tk", "Tkinter, IDLE, pydoc", 5, parent = default_feature, attributes=2) htmlfiles = Feature(db, "Documentation", "Documentation", "Python HTMLHelp File", 7, parent = default_feature) @@ -811,7 +814,8 @@ # Add all executables, icons, text files into the TARGETDIR component root = PyDirectory(db, cab, None, srcdir, "TARGETDIR", "SourceDir") default_feature.set_current() - root.add_file("PCBuild/w9xpopen.exe") + if not msilib.Win64: + root.add_file("PCBuild/w9xpopen.exe") root.add_file("PC/py.ico") root.add_file("PC/pyc.ico") root.add_file("README.txt", src="README") @@ -851,6 +855,8 @@ if dir == "CVS" or dir.startswith("plat-"): continue elif dir in ["lib-tk", "idlelib", "Icons"]: + if not have_tcl: + continue tcltk.set_current() elif dir in ['test', 'output']: testsuite.set_current() @@ -913,15 +919,16 @@ continue dlls.append(f) lib.add_file(f) - if not os.path.exists(srcdir+"/PCBuild/_tkinter.pyd"): - print "WARNING: Missing _tkinter.pyd" - else: - lib.start_component("TkDLLs", tcltk) - lib.add_file("_tkinter.pyd") - dlls.append("_tkinter.pyd") - tcldir = os.path.normpath(srcdir+"/../tcltk/bin") - for f in glob.glob1(tcldir, "*.dll"): - lib.add_file(f, src=os.path.join(tcldir, f)) + if have_tcl: + if not os.path.exists(srcdir+"/PCBuild/_tkinter.pyd"): + print "WARNING: Missing _tkinter.pyd" + else: + lib.start_component("TkDLLs", tcltk) + lib.add_file("_tkinter.pyd") + dlls.append("_tkinter.pyd") + tcldir = os.path.normpath(srcdir+"/../tcltk/bin") + for f in glob.glob1(tcldir, "*.dll"): + lib.add_file(f, src=os.path.join(tcldir, f)) # check whether there are any unknown extensions for f in glob.glob1(srcdir+"/PCBuild", "*.pyd"): if f.endswith("_d.pyd"): continue # debug version @@ -938,19 +945,20 @@ for f in dlls: lib.add_file(f.replace('pyd','lib')) lib.add_file('python%s%s.lib' % (major, minor)) - # Add Tcl/Tk - tcldirs = [(root, '../tcltk/lib', 'tcl')] - tcltk.set_current() - while tcldirs: - parent, phys, dir = tcldirs.pop() - lib = PyDirectory(db, cab, parent, phys, dir, "%s|%s" % (parent.make_short(dir), dir)) - if not os.path.exists(lib.absolute): - continue - for f in os.listdir(lib.absolute): - if os.path.isdir(os.path.join(lib.absolute, f)): - tcldirs.append((lib, f, f)) - else: - lib.add_file(f) + if have_tcl: + # Add Tcl/Tk + tcldirs = [(root, '../tcltk/lib', 'tcl')] + tcltk.set_current() + while tcldirs: + parent, phys, dir = tcldirs.pop() + lib = PyDirectory(db, cab, parent, phys, dir, "%s|%s" % (parent.make_short(dir), dir)) + if not os.path.exists(lib.absolute): + continue + for f in os.listdir(lib.absolute): + if os.path.isdir(os.path.join(lib.absolute, f)): + tcldirs.append((lib, f, f)) + else: + lib.add_file(f) # Add tools tools.set_current() tooldir = PyDirectory(db, cab, root, "Tools", "Tools", "TOOLS|Tools") @@ -965,8 +973,9 @@ x.glob("*.txt") if f == 'Scripts': lib.add_file("README.txt", src="README") - lib.start_component("pydocgui.pyw", tcltk, keyfile="pydocgui.pyw") - lib.add_file("pydocgui.pyw") + if have_tcl: + lib.start_component("pydocgui.pyw", tcltk, keyfile="pydocgui.pyw") + lib.add_file("pydocgui.pyw") # Add documentation htmlfiles.set_current() lib = PyDirectory(db, cab, root, "Doc", "Doc", "DOC|Doc") @@ -984,25 +993,32 @@ # IDLE verbs depend on the tcltk feature. # msidbComponentAttributesRegistryKeyPath = 4 # -1 for Root specifies "dependent on ALLUSERS property" + tcldata = [] + if have_tcl: + tcldata = [ + ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", 4, + "&%s <> 2" % ext_feature.id, "py.IDLE")] add_data(db, "Component", # msidbComponentAttributesRegistryKeyPath = 4 [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", 4, None, "InstallPath"), ("REGISTRY.def", msilib.gen_uuid(), "TARGETDIR", 4, - None, None), - ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", 4, - "&%s <> 2" % ext_feature.id, "py.IDLE")]) + None, None)] + tcldata) # See "FeatureComponents Table". # The association between TclTk and pythonw.exe is necessary to make ICE59 # happy, because the installer otherwise believes that the IDLE and PyDoc # shortcuts might get installed without pythonw.exe being install. This # is not true, since installing TclTk will install the default feature, which # will cause pythonw.exe to be installed. + tcldata = [] + if have_tcl: + tcltkdata = [(tcltk.id, "REGISTRY.tcl"), + (tcltk.id, "pythonw.exe")] add_data(db, "FeatureComponents", [(default_feature.id, "REGISTRY"), - (ext_feature.id, "REGISTRY.def"), - (tcltk.id, "REGISTRY.tcl"), - (tcltk.id, "pythonw.exe")]) + (ext_feature.id, "REGISTRY.def")] + + tcldata + ) pat = r"Software\Classes\%sPython.%sFile\shell\%s\command" ewi = "Edit with IDLE" @@ -1028,7 +1044,8 @@ # Non-advertised verbs: for advertised verbs, we would need to invoke the same # executable for both open and "Edit with IDLE". This cannot work, as we want # to use pythonw.exe in either case - add_data(db, "Registry", + if have_tcl: + add_data(db, "Registry", [#Verbs ("py.IDLE", -1, pat % (testprefix, "", ewi), "", r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -n -e "%1"', @@ -1058,12 +1075,17 @@ ("MenuDir", "ProgramMenuFolder", "PY%s%s|%sPython %s.%s" % (major,minor,testprefix,major,minor))]) add_data(db, "RemoveFile", [("MenuDir", "TARGETDIR", None, "MenuDir", 2)]) - add_data(db, "Shortcut", - [# Advertised shortcuts: targets are features, not files + tcltkshortcuts = [] + if have_tcl: + tcltkshortcuts = [ ("IDLE", "MenuDir", "IDLE|IDLE (Python GUI)", "pythonw.exe", tcltk.id, r"[TARGETDIR]Lib\idlelib\idle.pyw", None, None, "python_icon.exe", 0, None, "TARGETDIR"), ("PyDoc", "MenuDir", "MODDOCS|Module Docs", "pythonw.exe", tcltk.id, r"[TARGETDIR]Tools\scripts\pydocgui.pyw", None, None, "python_icon.exe", 0, None, "TARGETDIR"), + ] + add_data(db, "Shortcut", + tcltkshortcuts + + [# Advertised shortcuts: targets are features, not files ("Python", "MenuDir", "PYTHON|Python (command line)", "python.exe", default_feature.id, None, None, None, "python_icon.exe", 2, None, "TARGETDIR"), ("Manual", "MenuDir", "MANUAL|Python Manuals", "documentation", From anthonybaxter at users.sourceforge.net Wed Sep 1 17:02:26 2004 From: anthonybaxter at users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Wed Sep 1 17:33:11 2004 Subject: [Python-checkins] python/nondist/peps pep-0318.txt,1.30,1.31 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31156 Modified Files: pep-0318.txt Log Message: ding dong the witch is dead. or rather, the decorator discussion is. updating the pep. (I'm not sure if the "Community Concensus" section should be trimmed down radically now - it's a lot of words for a rejected form, and the case for the form is still available on the web and in the mailing list archives... opinions, anyone?) Index: pep-0318.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0318.txt,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- pep-0318.txt 30 Aug 2004 16:00:06 -0000 1.30 +++ pep-0318.txt 1 Sep 2004 15:02:22 -0000 1.31 @@ -8,49 +8,49 @@ Content-Type: text/x-rst Created: 05-Jun-2003 Python-Version: 2.4 -Post-History: 09-Jun-2003, 10-Jun-2003, 27-Feb-2004, 23-Mar-2004, 30-Aug-2004 +Post-History: 09-Jun-2003, 10-Jun-2003, 27-Feb-2004, 23-Mar-2004, 30-Aug-2004, +2-Sep-2004 WarningWarningWarning ===================== -The final decision on the syntax for 2.4a3 is not yet made. This will -be done before 2.4a3, and this document will be updated to match. -Note also that this document does not attempt to cover the huge number -of potential alternative syntaxes, nor is it an attempt to -exhaustively list all the positives and negatives of each form. +This document is meant to describe the decorator syntax and the +process that resulted in the decisions that were made. It does not +attempt to cover the huge number of potential alternative syntaxes, +nor is it an attempt to exhaustively list all the positives and +negatives of each form. Abstract ======== -The current method for transforming functions and methods (for -instance, declaring them as a class or static method) is awkward and -can lead to code that is difficult to understand. Ideally, these -transformations should be made at the same point in the code where the -declaration itself is made. This PEP introduces new syntax for -transformations of a function or method declaration. +The current method for transforming functions and methods (for instance, +declaring them as a class or static method) is awkward and can lead to +code that is difficult to understand. Ideally, these transformations +should be made at the same point in the code where the declaration +itself is made. This PEP introduces new syntax for transformations of a +function or method declaration. Motivation ========== -The current method of applying a transformation to a function or -method places the actual translation after the function body. For -large functions this separates a key component of the function's -behavior from the definition of the rest of the function's external -interface. For example:: +The current method of applying a transformation to a function or method +places the actual translation after the function body. For large +functions this separates a key component of the function's behavior from +the definition of the rest of the function's external interface. For +example:: def foo(self): perform method operation foo = classmethod(foo) This becomes less readable with longer methods. It also seems less -than pythonic to name the function three times for what is -conceptually a single declaration. A solution to this problem is to -move the transformation of the method closer to the method's own -declaration. While the new syntax is not yet final, the intent is to -replace:: +than pythonic to name the function three times for what is conceptually +a single declaration. A solution to this problem is to move the +transformation of the method closer to the method's own declaration. +While the new syntax is not yet final, the intent is to replace:: def foo(cls): pass @@ -65,41 +65,39 @@ def foo(cls): pass -Modifying classes in this fashion is also possible, though the -benefits are not as immediately apparent. Almost certainly, anything -which could be done with class decorators could be done using -metaclasses, but using metaclasses is sufficiently obscure that there -is some attraction to having an easier way to make simple -modifications to classes. For Python 2.4, only function/method -decorators are being added. +Modifying classes in this fashion is also possible, though the benefits +are not as immediately apparent. Almost certainly, anything which could +be done with class decorators could be done using metaclasses, but +using metaclasses is sufficiently obscure that there is some attraction +to having an easier way to make simple modifications to classes. For +Python 2.4, only function/method decorators are being added. Why Is This So Hard? -------------------- -Two decorators (``classmethod()`` and ``staticmethod()``) have -been available in Python since version 2.2. It's been assumed since +Two decorators (``classmethod()`` and ``staticmethod()``) have been +available in Python since version 2.2. It's been assumed since approximately that time that some syntactic support for them would eventually be added to the language. Given this assumption, one might -wonder why it's been so difficult to arrive at a consensus. -Discussions have raged off-and-on at times in both comp.lang.python -and the python-dev mailing list about how best to implement function -decorators. There is no one clear reason why this should be so, but a -few problems seem to be most problematic. +wonder why it's been so difficult to arrive at a consensus. Discussions +have raged off-and-on at times in both comp.lang.python and the +python-dev mailing list about how best to implement function decorators. +There is no one clear reason why this should be so, but a few problems +seem to be most problematic. * Disagreement about where the "declaration of intent" belongs. - Almost everyone agrees that decorating/transforming a function at - the end of its definition is suboptimal. Beyond that there seems to - be no clear consensus where to place this information. + Almost everyone agrees that decorating/transforming a function at the + end of its definition is suboptimal. Beyond that there seems to be no + clear consensus where to place this information. * Syntactic constraints. Python is a syntactically simple language with fairly strong constraints on what can and can't be done without "messing things up" (both visually and with regards to the language parser). There's no obvious way to structure this information so that people new to the concept will think, "Oh yeah, I know what - you're doing." The best that seems possible is to keep new users - from creating a wildly incorrect mental model of what the syntax - means. + you're doing." The best that seems possible is to keep new users from + creating a wildly incorrect mental model of what the syntax means. * Overall unfamiliarity with the concept. For people who have a passing acquaintance with algebra (or even basic arithmetic) or have @@ -109,7 +107,7 @@ strong preexisting meme that captures the concept. * Syntax discussions in general appear to cause more contention than - almost anything else. Readers are pointed to the ternary operator + almost anything else. Readers are pointed to the ternary operator discussions that were associated with PEP 308 for another example of this. @@ -117,12 +115,12 @@ Background ========== -There is general agreement that syntactic support is desirable to the -current state of affairs. Guido mentioned `syntactic support for -decorators`_ in his DevDay keynote presentation at the `10th Python -Conference`_, though `he later said`_ it was only one of several -extensions he proposed there "semi-jokingly". `Michael Hudson raised -the topic`_ on ``python-dev`` shortly after the conference, +There is general agreement that syntactic support is desirable to +the current state of affairs. Guido mentioned `syntactic support +for decorators`_ in his DevDay keynote presentation at the `10th +Python Conference`_, though `he later said`_ it was only one of +several extensions he proposed there "semi-jokingly". `Michael Hudson +raised the topic`_ on ``python-dev`` shortly after the conference, attributing the initial bracketed syntax to an earlier proposal on ``comp.lang.python`` by `Gareth McCaughan`_. @@ -138,18 +136,21 @@ http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=slrna40k88.2h9o.Gareth.McCaughan%40g.local Class decorations seem like an obvious next step because class -definition and function definition are syntactically similar. +definition and function definition are syntactically similar, +however Guido remains unconvinced, and class decorators will almost +certainly not be in Python 2.4. -The discussion continued on and off on python-dev from February 2002 -through July 2004. Hundreds and hundreds of posts were made, with -people proposing many possible syntax variations. Guido took a list -of proposals to `EuroPython 2004`_, where a discussion took place. -Subsequent to this, he decided that for 2.4a2 we'd have the -`Java-style`_ @decorator syntax. Barry Warsaw named this the -'pie-decorator' syntax, in honor of the Pie-thon Parrot shootout which -was announced about the same time as the decorator syntax, and because -the @ looks a little like a pie. Guido `outlined his case`_ on -Python-dev, including `this piece`_ on the various rejected forms. +The discussion continued on and off on python-dev from February +2002 through July 2004. Hundreds and hundreds of posts were made, +with people proposing many possible syntax variations. Guido took +a list of proposals to `EuroPython 2004`_, where a discussion took +place. Subsequent to this, he decided that we'd have the `Java-style`_ +@decorator syntax, and this appeared for the first time in 2.4a2. +Barry Warsaw named this the 'pie-decorator' syntax, in honor of the +Pie-thon Parrot shootout which was occured around the same time as +the decorator syntax, and because the @ looks a little like a pie. +Guido `outlined his case`_ on Python-dev, including `this piece`_ +on some of the (many) rejected forms. .. _EuroPython 2004: http://www.python.org/doc/essays/ppt/euro2004/euro2004.pdf @@ -199,8 +200,8 @@ frequently * not make it more difficult to scan through code quickly. It should - still be easy to search for all definitions, a particular - definition, or the arguments that a function accepts + still be easy to search for all definitions, a particular definition, + or the arguments that a function accepts * not needlessly complicate secondary support tools such as language-sensitive editors and other "`toy parser tools out @@ -208,8 +209,8 @@ * allow future compilers to optimize for decorators. With the hope of a JIT compiler for Python coming into existence at some point this - tends to require the syntax for decorators to come before the - function definition + tends to require the syntax for decorators to come before the function + definition * move from the end of the function, where it's currently hidden, to the front where it is more `in your face`_ @@ -246,8 +247,8 @@ func = dec2(dec1(func)) without the intermediate assignment to the variable ``func``. The -decorators are near the function declaration. The @ sign makes it -clear that something new is going on here. +decorators are near the function declaration. The @ sign makes it clear +that something new is going on here. The decorator statement is limited in what it can accept -- arbitrary expressions will not work. Guido preferred this because of a `gut @@ -278,8 +279,8 @@ The first syntax point is the location of the decorators. For the following examples, we use the @syntax used in 2.4a2. -Decorators before the def statement are the first alternative, -and the syntax used in 2.4a2:: +Decorators before the def statement are the first alternative, and the +syntax used in 2.4a2:: @classmethod def foo(arg1,arg2): @@ -290,36 +291,36 @@ def bar(low,high): pass -There have been a number of objections raised to this location -- -the primary one is that it's the first real Python case where a -line of code has a result on a following line. The syntax that -will be in 2.4a3 will also require one decorator per line (in a2, -multiple decorators can be specified on the same line). +There have been a number of objections raised to this location -- the +primary one is that it's the first real Python case where a line of code +has a result on a following line. The syntax available for in 2.4a3 +requires one decorator per line (in a2, multiple decorators could be +specified on the same line). People also complained that the syntax got unworldly quickly when multiple decorators were used. The point was made, though, that the chances of a large number of decorators being used on a single function were small and thus this was not a large worry. -Some of the advantages of this form are that the decorators live -outside the method body -- they are obviously executed at the time -the function is defined. +Some of the advantages of this form are that the decorators live outside +the method body -- they are obviously executed at the time the function +is defined. -Another advantage is that being prefix to the function definition fit the -idea of knowing about a change to the semantics of the code before the -code itself, thus knowing how to interpret the code's semantics +Another advantage is that being prefix to the function definition fit +the idea of knowing about a change to the semantics of the code before +the code itself, thus knowing how to interpret the code's semantics properly without having to go back and change your initial perceptions if the syntax did not come before the function definition. Guido decided `he preferred`_ having the decorators on the line before -the 'def', because it was felt that a long argument list would mean -that the decorators would be 'hidden' +the 'def', because it was felt that a long argument list would mean that +the decorators would be 'hidden' .. _he preferred: http://mail.python.org/pipermail/python-dev/2004-March/043756.html -The second form is the decorators between the def and the function -name, or the function name and the argument list:: +The second form is the decorators between the def and the function name, +or the function name and the argument list:: def @classmethod foo(arg1,arg2): pass @@ -336,12 +337,12 @@ There are a couple of objections to this form. The first is that it breaks easily 'greppability' of the source -- you can no longer search for 'def foo(' and find the definition of the function. The second, -more serious, objection is that in the case of multiple decorators, -the syntax would be extremely unwieldy. +more serious, objection is that in the case of multiple decorators, the +syntax would be extremely unwieldy. -The next form, which has had a number of strong proponents, is to -have the decorators between the argument list and the trailing ``:`` -in the 'def' line:: +The next form, which has had a number of strong proponents, is to have +the decorators between the argument list and the trailing ``:`` in the +'def' line:: def foo(arg1,arg2) @classmethod: pass @@ -349,8 +350,8 @@ def bar(low,high) @accepts(int,int),@returns(float): pass -Guido `summarized the arguments`_ against this form (many of which -also apply to the previous form) as: +Guido `summarized the arguments`_ against this form (many of which also +apply to the previous form) as: - it hides crucial information (e.g. that it is a static method) after the signature, where it is easily missed @@ -364,9 +365,8 @@ .. _summarized the arguments: http://mail.python.org/pipermail/python-dev/2004-August/047112.html -The next form is that the decorator syntax go inside the method -body at the start, in the same place that docstrings currently -live: +The next form is that the decorator syntax go inside the method body at +the start, in the same place that docstrings currently live: def foo(arg1,arg2): @classmethod @@ -377,16 +377,16 @@ @returns(float) pass -The primary objection to this form is that it requires "peeking -inside" the method body to determine the decorators. In addition, -even though the code is inside the method body, it is not executed -when the method is run. Guido felt that docstrings were not a good -counter-example, and that it was quite possible that a 'docstring' -decorator could help move the docstring to outside the function body. +The primary objection to this form is that it requires "peeking inside" +the method body to determine the decorators. In addition, even though +the code is inside the method body, it is not executed when the method +is run. Guido felt that docstrings were not a good counter-example, and +that it was quite possible that a 'docstring' decorator could help move +the docstring to outside the function body. -The final form is a new block that encloses the method's code. For -this example, we'll use a 'decorate' keyword, as it makes no sense -with the @syntax. :: +The final form is a new block that encloses the method's code. For this +example, we'll use a 'decorate' keyword, as it makes no sense with the +@syntax. :: decorate: classmethod @@ -400,8 +400,8 @@ pass This form would result in inconsistent indentation for decorated and -undecorated methods. In addition, a decorated method's body would -start three indent levels in. +undecorated methods. In addition, a decorated method's body would start +three indent levels in. Syntax forms @@ -420,7 +420,7 @@ The major objections against this syntax are that the @ symbol is not currently used in Python (and is used in both IPython and Leo), - and that the @ symbol is not meaningful. Another objection is that + and that the @ symbol is not meaningful. Another objection is that this "wastes" a currently unused character (from a limited set) on something that is not perceived as a major use. @@ -437,8 +437,8 @@ This is a variant on the @decorator syntax -- it has the advantage that it does not break IPython and Leo. Its major disadvantage - compared to the @syntax is that the | symbol looks like both a - capital I and a lowercase l. + compared to the @syntax is that the | symbol looks like both a capital + I and a lowercase l. * list syntax:: @@ -474,28 +474,29 @@ * ``decorate()`` - The ``decorate()`` proposal was that no new syntax be implemented -- - instead a magic function that used introspection to manipulate the - following function. Both Jp Calderone and Philip Eby produced + The ``decorate()`` proposal was that no new syntax be implemented + -- instead a magic function that used introspection to manipulate + the following function. Both Jp Calderone and Philip Eby produced implementations of functions that did this. Guido was pretty firmly against this -- with no new syntax, the magicness of a function like this is extremely high: - Using functions with "action-at-a-distance" through - sys.settraceback may be okay for an obscure feature that can't be - had any other way yet doesn't merit changes to the language, but - that's not the situation for decorators. The widely held view - here is that decorators need to be added as a syntactic feature to - avoid the problems with the postfix notation used in 2.2 and 2.3. - Decorators are slated to be an important new language feature and - their design needs to be forward-looking, not constrained by what - can be implemented in 2.3. + Using functions with "action-at-a-distance" through sys.settraceback + may be okay for an obscure feature that can't be had any other + way yet doesn't merit changes to the language, but that's not + the situation for decorators. The widely held view here is that + decorators need to be added as a syntactic feature to avoid the + problems with the postfix notation used in 2.2 and 2.3. Decorators + are slated to be an important new language feature and their + design needs to be forward-looking, not constrained by what can be + implemented in 2.3. * _`new keyword (and block)` - This idea was the consensus alternate from comp.lang.python. Robert - Brewer wrote up a detailed `J2 proposal`_ document outlining the - arguments in favor of this. The issues with this form are: + This idea was the consensus alternate from comp.lang.python (more + on this in `Community Consensus`_ below.) Robert Brewer wrote up a + detailed `J2 proposal`_ document outlining the arguments in favor of + this form. The initial issues with this form are: - It requires a new keyword, and therefore a ``from __future__ import decorators`` statement. @@ -508,12 +509,39 @@ code block, but isn't. Attempts to use statements in this block will cause a syntax error, which may confuse users. - See `Community Consensus`_ below. + A few days later, Guido `rejected the proposal`_ on two main grounds, + firstly: + + ... the syntactic form of an indented block strongly + suggests that its contents should be a sequence of statements, but + in fact it is not -- only expressions are allowed, and there is an + implicit "collecting" of these expressions going on until they can + be applied to the subsequent function definition. ... + + and secondly: + + ... the keyword starting the line that heads a block + draws a lot of attention to it. This is true for "if", "while", + "for", "try", "def" and "class". But the "using" keyword (or any + other keyword in its place) doesn't deserve that attention; the + emphasis should be on the decorator or decorators inside the suite, + since those are the important modifiers to the function definition + that follows. ... + + Readers are invited to read `the full response`_. .. _J2 proposal: http://www.aminus.org/rbre/python/pydec.html -There are plenty of other variants and proposals on `the wiki page`_. + .. _rejected the proposal: + http://mail.python.org/pipermail/python-dev/2004-September/048518.html + + .. _the full response: + http://mail.python.org/pipermail/python-dev/2004-September/048518.html + +* Other forms + + There are plenty of other variants and proposals on `the wiki page`_. .. _the wiki page: http://www.python.org/moin/PythonDecorators @@ -522,18 +550,18 @@ Why @? ------ -There is some history in Java using @ initially as a marker in -`Javadoc comments`_ and later in Java 1.5 for `annotations`_, which -are similar to Python decorators. The fact that @ was previously -unused as a token in Python also means it's clear there is no -possibility of such code being parsed by an earlier version of Python, -leading to possibly subtle semantic bugs. It also means that ambiguity -of what is a decorator and what isn't is removed. of That said, @ is -still a fairly arbitrary choice. Some have suggested using | instead. +There is some history in Java using @ initially as a marker in `Javadoc +comments`_ and later in Java 1.5 for `annotations`_, which are similar +to Python decorators. The fact that @ was previously unused as a token +in Python also means it's clear there is no possibility of such code +being parsed by an earlier version of Python, leading to possibly subtle +semantic bugs. It also means that ambiguity of what is a decorator +and what isn't is removed. of That said, @ is still a fairly arbitrary +choice. Some have suggested using | instead. For syntax options which use a list-like syntax (no matter where it appears) to specify the decorators a few alternatives were proposed: -``[|...|]``, ``*[...]*``, and ``<...>``. +``[|...|]``, ``*[...]*``, and ``<...>``. .. _Javadoc comments: http://java.sun.com/j2se/javadoc/writingdoccomments/ @@ -545,8 +573,8 @@ =============================== Guido asked for a volunteer to implement his preferred syntax, and Mark -Russell stepped up and posted a `patch`_ to SF. The syntax accepted -for 2.4a2 is:: +Russell stepped up and posted a `patch`_ to SF. This new syntax was +available in 2.4a2. :: @dec2 @dec1 @@ -561,6 +589,10 @@ though without the intermediate creation of a variable named ``func``. +The version implemented in 2.4a2 allowed multiple ``@decorator`` clauses +on a single line. In 2.4a3, this was tightened up to only allowing one +decorator per line. + A `previous patch`_ from Michael Hudson which implements the list-after-def syntax is also still kicking around. @@ -572,19 +604,44 @@ could come up with a community consensus, a decent proposal, and an implementation. After an amazing number of posts, collecting a vast number of alternatives in the `Python wiki`_, a community consensus -emerged (below). As at time of writing, we're waiting for Guido's -decision. +emerged (below). Guido `subsequently rejected`_ this alternate form, +but added: + + In Python 2.4a3 (to be released this Thursday), everything remains + as currently in CVS. For 2.4b1, I will consider a change of @ to + some other single character, even though I think that @ has the + advantage of being the same character used by a similar feature + in Java. It's been argued that it's not quite the same, since @ + in Java is used for attributes that don't change semantics. But + Python's dynamic nature makes that its syntactic elements never mean + quite the same thing as similar constructs in other languages, and + there is definitely significant overlap. Regarding the impact on + 3rd party tools: IPython's author doesn't think there's going to be + much impact; Leo's author has said that Leo will survive (although + it will cause him and his users some transitional pain). I actually + expect that picking a character that's already used elsewhere in + Python's syntax might be harder for external tools to adapt to, + since parsing will have to be more subtle in that case. But I'm + frankly undecided, so there's some wiggle room here. I don't want + to consider further syntactic alternatives at this point: the buck + has to stop at some point, everyone has had their say, and the show + must go on. .. _Python wiki: http://www.python.org/moin/PythonDecorators +.. _subsequently rejected: + http://mail.python.org/pipermail/python-dev/2004-September/048518.html Community Consensus ------------------- -The consensus that emerged was for the proposed J2 syntax: the new -keyword ``using`` prefixing a block of decorators before the ``def`` -statement. For example:: +[editor's note: should this section be removed now?] + +The consensus that emerged on comp.lang.python was the proposed J2 +syntax (the "J2" was how it was referenced on the PythonDecorators wiki +page): the new keyword ``using`` prefixing a block of decorators before +the ``def`` statement. For example:: using: classmethod @@ -613,15 +670,21 @@ .. _a patch: http://www.python.org/sf/1013835 +As noted previously, Guido rejected this form, outlining his problems +with it in `a message`_ to python-dev and comp.lang.python. + +.. _a message: + http://mail.python.org/pipermail/python-dev/2004-September/048518.html + Examples ======== Much of the discussion on ``comp.lang.python`` and the ``python-dev`` mailing list focuses on the use of decorators as a cleaner way to use -the ``staticmethod()`` and ``classmethod()`` builtins. This -capability is much more powerful than that. This section presents -some examples of use. +the ``staticmethod()`` and ``classmethod()`` builtins. This capability +is much more powerful than that. This section presents some examples of +use. 1. Define a function to be executed at exit. Note that the function isn't actually "wrapped" in the usual sense. :: @@ -639,9 +702,8 @@ is for example purposes only. 2. Define a class with a singleton instance. Note that once the class - disappears enterprising programmers would have to be more creative - to create more instances. (From Shane Hathaway on ``python-dev``.) - :: + disappears enterprising programmers would have to be more creative to + create more instances. (From Shane Hathaway on ``python-dev``.) :: def singleton(cls): instances = {} @@ -734,14 +796,17 @@ =========== 1. It's not yet certain that class decorators will be incorporated - into the language at this point. Guido expressed skepticism about + into the language at a future point. Guido expressed skepticism about the concept, but various people have made some `strong arguments`_ (search for ``PEP 318 -- posting draft``) on their behalf in - ``python-dev``. + ``python-dev``. It's exceedingly unlikely that class decorators + will be in Python 2.4. .. _strong arguments: http://mail.python.org/pipermail/python-dev/2004-March/thread.html +2. The choice of the ``@`` character will be re-examined before + Python 2.4b1. Copyright ========= From akuchling at users.sourceforge.net Wed Sep 1 17:44:36 2004 From: akuchling at users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed Sep 1 17:44:39 2004 Subject: [Python-checkins] python/nondist/peps pep-0318.txt,1.31,1.32 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8465 Modified Files: pep-0318.txt Log Message: Minor polishing of words Index: pep-0318.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0318.txt,v retrieving revision 1.31 retrieving revision 1.32 diff -u -d -r1.31 -r1.32 --- pep-0318.txt 1 Sep 2004 15:02:22 -0000 1.31 +++ pep-0318.txt 1 Sep 2004 15:44:33 -0000 1.32 @@ -37,7 +37,7 @@ ========== The current method of applying a transformation to a function or method -places the actual translation after the function body. For large +places the actual transformation after the function body. For large functions this separates a key component of the function's behavior from the definition of the rest of the function's external interface. For example:: @@ -84,7 +84,7 @@ have raged off-and-on at times in both comp.lang.python and the python-dev mailing list about how best to implement function decorators. There is no one clear reason why this should be so, but a few problems -seem to be most problematic. +seem to be most divisive. * Disagreement about where the "declaration of intent" belongs. Almost everyone agrees that decorating/transforming a function at the @@ -293,11 +293,11 @@ There have been a number of objections raised to this location -- the primary one is that it's the first real Python case where a line of code -has a result on a following line. The syntax available for in 2.4a3 +has an effect on a following line. The syntax available in 2.4a3 requires one decorator per line (in a2, multiple decorators could be specified on the same line). -People also complained that the syntax got unworldly quickly when +People also complained that the syntax quickly got unwieldy when multiple decorators were used. The point was made, though, that the chances of a large number of decorators being used on a single function were small and thus this was not a large worry. @@ -306,9 +306,9 @@ the method body -- they are obviously executed at the time the function is defined. -Another advantage is that being prefix to the function definition fit +Another advantage is that a prefix to the function definition fits the idea of knowing about a change to the semantics of the code before -the code itself, thus knowing how to interpret the code's semantics +the code itself, thus you know how to interpret the code's semantics properly without having to go back and change your initial perceptions if the syntax did not come before the function definition. @@ -365,7 +365,7 @@ .. _summarized the arguments: http://mail.python.org/pipermail/python-dev/2004-August/047112.html -The next form is that the decorator syntax go inside the method body at +The next form is that the decorator syntax goes inside the method body at the start, in the same place that docstrings currently live: def foo(arg1,arg2): @@ -556,7 +556,7 @@ in Python also means it's clear there is no possibility of such code being parsed by an earlier version of Python, leading to possibly subtle semantic bugs. It also means that ambiguity of what is a decorator -and what isn't is removed. of That said, @ is still a fairly arbitrary +and what isn't is removed. That said, @ is still a fairly arbitrary choice. Some have suggested using | instead. For syntax options which use a list-like syntax (no matter where it From fdrake at acm.org Wed Sep 1 17:45:26 2004 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Wed Sep 1 17:45:35 2004 Subject: [Python-checkins] python/nondist/peps pep-0318.txt,1.30,1.31 In-Reply-To: References: Message-ID: <200409011145.26772.fdrake@acm.org> On Wednesday 01 September 2004 11:02 am, anthonybaxter@users.sourceforge.net wrote: > (I'm not sure if the "Community Concensus" section should be trimmed > down radically now - it's a lot of words for a rejected form, and the > case for the form is still available on the web and in the mailing > list archives... opinions, anyone?) I'm for leaving the text in; wikis are fragile, and this is a valuable bit of Python history. A reader can ignore it if that's not interesting to them. -Fred -- Fred L. Drake, Jr. From gvanrossum at gmail.com Wed Sep 1 17:52:58 2004 From: gvanrossum at gmail.com (Guido van Rossum) Date: Wed Sep 1 17:53:06 2004 Subject: [Python-checkins] python/nondist/peps pep-0318.txt,1.30,1.31 In-Reply-To: <200409011145.26772.fdrake@acm.org> References: <200409011145.26772.fdrake@acm.org> Message-ID: > > (I'm not sure if the "Community Concensus" section should be trimmed > > down radically now - it's a lot of words for a rejected form, and the > > case for the form is still available on the web and in the mailing > > list archives... opinions, anyone?) > > I'm for leaving the text in; wikis are fragile, and this is a valuable bit of > Python history. A reader can ignore it if that's not interesting to them. +1 -- --Guido van Rossum (home page: http://www.python.org/~guido/) Ask me about gmail. From anthonybaxter at users.sourceforge.net Wed Sep 1 18:18:37 2004 From: anthonybaxter at users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Wed Sep 1 18:18:40 2004 Subject: [Python-checkins] python/nondist/peps pep-0000.txt,1.287,1.288 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14628 Modified Files: pep-0000.txt Log Message: pep318 is accepted Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.287 retrieving revision 1.288 diff -u -d -r1.287 -r1.288 --- pep-0000.txt 27 Aug 2004 20:28:57 -0000 1.287 +++ pep-0000.txt 1 Sep 2004 16:18:20 -0000 1.288 @@ -66,6 +66,7 @@ S 252 Making Types Look More Like Classes GvR S 253 Subtyping Built-in Types GvR SA 309 Partial Function Application Harris + SA 318 Decorators for Functions and Methods Smith, et al SA 328 Imports: Multi-Line and Absolute/Relative Aahz Open PEPs (under consideration) @@ -112,7 +113,6 @@ S 313 Adding Roman Numeral Literals to Python Meyer S 314 Metadata for Python Software Packages v1.1 Kuchling S 315 Enhanced While Loop Carroll - S 318 Decorators for Functions and Methods Smith, et al S 319 Python Synchronize/Asynchronize Block Pelletier S 321 Date/Time Parsing and Formatting Kuchling S 323 Copyable Iterators Martelli @@ -346,7 +346,7 @@ S 315 Enhanced While Loop Carroll SD 316 Programming by Contract for Python Way SR 317 Eliminate Implicit Exception Instantiation Taschuk - S 318 Decorators for Functions, Methods & Classes Smith, et al + SA 318 Decorators for Functions and Methods Smith, et al S 319 Python Synchronize/Asynchronize Block Pelletier I 320 Python 2.4 Release Schedule Warsaw S 321 Date/Time Parsing and Formatting Kuchling From loewis at users.sourceforge.net Wed Sep 1 20:29:28 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed Sep 1 20:29:31 2004 Subject: [Python-checkins] python/dist/src/PCbuild BUILDno.txt, 1.60, 1.61 pythoncore.vcproj, 1.19, 1.20 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8741 Modified Files: BUILDno.txt pythoncore.vcproj Log Message: Update buildno for 2.4a3 Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.60 retrieving revision 1.61 diff -u -d -r1.60 -r1.61 --- BUILDno.txt 4 Aug 2004 13:42:43 -0000 1.60 +++ BUILDno.txt 1 Sep 2004 18:29:25 -0000 1.61 @@ -33,6 +33,8 @@ Windows Python BUILD numbers ---------------------------- + 56 2.4.0a3 + 2-Sep-2004 55 2.4.0a2 4-Aug-2004 54 2.4.0a1 Index: pythoncore.vcproj =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.vcproj,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- pythoncore.vcproj 31 Aug 2004 14:29:12 -0000 1.19 +++ pythoncore.vcproj 1 Sep 2004 18:29:25 -0000 1.20 @@ -1382,7 +1382,7 @@ Name="VCCLCompilerTool" Optimization="2" AdditionalIncludeDirectories="" - PreprocessorDefinitions="BUILD=55"/> + PreprocessorDefinitions="BUILD=56"/> @@ -1390,7 +1390,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="" - PreprocessorDefinitions="BUILD=55"/> + PreprocessorDefinitions="BUILD=56"/> @@ -1398,7 +1398,7 @@ Name="VCCLCompilerTool" Optimization="2" AdditionalIncludeDirectories="" - PreprocessorDefinitions="BUILD=55"/> + PreprocessorDefinitions="BUILD=56"/> Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2121 Modified Files: pep-0333.txt Log Message: Fix some typos, and clean up/clarify language regarding iterables so that Alan's Jython-based server will be compatible with the "letter of the law" of the spec. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- pep-0333.txt 1 Sep 2004 13:44:07 -0000 1.6 +++ pep-0333.txt 1 Sep 2004 20:35:42 -0000 1.7 @@ -773,11 +773,18 @@ more complex: * You may not return a file object and expect it to work as an iterable, - since before Python 2.2, files were not iterable. + since before Python 2.2, files were not iterable. (Some servers + may loosen this guideline by checking for ``types.FileType``, but + this is an optional, server-specific extension. If you want your + application code to be used with pre-2.2 Pythons such as Jython, + you should *not* return a file object; use a pre-2.2 iterable + or a sequence instead.) -* If you return an iterable, it **must** implement the pre-2.2 iterator - protocol. That is, provide a ``__getitem__`` method that accepts - an integer key, and raises ``IndexError`` when exhausted. +* If you return a custom iterable, it **must** implement the pre-2.2 + iterator protocol. That is, provide a ``__getitem__`` method that + accepts an integer key, and raises ``IndexError`` when exhausted. + (Note that built-in sequence types are also acceptable, since they + also implement this protocol.) Finally, middleware that wishes to support pre-2.2 versions of Python, and iterates over application return values or itself returns an @@ -863,7 +870,7 @@ ``fileno`` attribute if it is anything other than a method returning an **operating system file descriptor**. "File-like" objects that do not possess a true operating system file descriptor number -are expressly. Servers running on platforms where file +are expressly forbidden. Servers running on platforms where file descriptors do not exist, or where there is no meaningful API for accelerating transmission from a file descriptor should ignore the ``fileno`` attribute. From mhammond at users.sourceforge.net Thu Sep 2 00:31:26 2004 From: mhammond at users.sourceforge.net (mhammond@users.sourceforge.net) Date: Thu Sep 2 00:31:30 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_capi.py, 1.6, 1.6.10.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22421/Lib/test Modified Files: Tag: release23-maint test_capi.py Log Message: Backport [ 1010677 ] thread Module Breaks PyGILState_Ensure() to the 2.3 maint branch. Index: test_capi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_capi.py,v retrieving revision 1.6 retrieving revision 1.6.10.1 diff -u -d -r1.6 -r1.6.10.1 --- test_capi.py 24 Apr 2003 16:02:51 -0000 1.6 +++ test_capi.py 1 Sep 2004 22:31:22 -0000 1.6.10.1 @@ -43,3 +43,6 @@ if have_thread_state: TestThreadState() + import threading + t = threading.Thread(target=TestThreadState) + t.start() From mhammond at users.sourceforge.net Thu Sep 2 00:31:26 2004 From: mhammond at users.sourceforge.net (mhammond@users.sourceforge.net) Date: Thu Sep 2 00:31:31 2004 Subject: [Python-checkins] python/dist/src/Modules threadmodule.c, 2.56, 2.56.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22421/Modules Modified Files: Tag: release23-maint threadmodule.c Log Message: Backport [ 1010677 ] thread Module Breaks PyGILState_Ensure() to the 2.3 maint branch. Index: threadmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/threadmodule.c,v retrieving revision 2.56 retrieving revision 2.56.8.1 diff -u -d -r2.56 -r2.56.8.1 --- threadmodule.c 16 Jun 2003 18:51:28 -0000 2.56 +++ threadmodule.c 1 Sep 2004 22:31:23 -0000 2.56.8.1 @@ -172,11 +172,10 @@ t_bootstrap(void *boot_raw) { struct bootstate *boot = (struct bootstate *) boot_raw; - PyThreadState *tstate; + PyGILState_STATE gstate; PyObject *res; - tstate = PyThreadState_New(boot->interp); - PyEval_AcquireThread(tstate); + gstate = PyGILState_Ensure(); res = PyEval_CallObjectWithKeywords( boot->func, boot->args, boot->keyw); if (res == NULL) { @@ -201,8 +200,7 @@ Py_DECREF(boot->args); Py_XDECREF(boot->keyw); PyMem_DEL(boot_raw); - PyThreadState_Clear(tstate); - PyThreadState_DeleteCurrent(); + PyGILState_Release(gstate); PyThread_exit_thread(); } From goodger at users.sourceforge.net Thu Sep 2 01:40:15 2004 From: goodger at users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu Sep 2 01:40:22 2004 Subject: [Python-checkins] python/nondist/peps pep-0318.txt,1.32,1.33 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3051 Modified Files: pep-0318.txt Log Message: whitespace Index: pep-0318.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0318.txt,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- pep-0318.txt 1 Sep 2004 15:44:33 -0000 1.32 +++ pep-0318.txt 1 Sep 2004 23:40:12 -0000 1.33 @@ -9,16 +9,16 @@ Created: 05-Jun-2003 Python-Version: 2.4 Post-History: 09-Jun-2003, 10-Jun-2003, 27-Feb-2004, 23-Mar-2004, 30-Aug-2004, -2-Sep-2004 + 2-Sep-2004 WarningWarningWarning ===================== This document is meant to describe the decorator syntax and the -process that resulted in the decisions that were made. It does not -attempt to cover the huge number of potential alternative syntaxes, -nor is it an attempt to exhaustively list all the positives and +process that resulted in the decisions that were made. It does not +attempt to cover the huge number of potential alternative syntaxes, +nor is it an attempt to exhaustively list all the positives and negatives of each form. @@ -144,12 +144,12 @@ 2002 through July 2004. Hundreds and hundreds of posts were made, with people proposing many possible syntax variations. Guido took a list of proposals to `EuroPython 2004`_, where a discussion took -place. Subsequent to this, he decided that we'd have the `Java-style`_ -@decorator syntax, and this appeared for the first time in 2.4a2. -Barry Warsaw named this the 'pie-decorator' syntax, in honor of the -Pie-thon Parrot shootout which was occured around the same time as -the decorator syntax, and because the @ looks a little like a pie. -Guido `outlined his case`_ on Python-dev, including `this piece`_ +place. Subsequent to this, he decided that we'd have the `Java-style`_ +@decorator syntax, and this appeared for the first time in 2.4a2. +Barry Warsaw named this the 'pie-decorator' syntax, in honor of the +Pie-thon Parrot shootout which was occured around the same time as +the decorator syntax, and because the @ looks a little like a pie. +Guido `outlined his case`_ on Python-dev, including `this piece`_ on some of the (many) rejected forms. .. _EuroPython 2004: @@ -293,7 +293,7 @@ There have been a number of objections raised to this location -- the primary one is that it's the first real Python case where a line of code -has an effect on a following line. The syntax available in 2.4a3 +has an effect on a following line. The syntax available in 2.4a3 requires one decorator per line (in a2, multiple decorators could be specified on the same line). @@ -446,9 +446,9 @@ def foo(arg1,arg2): pass - [accepts(int,int), returns(float)] - def bar(low,high): - pass + [accepts(int,int), returns(float)] + def bar(low,high): + pass The major objection to the list syntax is that it's currently meaningful (when used in the form before the method). It's also @@ -461,8 +461,8 @@ pass - def bar(low,high): - pass + def bar(low,high): + pass None of these alternatives gained much traction. The alternatives which involve square brackets only serve to make it obvious that the @@ -539,7 +539,7 @@ .. _the full response: http://mail.python.org/pipermail/python-dev/2004-September/048518.html -* Other forms +* Other forms There are plenty of other variants and proposals on `the wiki page`_. @@ -573,7 +573,7 @@ =============================== Guido asked for a volunteer to implement his preferred syntax, and Mark -Russell stepped up and posted a `patch`_ to SF. This new syntax was +Russell stepped up and posted a `patch`_ to SF. This new syntax was available in 2.4a2. :: @dec2 @@ -667,7 +667,7 @@ .. _detailed proposal: http://www.aminus.org/rbre/python/pydec.html -.. _a patch: +.. _a patch: http://www.python.org/sf/1013835 As noted previously, Guido rejected this form, outlining his problems @@ -732,7 +732,7 @@ def mymethod(f): ... -4. Enforce function argument and return types. Note that this +4. Enforce function argument and return types. Note that this copies the func_name attribute from the old to the new function. func_name was made writable in Python 2.4a3:: @@ -799,13 +799,13 @@ into the language at a future point. Guido expressed skepticism about the concept, but various people have made some `strong arguments`_ (search for ``PEP 318 -- posting draft``) on their behalf in - ``python-dev``. It's exceedingly unlikely that class decorators + ``python-dev``. It's exceedingly unlikely that class decorators will be in Python 2.4. .. _strong arguments: http://mail.python.org/pipermail/python-dev/2004-March/thread.html -2. The choice of the ``@`` character will be re-examined before +2. The choice of the ``@`` character will be re-examined before Python 2.4b1. Copyright From anthonybaxter at users.sourceforge.net Thu Sep 2 18:37:18 2004 From: anthonybaxter at users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Thu Sep 2 18:37:20 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1126,1.1127 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7255/Misc Modified Files: NEWS Log Message: release date Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1126 retrieving revision 1.1127 diff -u -d -r1.1126 -r1.1127 --- NEWS 31 Aug 2004 13:50:43 -0000 1.1126 +++ NEWS 2 Sep 2004 16:37:15 -0000 1.1127 @@ -7,7 +7,7 @@ What's New in Python 2.4 alpha 3? ================================= -*Release date: XX-XXX-2004* +*Release date: 02-SEP-2004* Core and builtins ----------------- From anthonybaxter at users.sourceforge.net Thu Sep 2 18:37:53 2004 From: anthonybaxter at users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Thu Sep 2 18:37:57 2004 Subject: [Python-checkins] python/dist/src README,1.182,1.183 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7378 Modified Files: README Log Message: update version Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.182 retrieving revision 1.183 diff -u -d -r1.182 -r1.183 --- README 8 Jun 2004 08:17:30 -0000 1.182 +++ README 2 Sep 2004 16:37:51 -0000 1.183 @@ -1,4 +1,4 @@ -This is Python version 2.4 alpha 1 +This is Python version 2.4 alpha 3 ================================== Copyright (c) 2001, 2002, 2003, 2004 Python Software Foundation. From anthonybaxter at users.sourceforge.net Thu Sep 2 18:38:23 2004 From: anthonybaxter at users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Thu Sep 2 18:38:26 2004 Subject: [Python-checkins] python/dist/src/Misc/RPM python-2.4.spec,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Misc/RPM In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7466/Misc/RPM Modified Files: python-2.4.spec Log Message: update version Index: python-2.4.spec =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/RPM/python-2.4.spec,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- python-2.4.spec 8 Jul 2004 06:01:42 -0000 1.2 +++ python-2.4.spec 2 Sep 2004 16:38:20 -0000 1.3 @@ -30,7 +30,7 @@ ################################# %define name python -%define version 2.4a1 +%define version 2.4a3 %define libvers 2.4 %define release 1pydotorg %define __prefix /usr From paulagrassi203 at hotmail.com Thu Sep 2 20:12:15 2004 From: paulagrassi203 at hotmail.com (Paula Bernardes) Date: Thu Sep 2 20:12:13 2004 Subject: [Python-checkins] =?iso-8859-1?q?Divulga=E7=E3o_em_sites_de_busc?= =?iso-8859-1?q?a_-_Marketing_por_e-mail_-_Cadastramento_de_homepag?= =?iso-8859-1?q?es_em_buscadores?= Message-ID: <20040902181212.67F5C1E4004@bag.python.org> Visite agora: http://www.divulgamail.mx.gs Divulga??o da Home Page em Sites de Busca, Divulga??o Sites Como divulgar home pages como divulgar sites como divulgar meu site, dicas de divulga??o de sites. Otimiza??o e posicionamento no Google. Mala direta e-mail, email regi?es, e-mails regi?o, mala direta por email, marketing e-mail, regi?es, cadastro e-mails, publicidade por email, emails regi?o, divulgar, enviar emails, campanha emails, propaganda emails, email cidade, envio an?nimo emails, email estados, divulgar e-mail, programas emails, e-mails por estados, e-mails cidade, cadastro e-mail, mala direta por e-mail, listas emails, e-mail regi?es, propaganda email, enviar email an?nimo, envio mala direta, estados, campanha, cidade, envio, publicidade e-mails, Visite agora: http://www.divulgamail.mx.gs Divulga??o da Home Page em Sites de Busca, Divulga??o Sites Como divulgar home pages como divulgar sites como divulgar meu site, dicas de divulga??o de sites. Otimiza??o e posicionamento no Google. campanhas e-mail, lista e-mail, programas e-mails, e-mails estado, publicidade emails, marketing digital, cidade, divulgar, lista email, emails estados, propaganda digital e-mails, e-mail por regi?es, e-mails por cidades, email cidades, campanha e-mail, e-mail estado, listas email, lista emails, propaganda por e-mails, mala direta email, publicidade, cidades, marketing emails, cidade, email por regi?es, envio propaganda, listas e-mails, e-mails regi?es, divulgar e-mails, envio mala-direta, e-mail cidades, email estado, e-mails por Visite agora: http://www.divulgamail.mx.gs Divulga??o da Home Page em Sites de Busca, Divulga??o Sites Como divulgar home pages como divulgar sites como divulgar meu site, dicas de divulga??o de sites. Otimiza??o e posicionamento no Google. Regi?o, marketing por emails, propaganda, software email em massa, propaganda digital e-mail, programas email, email, mala direta, propaganda e-mail, marketing e-mails, e-mail, mala-direta email, propaganda digital, emails por regi?o, email segmentado, estado, campanhas e-mails, e-mails cidades, e-mails segmentados, email por estado, marketing por email, emails segmentado, divulga??o, e-mails estados, cidade, campanha e-mails, software, email segmentados, regi?o, enviar e-mails an?nimo, enviar emails an?nimo, mala direta emails, marketing email, emails segmentados, programas e-mail, e-mails por cidade, lista e-mails, propaganda, mala direta por e-mails, campanha email, software spam internet, Visite agora: http://www.divulgamail.mx.gs Divulga??o da Home Page em Sites de Busca, buscadores, Divulga??o Sites Como divulgar home pages como divulgar sites como divulgar meu site, dicas de divulga??o de sites. Otimiza??o e posicionamento no Google., e-mail regi?o, listas, listas segmentadas, marketing, marketing digital por emails, email regi?o, divulga??o e-mail, emails por cidade, mala-direta por email, marketing digital por e-mails, listas email, lista segmentada, cidades, cadastro email, divulgue seu produto, mala-direta por e-mails, e-mail por estado, segmentos, email por cidades, propaganda por e-mail, emails cidades, publicidade por emails, envio e-mail, e-mails por estado, mala direta, mala-direta, mala-direta por emails, e-mail segmentado, marketing digital emails, cidades, divulga??o e-mails, marketing, e-mail estados, cidades, marketing por e-mail, envio emails, marketing digital email, propaganda Visite agora: http://www.divulgamail.mx.gs por email, envio an?nimo email, divulgue sua propaganda, propaganda digital emails, cidade, emails por cidades, e-mails segmentado, propaganda por emails, divulgar email, e-mail cidade, enviar e-mails, e-mails, cadastro emails, e-mail por cidade, envio email, cadastro, lista, envio e-mails, propaganda digital email, publicidade por e-mails, marketing digital, e-mail por regi?o, email por estados, divulga??o, emails por estados, segmentados, mala-direta emails, envio publicidade, campanhas, mala direta por emails, e-mail por estados, marketing por e-mails, emails por estado, mala-direta e-mails, marketing digital e-mail, divulgar emails, emails regi?es, publicidade, email por regi?o, e-mails por regi?es, listas e-mail, divulga??o emails, mala-direta por e-mail, enviar e-mail, enviar email, Visite agora: http://www.divulgamail.mx.gs divulga??o email, cidades, publicidade por e-mail, enviar, emails por regi?es, marketing digital por e-mail, email por cidade, campanhas email, marketing digital por email, marketing digital e-mails, propaganda e-mails, e-mail segmentados, envio an?nimo e-mail, software publicidade internet, segmentados, envio an?nimo e-mails, lista mala direta, programa email an?nimo, mala direta internet, publicidade email, mala direta segmentada, emails segmentados, marketing digital, mala direta email, publicidade, spam, mala direta e-mail, email regi?es, e-mails regi?o, mala direta por email, marketing e-mail, regi?es, cadastro e-mails, publicidade por email, emails regi?o, divulgar, enviar emails, campanha emails, propaganda emails, email cidade, envio an?nimo emails, email estados, divulgar e-mail, programas emails, e-mails por estados, e-mails cidade, cadastro e-mail, mala direta por e-mail, listas emails, e-mail regi?es, propaganda email, enviar email an?nimo, envio Visite agora: http://www.divulgamail.mx.gs mala direta, estados, campanha, cidade, envio, publicidade e-mails, campanhas e-mail, lista e-mail, programas e-mails, e-mails estado, publicidade emails, marketing digital, cidade, divulgar, lista email, emails estados, propaganda digital e-mails, e-mail por regi?es, e-mails por cidades, email cidades, campanha e-mail, e-mail estado, listas email, lista emails, propaganda por e-mails, mala direta email, publicidade, cidades, marketing emails, cidade, email por regi?es, envio propaganda, listas e-mails, e-mails regi?es, divulgar e-mails, envio mala-direta, e-mail cidades, email estado, e-mails por regi?o, marketing por emails, propaganda, software email em massa, propaganda digital e-mail, programas email, email, mala direta, propaganda e-mail, marketing e-mails, e-mail, mala-direta email, propaganda Visite agora: http://www.divulgamail.mx.gs digital, emails por regi?o, email segmentado, estado, campanhas e-mails, e-mails cidades, e-mails segmentados, email por estado, marketing por email, emails segmentado, divulga??o, e-mails estados, cidade, campanha e-mails, software, email segmentados, regi?o, enviar e-mails an?nimo, enviar emails an?nimo, mala direta emails, marketing email, emails segmentados, programas e-mail, e-mails por cidade, lista e-mails, propaganda, mala direta por e-mails, campanha email, software spam internet, emails Visite agora: http://www.divulgamail.mx.gs estado, publicidade e-mail, e-mail por cidades, enviar e-mail an?nimo, software propaganda internet, emails cidade, emails, campanhas emails, mala-direta e-mail, publicidade email, mala direta e-mails, e-mail regi?o, listas, listas segmentadas, marketing, marketing digital por emails, email regi?o, divulga??o e-mail, emails por cidade, mala-direta por email, marketing digital por e-mails, listas email, lista segmentada, cidades, cadastro email, divulgue seu produto, mala-direta por e-mails, e-mail por estado, segmentos, email por cidades, propaganda por e-mail, emails cidades, publicidade por emails, envio e-mail, e- Visite agora: http://www.divulgamail.mx.gs mails por estado, mala direta, mala-direta, mala-direta por emails, e-mail segmentado, marketing digital emails, cidades, divulga??o e-mails, marketing, e-mail estados, cidades, marketing por e-mail, envio emails, marketing digital email, propaganda por email, envio an?nimo email, divulgue sua propaganda, propaganda digital emails, cidade, emails por cidades, e-mails segmentado, propaganda por emails, divulgar email, e-mail cidade, enviar e-mails, e-mails, cadastro emails, e-mail por cidade, envio email, cadastro, lista, envio e-mails, propaganda digital email, publicidade por e-mails, marketing digital, e-mail por regi?o, email por estados, divulga??o, emails por estados, segmentados, mala-direta emails, envio publicidade, campanhas, mala direta por emails, e-mail por estados, marketing por e- Visite agora: http://www.divulgamail.mx.gs mails, emails por estado, mala-direta e-mails, marketing digital e-mail, divulgar emails, emails regi?es, publicidade, email por regi?o, e-mails por regi?es, listas e-mail, divulga??o emails, mala-direta por e-mail, enviar e-mail, enviar email, divulga??o email, cidades, publicidade por e-mail, enviar, emails por regi?es, marketing digital por e-mail, email por cidade, campanhas email, marketing digital por email, marketing digital e-mails, propaganda e-mails, e-mail segmentados, envio an?nimo e-mail, software publicidade internet, segmentados, envio an?nimo e-mails, lista mala direta, programa email an?nimo, mala direta internet, publicidade email, mala direta segmentada, emails segmentados, marketing digital, mala direta email, publicidade, spam From bcannon at users.sourceforge.net Thu Sep 2 21:10:16 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Thu Sep 2 21:10:19 2004 Subject: [Python-checkins] python/nondist/peps pep-3000.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5417 Modified Files: pep-3000.txt Log Message: Mention that making list comprehensions sugar for genexps will remove exposure of the loop variable. Index: pep-3000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-3000.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- pep-3000.txt 27 Aug 2004 18:43:32 -0000 1.6 +++ pep-3000.txt 2 Sep 2004 19:10:13 -0000 1.7 @@ -67,7 +67,8 @@ * ``True`` and ``False`` become keywords [4]_ * ``as`` becomes a keyword [5]_ * Have list comprehensions be syntactic sugar for passing an - equivalent generator expression to ``list()``. + equivalent generator expression to ``list()``; as a consequence the + loop variable will no longer be exposed. * Comparisons other than ``==`` and ``!=`` between disparate types will raise an exception unless explicitly supported by the type From montanaro at users.sourceforge.net Fri Sep 3 02:04:08 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri Sep 3 02:04:13 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libsimplexmlrpc.tex, 1.5, 1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29880 Modified Files: libsimplexmlrpc.tex Log Message: Make the api of the _dispatch() method more concrete. I have no idea if this is the right way to document such things (Fred, help me out here :-), but I got misled by the existing documentation and assumed the parameter list was a *args sort of thing. Index: libsimplexmlrpc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsimplexmlrpc.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- libsimplexmlrpc.tex 17 Jan 2003 22:47:33 -0000 1.5 +++ libsimplexmlrpc.tex 3 Sep 2004 00:04:05 -0000 1.6 @@ -59,8 +59,13 @@ Register an object which is used to expose method names which have not been registered using \method{register_function()}. If \var{instance} contains a \method{_dispatch()} method, it is called - with the requested method name and the parameters from the request; - the return value is returned to the client as the result. If + with the requested method name and the parameters from the request. Its + API is \code{def \method{_dispatch}(self, method, params)} (note tha + \var{params} does not represent a variable argument list). If it calls an + underlying function to perform its task, that function is called as + \code{func(*params)}, expanding the parameter list. + The return value from \method{_dispatch()} is returned to the client as + the result. If \var{instance} does not have a \method{_dispatch()} method, it is searched for an attribute matching the name of the requested method; if the requested method name contains periods, each component of the From anthonybaxter at users.sourceforge.net Fri Sep 3 11:32:53 2004 From: anthonybaxter at users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Fri Sep 3 11:32:56 2004 Subject: [Python-checkins] python/nondist/peps pep-0318.txt,1.33,1.34 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16410 Modified Files: pep-0318.txt Log Message: fix editors note Index: pep-0318.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0318.txt,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- pep-0318.txt 1 Sep 2004 23:40:12 -0000 1.33 +++ pep-0318.txt 3 Sep 2004 09:32:50 -0000 1.34 @@ -636,7 +636,8 @@ Community Consensus ------------------- -[editor's note: should this section be removed now?] +This section documents the rejected J2 syntax, and is included for +historical completeness. The consensus that emerged on comp.lang.python was the proposed J2 syntax (the "J2" was how it was referenced on the PythonDecorators wiki From loewis at users.sourceforge.net Fri Sep 3 15:32:59 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Fri Sep 3 15:33:02 2004 Subject: [Python-checkins] python/dist/src/PC empty.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18880 Added Files: empty.c Log Message: Add main program for icon file. --- NEW FILE: empty.c --- #include int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { return 0; } From niemeyer at users.sourceforge.net Fri Sep 3 19:06:13 2004 From: niemeyer at users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Fri Sep 3 19:06:15 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libre.tex,1.108,1.109 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22680/Doc/lib Modified Files: libre.tex Log Message: Applying modified version of patch #1018386, which fixes some escaping bugs in SRE. Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.108 retrieving revision 1.109 diff -u -d -r1.108 -r1.109 --- libre.tex 18 Oct 2003 15:28:22 -0000 1.108 +++ libre.tex 3 Sep 2004 17:06:10 -0000 1.109 @@ -387,7 +387,8 @@ Octal escapes are included in a limited form: If the first digit is a 0, or if there are three octal digits, it is considered an octal -escape. Otherwise, it is a group reference. +escape. Otherwise, it is a group reference. As for string literals, +octal escapes are always at most three digits in length. % Note the lack of a period in the section title; it causes problems From niemeyer at users.sourceforge.net Fri Sep 3 19:06:12 2004 From: niemeyer at users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Fri Sep 3 19:06:16 2004 Subject: [Python-checkins] python/dist/src/Lib sre_parse.py,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22680/Lib Modified Files: sre_parse.py Log Message: Applying modified version of patch #1018386, which fixes some escaping bugs in SRE. Index: sre_parse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_parse.py,v retrieving revision 1.61 retrieving revision 1.62 diff -u -d -r1.61 -r1.62 --- sre_parse.py 25 Aug 2004 02:22:29 -0000 1.61 +++ sre_parse.py 3 Sep 2004 17:06:09 -0000 1.62 @@ -217,21 +217,11 @@ # check that group name is a valid string if not isident(name[0]): return False - for char in name: + for char in name[1:]: if not isident(char) and not isdigit(char): return False return True -def _group(escape, groups): - # check if the escape string represents a valid group - try: - gid = int(escape[1:]) - if gid and gid < groups: - return gid - except ValueError: - pass - return None # not a valid group - def _class_escape(source, escape): # handle escape code inside character class code = ESCAPES.get(escape) @@ -241,7 +231,8 @@ if code: return code try: - if escape[1:2] == "x": + c = escape[1:2] + if c == "x": # hexadecimal escape (exactly two digits) while source.next in HEXDIGITS and len(escape) < 4: escape = escape + source.get() @@ -249,12 +240,14 @@ if len(escape) != 2: raise error, "bogus escape: %s" % repr("\\" + escape) return LITERAL, int(escape, 16) & 0xff - elif escape[1:2] in OCTDIGITS: + elif c in OCTDIGITS: # octal escape (up to three digits) - while source.next in OCTDIGITS and len(escape) < 5: + while source.next in OCTDIGITS and len(escape) < 4: escape = escape + source.get() escape = escape[1:] return LITERAL, int(escape, 8) & 0xff + elif c in DIGITS: + raise error, "bogus escape: %s" % repr(escape) if len(escape) == 2: return LITERAL, ord(escape[1]) except ValueError: @@ -270,19 +263,20 @@ if code: return code try: - if escape[1:2] == "x": + c = escape[1:2] + if c == "x": # hexadecimal escape while source.next in HEXDIGITS and len(escape) < 4: escape = escape + source.get() if len(escape) != 4: raise ValueError return LITERAL, int(escape[2:], 16) & 0xff - elif escape[1:2] == "0": + elif c == "0": # octal escape while source.next in OCTDIGITS and len(escape) < 4: escape = escape + source.get() return LITERAL, int(escape[1:], 8) & 0xff - elif escape[1:2] in DIGITS: + elif c in DIGITS: # octal escape *or* decimal group reference (sigh) if source.next in DIGITS: escape = escape + source.get() @@ -291,9 +285,9 @@ # got three octal digits; this is an octal escape escape = escape + source.get() return LITERAL, int(escape[1:], 8) & 0xff - # got at least one decimal digit; this is a group reference - group = _group(escape, state.groups) - if group: + # not an octal escape, so this is a group reference + group = int(escape[1:]) + if group < state.groups: if not state.checkgroup(group): raise error, "cannot refer to open group" return GROUPREF, group @@ -709,7 +703,8 @@ break # end of replacement string if this and this[0] == "\\": # group - if this == "\\g": + c = this[1:2] + if c == "g": name = "" if s.match("<"): while 1: @@ -723,6 +718,8 @@ raise error, "bad group name" try: index = int(name) + if index < 0: + raise error, "negative group number" except ValueError: if not isname(name): raise error, "bad character in group name" @@ -731,26 +728,23 @@ except KeyError: raise IndexError, "unknown group name" a((MARK, index)) - elif len(this) > 1 and this[1] in DIGITS: - code = None - while 1: - group = _group(this, pattern.groups+1) - if group: - if (s.next not in DIGITS or - not _group(this + s.next, pattern.groups+1)): - code = MARK, group - break - elif s.next in OCTDIGITS: + elif c == "0": + if s.next in OCTDIGITS: + this = this + sget() + if s.next in OCTDIGITS: this = this + sget() - else: - break - if not code: - this = this[1:] - code = LITERAL, makechar(int(this[-6:], 8) & 0xff) - if code[0] is LITERAL: - literal(code[1]) - else: - a(code) + literal(makechar(int(this[1:], 8) & 0xff)) + elif c in DIGITS: + isoctal = False + if s.next in DIGITS: + this = this + sget() + if (c in OCTDIGITS and s.next in OCTDIGITS and + this[2] in OCTDIGITS): + this = this + sget() + isoctal = True + literal(makechar(int(this[1:], 8) & 0xff)) + if not isoctal: + a((MARK, int(this[1:]))) else: try: this = makechar(ESCAPES[this][1]) @@ -782,7 +776,7 @@ for index, group in groups: literals[index] = s = g(group) if s is None: - raise IndexError + raise error, "unmatched group" except IndexError: - raise error, "empty group" + raise error, "invalid group reference" return sep.join(literals) From niemeyer at users.sourceforge.net Fri Sep 3 19:06:12 2004 From: niemeyer at users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Fri Sep 3 19:06:16 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_re.py,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22680/Lib/test Modified Files: test_re.py Log Message: Applying modified version of patch #1018386, which fixes some escaping bugs in SRE. Index: test_re.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_re.py,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- test_re.py 31 May 2004 03:09:25 -0000 1.50 +++ test_re.py 3 Sep 2004 17:06:10 -0000 1.51 @@ -83,6 +83,48 @@ self.assertEqual(re.sub('\r\n', '\n', 'abc\r\ndef\r\n'), 'abc\ndef\n') + def test_sub_template_numeric_escape(self): + # bug 776311 and friends + self.assertEqual(re.sub('x', r'\0', 'x'), '\0') + self.assertEqual(re.sub('x', r'\000', 'x'), '\000') + self.assertEqual(re.sub('x', r'\001', 'x'), '\001') + self.assertEqual(re.sub('x', r'\008', 'x'), '\0' + '8') + self.assertEqual(re.sub('x', r'\009', 'x'), '\0' + '9') + self.assertEqual(re.sub('x', r'\111', 'x'), '\111') + self.assertEqual(re.sub('x', r'\117', 'x'), '\117') + + self.assertEqual(re.sub('x', r'\1111', 'x'), '\1111') + self.assertEqual(re.sub('x', r'\1111', 'x'), '\111' + '1') + + self.assertEqual(re.sub('x', r'\00', 'x'), '\x00') + self.assertEqual(re.sub('x', r'\07', 'x'), '\x07') + self.assertEqual(re.sub('x', r'\08', 'x'), '\0' + '8') + self.assertEqual(re.sub('x', r'\09', 'x'), '\0' + '9') + self.assertEqual(re.sub('x', r'\0a', 'x'), '\0' + 'a') + + self.assertEqual(re.sub('x', r'\400', 'x'), '\0') + self.assertEqual(re.sub('x', r'\777', 'x'), '\377') + + self.assertRaises(re.error, re.sub, 'x', r'\1', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\8', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\9', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\11', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\18', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\1a', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\90', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\99', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\118', 'x') # r'\11' + '8' + self.assertRaises(re.error, re.sub, 'x', r'\11a', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\181', 'x') # r'\18' + '1' + self.assertRaises(re.error, re.sub, 'x', r'\800', 'x') # r'\80' + '0' + + # in python2.3 (etc), these loop endlessly in sre_parser.py + self.assertEqual(re.sub('(((((((((((x)))))))))))', r'\11', 'x'), 'x') + self.assertEqual(re.sub('((((((((((y))))))))))(.)', r'\118', 'xyz'), + 'xz8') + self.assertEqual(re.sub('((((((((((y))))))))))(.)', r'\11a', 'xyz'), + 'xza') + def test_qualified_re_sub(self): self.assertEqual(re.sub('a', 'b', 'aaaaa'), 'bbbbb') self.assertEqual(re.sub('a', 'b', 'aaaaa', 1), 'baaaa') @@ -105,6 +147,7 @@ self.assertRaises(IndexError, re.sub, '(?Px)', '\g', 'xx') self.assertRaises(re.error, re.sub, '(?Px)|(?Py)', '\g', 'xx') self.assertRaises(re.error, re.sub, '(?Px)|(?Py)', '\\2', 'xx') + self.assertRaises(re.error, re.sub, '(?Px)', '\g<-1>', 'xx') def test_re_subn(self): self.assertEqual(re.subn("(?i)b+", "x", "bbbb BBBB"), ('x x', 2)) @@ -386,6 +429,16 @@ self.assertNotEqual(re.match(r"\x%02xz" % i, chr(i)+"z"), None) self.assertRaises(re.error, re.match, "\911", "") + def test_sre_character_class_literals(self): + for i in [0, 8, 16, 32, 64, 127, 128, 255]: + self.assertNotEqual(re.match(r"[\%03o]" % i, chr(i)), None) + self.assertNotEqual(re.match(r"[\%03o0]" % i, chr(i)), None) + self.assertNotEqual(re.match(r"[\%03o8]" % i, chr(i)), None) + self.assertNotEqual(re.match(r"[\x%02x]" % i, chr(i)), None) + self.assertNotEqual(re.match(r"[\x%02x0]" % i, chr(i)), None) + self.assertNotEqual(re.match(r"[\x%02xz]" % i, chr(i)), None) + self.assertRaises(re.error, re.match, "[\911]", "") + def test_bug_113254(self): self.assertEqual(re.match(r'(a)|(b)', 'b').start(1), -1) self.assertEqual(re.match(r'(a)|(b)', 'b').end(1), -1) From niemeyer at users.sourceforge.net Fri Sep 3 20:12:03 2004 From: niemeyer at users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Fri Sep 3 20:12:07 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_re.py,1.51,1.52 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2859/Lib/test Modified Files: test_re.py Log Message: Fixing bug #817234, which made SRE get into an infinite loop on empty final matches with finditer(). New test cases included for this bug and for #581080. Index: test_re.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_re.py,v retrieving revision 1.51 retrieving revision 1.52 diff -u -d -r1.51 -r1.52 --- test_re.py 3 Sep 2004 17:06:10 -0000 1.51 +++ test_re.py 3 Sep 2004 18:11:59 -0000 1.52 @@ -567,6 +567,22 @@ self.assertEqual(re.compile(pattern).split("a.b.c"), ['a','b','c']) + def test_bug_581080(self): + iter = re.finditer(r"\s", "a b") + self.assertEqual(iter.next().span(), (1,2)) + self.assertRaises(StopIteration, iter.next) + + scanner = re.compile(r"\s").scanner("a b") + self.assertEqual(scanner.search().span(), (1, 2)) + self.assertEqual(scanner.search(), None) + + def test_bug_817234(self): + iter = re.finditer(r".*", "asdf") + self.assertEqual(iter.next().span(), (0, 4)) + self.assertEqual(iter.next().span(), (4, 4)) + self.assertRaises(StopIteration, iter.next) + + def run_re_tests(): from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR if verbose: From niemeyer at users.sourceforge.net Fri Sep 3 20:12:03 2004 From: niemeyer at users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Fri Sep 3 20:12:08 2004 Subject: [Python-checkins] python/dist/src/Modules _sre.c,2.107,2.108 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2859/Modules Modified Files: _sre.c Log Message: Fixing bug #817234, which made SRE get into an infinite loop on empty final matches with finditer(). New test cases included for this bug and for #581080. Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.107 retrieving revision 2.108 diff -u -d -r2.107 -r2.108 --- _sre.c 15 Jul 2004 15:54:04 -0000 2.107 +++ _sre.c 3 Sep 2004 18:11:59 -0000 2.108 @@ -539,7 +539,7 @@ break; case SRE_OP_ANY_ALL: - /* repeated dot wildcare. skip to the end of the target + /* repeated dot wildcard. skip to the end of the target string, and backtrack from there */ TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr)); ptr = end; @@ -3244,8 +3244,7 @@ match = pattern_new_match((PatternObject*) self->pattern, state, status); - if ((status == 0 || state->ptr == state->start) && - state->ptr < state->end) + if (status == 0 || state->ptr == state->start) state->start = (void*) ((char*) state->ptr + state->charsize); else state->start = state->ptr; @@ -3276,8 +3275,7 @@ match = pattern_new_match((PatternObject*) self->pattern, state, status); - if ((status == 0 || state->ptr == state->start) && - state->ptr < state->end) + if (status == 0 || state->ptr == state->start) state->start = (void*) ((char*) state->ptr + state->charsize); else state->start = state->ptr; From rhettinger at users.sourceforge.net Fri Sep 3 21:09:26 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri Sep 3 21:09:29 2004 Subject: [Python-checkins] python/dist/src/Lib random.py,1.65,1.66 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13588 Modified Files: random.py Log Message: SF bug #1022010: Import random fails * trap NotImplementedError raised by os.urandom calls when not available on a particular system. Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.65 retrieving revision 1.66 diff -u -d -r1.65 -r1.66 --- random.py 31 Aug 2004 02:19:55 -0000 1.65 +++ random.py 3 Sep 2004 19:09:22 -0000 1.66 @@ -62,7 +62,8 @@ try: from os import urandom as _urandom from binascii import hexlify as _hexlify -except ImportError: + _urandom(1) # verify that urandom is implemented +except (ImportError, NotImplementedError): _urandom = None From niemeyer at users.sourceforge.net Fri Sep 3 22:15:58 2004 From: niemeyer at users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Fri Sep 3 22:16:02 2004 Subject: [Python-checkins] python/dist/src/Lib sre_parse.py,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25084/Lib Modified Files: sre_parse.py Log Message: Minor aesthetic change in sre_parse.py, as suggested by Mike Coleman. Index: sre_parse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_parse.py,v retrieving revision 1.62 retrieving revision 1.63 diff -u -d -r1.62 -r1.63 --- sre_parse.py 3 Sep 2004 17:06:09 -0000 1.62 +++ sre_parse.py 3 Sep 2004 20:15:56 -0000 1.63 @@ -738,8 +738,8 @@ isoctal = False if s.next in DIGITS: this = this + sget() - if (c in OCTDIGITS and s.next in OCTDIGITS and - this[2] in OCTDIGITS): + if (c in OCTDIGITS and this[2] in OCTDIGITS and + s.next in OCTDIGITS): this = this + sget() isoctal = True literal(makechar(int(this[1:], 8) & 0xff)) From greg at users.sourceforge.net Sat Sep 4 03:37:02 2004 From: greg at users.sourceforge.net (greg@users.sourceforge.net) Date: Sat Sep 4 03:37:05 2004 Subject: [Python-checkins] python/dist/src/Modules _bsddb.c,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12100 Modified Files: _bsddb.c Log Message: SF bug 1017405: the keys() values() and items() DB methods were ignoring their transaction (txn) argument. Index: _bsddb.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- _bsddb.c 9 Jul 2004 23:33:06 -0000 1.37 +++ _bsddb.c 4 Sep 2004 01:36:59 -0000 1.38 @@ -2570,7 +2570,7 @@ /* get a cursor */ MYDB_BEGIN_ALLOW_THREADS; - err = self->db->cursor(self->db, NULL, &cursor, 0); + err = self->db->cursor(self->db, txn, &cursor, 0); MYDB_END_ALLOW_THREADS; RETURN_IF_ERR(); From greg at users.sourceforge.net Sat Sep 4 03:41:04 2004 From: greg at users.sourceforge.net (greg@users.sourceforge.net) Date: Sat Sep 4 03:41:07 2004 Subject: [Python-checkins] python/dist/src/Modules _bsddb.c, 1.17.6.4, 1.17.6.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12657 Modified Files: Tag: release23-maint _bsddb.c Log Message: SF bug 1017405: DB keys() values() and items() methods were ignoring their txn argument. Index: _bsddb.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v retrieving revision 1.17.6.4 retrieving revision 1.17.6.5 diff -u -d -r1.17.6.4 -r1.17.6.5 --- _bsddb.c 16 Mar 2004 07:47:45 -0000 1.17.6.4 +++ _bsddb.c 4 Sep 2004 01:41:01 -0000 1.17.6.5 @@ -2409,7 +2409,7 @@ /* get a cursor */ MYDB_BEGIN_ALLOW_THREADS; - err = self->db->cursor(self->db, NULL, &cursor, 0); + err = self->db->cursor(self->db, txn, &cursor, 0); MYDB_END_ALLOW_THREADS; RETURN_IF_ERR(); From tim_one at users.sourceforge.net Sat Sep 4 17:04:21 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 4 17:04:25 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.97,1.98 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19029/Lib Modified Files: doctest.py Log Message: Added a couple names to __all__. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.97 retrieving revision 1.98 diff -u -d -r1.97 -r1.98 --- doctest.py 30 Aug 2004 16:19:24 -0000 1.97 +++ doctest.py 4 Sep 2004 15:04:06 -0000 1.98 @@ -176,10 +176,12 @@ 'DONT_ACCEPT_BLANKLINE', 'NORMALIZE_WHITESPACE', 'ELLIPSIS', + 'COMPARISON_FLAGS', 'REPORT_UDIFF', 'REPORT_CDIFF', 'REPORT_NDIFF', 'REPORT_ONLY_FIRST_FAILURE', + 'REPORTING_FLAGS', # 1. Utility Functions 'is_private', # 2. Example & DocTest From tim_one at users.sourceforge.net Sat Sep 4 19:21:05 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 4 19:21:08 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_doctest.py, 1.41, 1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11757/Lib/test Modified Files: test_doctest.py Log Message: Added IGNORE_EXCEPTION_DETAIL comparison option. The need is explained in the new docs. DocTestRunner.__run: Separate the determination of the example outcome from reporting that outcome, to squash brittle code duplication and excessive nesting. Index: test_doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- test_doctest.py 29 Aug 2004 00:38:17 -0000 1.41 +++ test_doctest.py 4 Sep 2004 17:21:02 -0000 1.42 @@ -837,6 +837,43 @@ ValueError: message (1, 1) +However, IGNORE_EXCEPTION_DETAIL can be used to allow a mismatch in the +detail: + + >>> def f(x): + ... r''' + ... >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... ValueError: wrong message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + (0, 1) + +But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type: + + >>> def f(x): + ... r''' + ... >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... TypeError: wrong type + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + Line 2, in f + Failed example: + raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL + Expected: + Traceback (most recent call last): + TypeError: wrong type + Got: + Traceback (most recent call last): + ... + ValueError: message + (1, 1) + If an exception is raised but not expected, then it is reported as an unexpected exception: From tim_one at users.sourceforge.net Sat Sep 4 19:21:04 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 4 19:21:11 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11757/Doc/lib Modified Files: libdoctest.tex Log Message: Added IGNORE_EXCEPTION_DETAIL comparison option. The need is explained in the new docs. DocTestRunner.__run: Separate the determination of the example outcome from reporting that outcome, to squash brittle code duplication and excessive nesting. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- libdoctest.tex 30 Aug 2004 16:19:24 -0000 1.40 +++ libdoctest.tex 4 Sep 2004 17:21:02 -0000 1.41 @@ -307,6 +307,9 @@ to be the start of the exception detail. Of course this does the right thing for genuine tracebacks. +\item When the \constant{IGNORE_EXCEPTION_DETAIL} doctest option is + is specified, everything following the leftmost colon is ignored. + \end{itemize} \versionchanged[The ability to handle a multi-line exception detail @@ -365,6 +368,34 @@ is prone to in regular expressions. \end{datadesc} +\begin{datadesc}{IGNORE_EXCEPTION_DETAIL} + When specified, an example that expects an exception passes if + an exception of the expected type is raised, even if the exception + detail does not match. For example, an example expecting + \samp{ValueError: 42} will pass if the actual exception raised is + \samp{ValueError: 3*14}, but will fail, e.g., if + \exception{TypeError} is raised. + + Note that a similar effect can be obtained using \constant{ELLIPSIS}, + and \constant{IGNORE_EXCEPTION_DETAIL} may go away when Python releases + prior to 2.4 become uninteresting. Until then, + \constant{IGNORE_EXCEPTION_DETAIL} is the only clear way to write a + doctest that doesn't care about the exception detail yet continues + to pass under Python releases prior to 2.4 (doctest directives + appear to be comments to them). For example, + +\begin{verbatim} +>>> (1, 2)[3] = 'moo' #doctest: +IGNORE_EXCEPTION_DETAIL +Traceback (most recent call last): + File "", line 1, in ? +TypeError: object doesn't support item assignment +\end{verbatim} + + passes under Python 2.4 and Python 2.3. The detail changed in 2.4, + to say "does not" instead of "doesn't". + +\end{datadesc} + \begin{datadesc}{COMPARISON_FLAGS} A bitmask or'ing together all the comparison flags above. \end{datadesc} @@ -463,6 +494,7 @@ \versionchanged[Constants \constant{DONT_ACCEPT_BLANKLINE}, \constant{NORMALIZE_WHITESPACE}, \constant{ELLIPSIS}, + \constant{IGNORE_EXCEPTION_DETAIL}, \constant{REPORT_UDIFF}, \constant{REPORT_CDIFF}, \constant{REPORT_NDIFF}, \constant{REPORT_ONLY_FIRST_FAILURE}, \constant{COMPARISON_FLAGS} and \constant{REPORTING_FLAGS} From tim_one at users.sourceforge.net Sat Sep 4 19:21:05 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 4 19:21:11 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.98,1.99 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11757/Lib Modified Files: doctest.py Log Message: Added IGNORE_EXCEPTION_DETAIL comparison option. The need is explained in the new docs. DocTestRunner.__run: Separate the determination of the example outcome from reporting that outcome, to squash brittle code duplication and excessive nesting. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.98 retrieving revision 1.99 diff -u -d -r1.98 -r1.99 --- doctest.py 4 Sep 2004 15:04:06 -0000 1.98 +++ doctest.py 4 Sep 2004 17:21:02 -0000 1.99 @@ -176,6 +176,7 @@ 'DONT_ACCEPT_BLANKLINE', 'NORMALIZE_WHITESPACE', 'ELLIPSIS', + 'IGNORE_EXCEPTION_DETAIL', 'COMPARISON_FLAGS', 'REPORT_UDIFF', 'REPORT_CDIFF', @@ -261,11 +262,13 @@ DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE') NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE') ELLIPSIS = register_optionflag('ELLIPSIS') +IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | DONT_ACCEPT_BLANKLINE | NORMALIZE_WHITESPACE | - ELLIPSIS) + ELLIPSIS | + IGNORE_EXCEPTION_DETAIL) REPORT_UDIFF = register_optionflag('REPORT_UDIFF') REPORT_CDIFF = register_optionflag('REPORT_CDIFF') @@ -1293,6 +1296,10 @@ # to modify them). original_optionflags = self.optionflags + SUCCESS, FAILURE, BOOM = range(3) # `outcome` state + + check = self._checker.check_output + # Process each example. for examplenum, example in enumerate(test.examples): @@ -1337,45 +1344,53 @@ got = self._fakeout.getvalue() # the actual output self._fakeout.truncate(0) + outcome = FAILURE # guilty until proved innocent or insane # If the example executed without raising any exceptions, - # then verify its output and report its outcome. + # verify its output. if exception is None: - if self._checker.check_output(example.want, got, - self.optionflags): - if not quiet: - self.report_success(out, test, example, got) - else: - if not quiet: - self.report_failure(out, test, example, got) - failures += 1 + if check(example.want, got, self.optionflags): + outcome = SUCCESS - # If the example raised an exception, then check if it was - # expected. + # The example raised an exception: check if it was expected. else: exc_info = sys.exc_info() exc_msg = traceback.format_exception_only(*exc_info[:2])[-1] + if not quiet: + got += _exception_traceback(exc_info) - # If `example.exc_msg` is None, then we weren't - # expecting an exception. + # If `example.exc_msg` is None, then we weren't expecting + # an exception. if example.exc_msg is None: - if not quiet: - self.report_unexpected_exception(out, test, example, - exc_info) - failures += 1 - # If `example.exc_msg` matches the actual exception - # message (`exc_msg`), then the example succeeds. - elif (self._checker.check_output(example.exc_msg, exc_msg, - self.optionflags)): - if not quiet: - got += _exception_traceback(exc_info) - self.report_success(out, test, example, got) - # Otherwise, the example fails. - else: - if not quiet: - got += _exception_traceback(exc_info) - self.report_failure(out, test, example, got) - failures += 1 + outcome = BOOM + + # We expected an exception: see whether it matches. + elif check(example.exc_msg, exc_msg, self.optionflags): + outcome = SUCCESS + + # Another chance if they didn't care about the detail. + elif self.optionflags & IGNORE_EXCEPTION_DETAIL: + m1 = re.match(r'[^:]*:', example.exc_msg) + m2 = re.match(r'[^:]*:', exc_msg) + if m1 and m2 and check(m1.group(0), m2.group(0), + self.optionflags): + outcome = SUCCESS + + # Report the outcome. + if outcome is SUCCESS: + if not quiet: + self.report_success(out, test, example, got) + elif outcome is FAILURE: + if not quiet: + self.report_failure(out, test, example, got) + failures += 1 + elif outcome is BOOM: + if not quiet: + self.report_unexpected_exception(out, test, example, + exc_info) + failures += 1 + else: + assert False, ("unknown outcome", outcome) # Restore the option flags (in case they were modified) self.optionflags = original_optionflags From rhettinger at users.sourceforge.net Sat Sep 4 22:09:15 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat Sep 4 22:09:19 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_compiler.py, 1.5, 1.6 test_decimal.py, 1.13, 1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11509 Modified Files: test_compiler.py test_decimal.py Log Message: Change the strategy for coping with time intensive tests from "all or none" to "all or some". This provides much greater test coverage without eating much time. It also makes it more likely that routine regression testing will unearth bugs. Index: test_compiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_compiler.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- test_compiler.py 8 Aug 2004 16:43:59 -0000 1.5 +++ test_compiler.py 4 Sep 2004 20:09:12 -0000 1.6 @@ -2,6 +2,7 @@ import os import test.test_support import unittest +from random import random class CompilerTest(unittest.TestCase): @@ -18,6 +19,8 @@ for basename in os.listdir(dir): if not basename.endswith(".py"): continue + if not TEST_ALL and random() < 0.98: + continue path = os.path.join(dir, basename) if test.test_support.verbose: print "compiling", path @@ -31,7 +34,8 @@ compiler.compile(buf, basename, "exec") def test_main(): - test.test_support.requires("compiler") + global TEST_ALL + TEST_ALL = test.test_support.is_resource_enabled("compiler") test.test_support.run_unittest(CompilerTest) if __name__ == "__main__": Index: test_decimal.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_decimal.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- test_decimal.py 17 Aug 2004 16:34:51 -0000 1.13 +++ test_decimal.py 4 Sep 2004 20:09:13 -0000 1.14 @@ -181,6 +181,10 @@ def eval_equation(self, s): #global DEFAULT_PRECISION #print DEFAULT_PRECISION + + if not TEST_ALL and random.random() < 0.90: + return + try: Sides = s.split('->') L = Sides[0].strip().split() @@ -997,9 +1001,13 @@ def test_main(arith=False, verbose=None): """ Execute the tests. - Runs arithmetic tests if arith is True or if the "decimal" resource - is enables in regrtest.py + Runs all arithmetic tests if arith is True or if the "decimal" resource + is enabled in regrtest.py """ + + global TEST_ALL + TEST_ALL = arith or is_resource_enabled('decimal') + test_classes = [ DecimalExplicitConstructionTest, DecimalImplicitConstructionTest, @@ -1008,20 +1016,17 @@ DecimalUsabilityTest, DecimalPythonAPItests, ContextAPItests, + DecimalTest, ] - if arith or is_resource_enabled('decimal'): - test_classes.extend([DecimalTest]) - run_unittest(*test_classes) import decimal as DecimalModule run_doctest(DecimalModule, verbose) - return if __name__ == '__main__': # Calling with no arguments runs all tests. - # Calling with "Skip" will skipover the arithmetic tests. + # Calling with "Skip" will skip over 90% of the arithmetic tests. if len(sys.argv) == 1: test_main(arith=True, verbose=True) elif len(sys.argv) == 2: From rhettinger at users.sourceforge.net Sat Sep 4 22:13:31 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat Sep 4 22:13:34 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_random.py, 1.18, 1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12609 Modified Files: test_random.py Log Message: SF bug #1022010: Import random fails * Complete the previous patch by making sure that the MachineRandom tests are only run when the underlying resource is available. Index: test_random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_random.py,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- test_random.py 30 Aug 2004 06:14:30 -0000 1.18 +++ test_random.py 4 Sep 2004 20:13:29 -0000 1.19 @@ -490,11 +490,14 @@ self.failUnless(set(random.__all__) <= set(dir(random))) def test_main(verbose=None): - testclasses = (WichmannHill_TestBasicOps, + testclasses = [WichmannHill_TestBasicOps, MersenneTwister_TestBasicOps, - HardwareRandom_TestBasicOps, TestDistributions, - TestModule) + TestModule] + + if random._urandom is not None: + testclasses.append(HardwareRandom_TestBasicOps) + test_support.run_unittest(*testclasses) # verify reference counting From rhettinger at users.sourceforge.net Sat Sep 4 23:14:37 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat Sep 4 23:14:40 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libsignal.tex,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22860 Modified Files: libsignal.tex Log Message: SF bug #1020540: a wrong link from "frame object" in lib index Index: libsignal.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsignal.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- libsignal.tex 13 Mar 2003 13:56:49 -0000 1.25 +++ libsignal.tex 4 Sep 2004 21:14:34 -0000 1.26 @@ -139,9 +139,10 @@ \exception{ValueError} exception to be raised. The \var{handler} is called with two arguments: the signal number - and the current stack frame (\code{None} or a frame object; see the - reference manual for a description of frame objects). -\obindex{frame} + and the current stack frame (\code{None} or a frame object; + for a description of frame objects, see the reference manual section + on the standard type hierarchy or see the attribute descriptions in + the \refmodule{inspect} module). \end{funcdesc} \subsection{Example} From rhettinger at users.sourceforge.net Sun Sep 5 00:49:57 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 5 00:50:02 2004 Subject: [Python-checkins] python/nondist/peps pep-0320.txt,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7200 Modified Files: pep-0320.txt Log Message: Update completed features for Py2.4a3. Index: pep-0320.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0320.txt,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- pep-0320.txt 28 Jul 2004 10:39:55 -0000 1.16 +++ pep-0320.txt 4 Sep 2004 22:49:54 -0000 1.17 @@ -16,8 +16,7 @@ beta release. Bugs may be fixed until the final release. There will be at least two alpha releases, two beta releases, and - one release candidate. The release date is not yet fixed but a - rough target for the first alpha is July 2004. + one release candidate. The release date is not yet fixed. Release Manager @@ -30,20 +29,26 @@ July 9: alpha 1 [completed] - August 5/6: alpha 2 + August 5/6: alpha 2 [completed] - August 26/27: alpha 3 or beta 1 + Sept 3: alpha 3 [completed] Completed features for 2.4 PEP 218 Builtin Set Objects. PEP 289 Generator expressions. - + + PEP 292 Simpler String Substitutions to be implemented as a module. + + PEP 318: Function/method decorator syntax, using @syntax + PEP 322 Reverse Iteration. PEP 327: A Decimal package for fixed precision arithmetic. + PEP 328: Multi-line Imports + Encapsulate the decorate-sort-undecorate pattern in a keyword for list.sort(). @@ -63,14 +68,6 @@ These features are all planned for 2.4b1, but have not yet landed. - PEP 292 Simpler String Substitutions to be implemented as a module. - - PEP 318: Function/method decorator syntax, using @syntax - - PEP 328: Imports: Multi-line and Absolute/Relative. (Still quite - controversial.) No-one has stepped forward to champion this, so it's - looking like it might not make it in. - Deprecate and/or remove the modules listed in PEP 4 (posixfile, gopherlib, pre, others) From rhettinger at users.sourceforge.net Sun Sep 5 01:53:27 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 5 01:53:31 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_pyclbr.py, 1.23, 1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17859 Modified Files: test_pyclbr.py Log Message: Teach a test about the different kinds of functions. Index: test_pyclbr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pyclbr.py,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- test_pyclbr.py 4 Aug 2004 02:36:18 -0000 1.23 +++ test_pyclbr.py 4 Sep 2004 23:53:20 -0000 1.24 @@ -4,7 +4,7 @@ ''' from test.test_support import run_unittest import unittest, sys -from types import ClassType, FunctionType, MethodType +from types import ClassType, FunctionType, MethodType, BuiltinFunctionType import pyclbr from unittest import TestCase @@ -92,7 +92,7 @@ self.assertHasattr(module, name, ignore) py_item = getattr(module, name) if isinstance(value, pyclbr.Function): - self.assertEquals(type(py_item), FunctionType) + self.assert_(isinstance(py_item, (FunctionType, BuiltinFunctionType))) else: self.failUnless(isinstance(py_item, (ClassType, type))) real_bases = [base.__name__ for base in py_item.__bases__] From rhettinger at users.sourceforge.net Sun Sep 5 02:00:48 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 5 02:00:54 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_random.py, 1.19, 1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18618/test Modified Files: test_random.py Log Message: Fulfill Martin's request to use try/except rather than a "look before you leap" approach. Makes the early call to os.urandom() unnecessary. Index: test_random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_random.py,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- test_random.py 4 Sep 2004 20:13:29 -0000 1.19 +++ test_random.py 5 Sep 2004 00:00:42 -0000 1.20 @@ -495,7 +495,11 @@ TestDistributions, TestModule] - if random._urandom is not None: + try: + random.HardwareRandom().random() + except NotImplementedError: + pass + else: testclasses.append(HardwareRandom_TestBasicOps) test_support.run_unittest(*testclasses) From rhettinger at users.sourceforge.net Sun Sep 5 02:00:48 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 5 02:00:55 2004 Subject: [Python-checkins] python/dist/src/Lib random.py,1.66,1.67 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18618 Modified Files: random.py Log Message: Fulfill Martin's request to use try/except rather than a "look before you leap" approach. Makes the early call to os.urandom() unnecessary. Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.66 retrieving revision 1.67 diff -u -d -r1.66 -r1.67 --- random.py 3 Sep 2004 19:09:22 -0000 1.66 +++ random.py 5 Sep 2004 00:00:41 -0000 1.67 @@ -44,6 +44,8 @@ from math import log as _log, exp as _exp, pi as _pi, e as _e from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin from math import floor as _floor +from os import urandom as _urandom +from binascii import hexlify as _hexlify __all__ = ["Random","seed","random","uniform","randint","choice","sample", "randrange","shuffle","normalvariate","lognormvariate", @@ -59,13 +61,6 @@ BPF = 53 # Number of bits in a float RECIP_BPF = 2**-BPF -try: - from os import urandom as _urandom - from binascii import hexlify as _hexlify - _urandom(1) # verify that urandom is implemented -except (ImportError, NotImplementedError): - _urandom = None - # Translated by Guido van Rossum from C source provided by # Adrian Baddeley. Adapted by Raymond Hettinger for use with @@ -111,11 +106,11 @@ """ if a is None: - if _urandom is None: + try: + a = long(_hexlify(_urandom(16)), 16) + except NotImplementedError: import time a = long(time.time() * 256) # use fractional seconds - else: - a = long(_hexlify(_urandom(16)), 16) super(Random, self).seed(a) self.gauss_next = None @@ -620,11 +615,11 @@ """ if a is None: - if _urandom is None: + try: + a = long(_hexlify(_urandom(16)), 16) + except NotImplementedError: import time a = long(time.time() * 256) # use fractional seconds - else: - a = long(_hexlify(_urandom(16)), 16) if not isinstance(a, (int, long)): a = hash(a) @@ -759,14 +754,10 @@ def random(self): """Get the next random number in the range [0.0, 1.0).""" - if _urandom is None: - raise NotImplementedError('Cannot find hardware entropy source') return (long(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF def getrandbits(self, k): """getrandbits(k) -> x. Generates a long int with k random bits.""" - if _urandom is None: - raise NotImplementedError('Cannot find hardware entropy source') if k <= 0: raise ValueError('number of bits must be greater than zero') if k != int(k): From rhettinger at users.sourceforge.net Sun Sep 5 13:42:38 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 5 13:42:44 2004 Subject: [Python-checkins] python/nondist/sandbox/statistics statistics.py, 1.12, 1.13 test_statistics.py, 1.3, 1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/statistics In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2748 Modified Files: statistics.py test_statistics.py Log Message: * removed nlargest() and nsmallest() which are now in the heapq module. * removed product() which did not fit with the rest of the module. * merged mean() and variance() into one function returning (count, mean, variance) after a single pass. * verified that the functions work with Decimal objects as well as floats. Index: statistics.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/statistics/statistics.py,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- statistics.py 2 Apr 2004 06:09:45 -0000 1.12 +++ statistics.py 5 Sep 2004 11:42:35 -0000 1.13 @@ -1,52 +1,8 @@ -"""statistics.py A collection of functions for summarizing data - -The module focuses on everyday data reduction functions and omits more -sophisticated statistical tools. - -Unless otherwise noted, each function is designed to accept any iterable -and make only a single pass over the data. This makes the tools suitable -for use with generator expressions and keeps them as memory friendly as -possible. Except for median() and select(), the use of iterators means -that the dataset can be processed one element at a time without bringing -it all into memory. - -The functions, nlargest and nsmallest, are also designed to use the fewest -possible data comparisions and the data elements may be non-numerical (such -as strings) as long they support __cmp__ or __lt__. - -Written and maintained by Raymond D. Hettinger . -Copyright (c) 2004 Python Software Foundation. All rights reserved. - -""" - from __future__ import division -import operator -import itertools -import heapq -import bisect import random -__all__ = ['mean', 'median', 'nlargest', 'nsmallest', - 'product', 'select', 'stddev'] - -def mean(data): - """Compute the arithmetic mean of a data sample""" - try: - cnt = len(data) # do it the fast way if possible - except TypeError: - cum = 0.0 - for cnt, elem in enumerate(data): - cum += elem - cnt += 1 # enumerate counts from zero - else: - cum = sum(data, 0.0) - try: - return cum / cnt - except ZeroDivisionError: - raise ValueError('data must have at least one element') - -def variance(data, sample=True): - """Computes the variance of the dataset. +def describe(data, sample=True): + """Computes the size, mean, and variance of the dataset. If sample is True, computes the variance with an n-1 divisor to reflect the additional degree of freedom in sampled data. If sample is False, @@ -80,25 +36,16 @@ m = newm if sample: try: - return (s / (k-1)) # sample variance + return (k, m, s / (k-1)) # sample variance except ZeroDivisionError: - raise ValueError('sample variance requires at least two elements') + return (k, m, None) else: - return (s / k) # population variance - -def stddev(data, sample=True): - """Computes the standard deviation of the dataset. - - If sample is True, computes the standard deviation with an n-1 divisor - for an unbiased estimator for a data sample. If sample is False, computes - with a divisor of n, giving the standard deviation for a complete population. - """ - return variance(data, sample) ** 0.5 + return (k, m, s / k, m) # population variance def select(data, n): """Find the nth rank ordered element (the least value has rank 0). - Equivalent to sorted(data)[n] + Equivalent to sorted(data)[n] but runs in O(n) time. """ data = list(data) if not 0 <= n < len(data): @@ -138,45 +85,12 @@ return select(data, n//2) return (select(data, n//2) + select(data, n//2-1)) / 2 -def product(iterable): - """Compute the product of the data elements""" - return reduce(operator.mul, iterable, 1) - -def nlargest(iterable, n=1): # XXX implement key= - """Find the n largest elements in the dataset""" - ## When collections.fibheap is available, use it instead of heapq - it = iter(iterable) - result = list(itertools.islice(it, n)) - heapq.heapify(result) - if len(result) == 0: - raise ValueError('data must have at least one element') - subst = heapq.heapreplace - sol = result[0] # sol --> Smallest of the nlargest - for elem in it: - if (elem > sol): - subst(result, elem) - sol = result[0] - result.sort(reverse=True) - return result - -def nsmallest(iterable, n=1): - """Find the n smallest elements in the dataset""" - ## When collections.fibheap is available, use it instead of bisect - it = iter(iterable) - result = sorted(itertools.islice(it, 0, n)) - if len(result) == 0: - raise ValueError('data must have at least one element') - insort = bisect.insort - pop = result.pop - los = result[-1] # los --> Largest of the nsmallest - for elem in it: - if (elem < los): - insort(result, elem) - pop() - los = result[-1] - return result - -XXX = """ - Other possible functions include data groupers for - binning, counting, and splitting into equivalence classes. -""" +if __name__ == '__main__': + print stats([3,4,5]) == (3, 4.0, 1.0) + print stats([2,4,6]) == (3, 4.0, 4.0) + print stats([3,5,7]) == (3, 5.0, 4.0) + from decimal import Decimal + print stats(map(Decimal,[3,5,7])) == (3, Decimal("5"), Decimal("4")) + print median(map(Decimal,[3,5,7])) == Decimal('5') + print median(map(Decimal,[3,5,7,9])) == Decimal('6') + print median(map(Decimal,[3,6,7,9])) == Decimal('6.5') Index: test_statistics.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/statistics/test_statistics.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- test_statistics.py 29 Feb 2004 09:12:28 -0000 1.3 +++ test_statistics.py 5 Sep 2004 11:42:36 -0000 1.4 @@ -1,5 +1,5 @@ from __future__ import division -from statistics import mean, stddev, product, nlargest, nsmallest, select, median +from statistics import describe, select, median ### UNITTESTS ################################################# @@ -15,6 +15,8 @@ class TestStats(unittest.TestCase): def test_mean(self): + def mean(data): + return describe(data)[1] self.assertEqual(mean(range(6)), 15/6.0) self.assertEqual(mean(g(6)), 15/6.0) self.assertEqual(mean([10]), 10) @@ -22,11 +24,14 @@ self.assertRaises(TypeError, mean, 'abc') def test_stddev(self): + def stddev(data, *args): + var = describe(data, *args)[2] + return var and var ** 0.5 or var self.assertEqual(stddev([10,15,20]), 5) self.assertEqual(round(stddev([11.1,4,9,13]), 3), 3.878) self.assertEqual(round(stddev([11.1,4,9,13], False), 3), 3.358) self.assertEqual(stddev([10], False), 0.0) - self.assertRaises(ValueError, stddev, [1]) + self.assertEqual(stddev([1]), None) self.assertRaises(ValueError, stddev, [], False) def test_median(self): @@ -42,13 +47,6 @@ self.assertEqual(median([30,10,2]), 10) self.assertRaises(ValueError, median, []) - def test_product(self): - self.assertEqual(product(range(1, 5)), 24) - def g(lo, hi): - for i in xrange(lo, hi): - yield i - self.assertEqual(product(g(1, 5)), 24) - def test_select(self): testdata = range(2000) + [20] * 500 + [85] * 500 sorteddata = sorted(testdata) @@ -74,30 +72,6 @@ self.assertRaises(ValueError, select, a, n+1) - def test_nlargest(self): - n = 10 - data = range(n) - random.shuffle(data) - copy = data[:] - self.assertEqual(nlargest(data), [n-1]) - self.assertRaises(ValueError, nlargest, data, 0) - for i in xrange(1, n+1): - self.assertEqual(nlargest(data, i), range(n-1, n-i-1, -1)) - self.assertEqual(data, copy) - self.assertEqual(nlargest('abcde', 3), list('edc')) - - def test_nsmallest(self): - n = 10 - data = range(n) - random.shuffle(data) - copy = data[:] - self.assertEqual(nsmallest(data), [0]) - self.assertRaises(ValueError, nlargest, data, 0) - for i in xrange(1, n+1): - self.assertEqual(nsmallest(data, i), range(i)) - self.assertEqual(data, copy) - self.assertEqual(nsmallest('abcde', 3), list('abc')) - if __name__ == '__main__': suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestStats)) From bcannon at users.sourceforge.net Sun Sep 5 21:42:17 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Sun Sep 5 21:42:20 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libxmlrpclib.tex, 1.17, 1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22126/Doc/lib Modified Files: libxmlrpclib.tex Log Message: Rework some wording. Index: libxmlrpclib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxmlrpclib.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- libxmlrpclib.tex 7 Aug 2004 17:39:35 -0000 1.17 +++ libxmlrpclib.tex 5 Sep 2004 19:42:15 -0000 1.18 @@ -170,7 +170,7 @@ \subsection{DateTime Objects \label{datetime-objects}} -This class may initialized from date in seconds since the epoch, a +This class may be initialized with seconds since the epoch, a time tuple, or an ISO 8601 time/date string. It has the following methods, supported mainly for internal use by the marshalling/unmarshalling code: From rhettinger at users.sourceforge.net Mon Sep 6 02:12:07 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 6 02:12:09 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex, 1.163, 1.164 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3272 Modified Files: libstdtypes.tex Log Message: SF bug #901654: split method documentation can be improved * Discuss the algorithmic distinctions between s.split() and s.split(sep). * Document the split behavior for empty strings. * Note the behavior when maxsplit is zero. * Include short examples. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.163 retrieving revision 1.164 diff -u -d -r1.163 -r1.164 --- libstdtypes.tex 12 Aug 2004 18:12:43 -0000 1.163 +++ libstdtypes.tex 6 Sep 2004 00:12:04 -0000 1.164 @@ -750,8 +750,22 @@ \begin{methoddesc}[string]{split}{\optional{sep \optional{,maxsplit}}} Return a list of the words in the string, using \var{sep} as the delimiter string. If \var{maxsplit} is given, at most \var{maxsplit} -splits are done. If \var{sep} is not specified or \code{None}, any -whitespace string is a separator. +splits are done. (thus, the list will have at most \code{\var{maxsplit}+1} +elements). If \var{maxsplit} is not specified or is zero, then there +is no limit on the number of splits (all possible splits are made). +Consecutive delimiters are not grouped together and are +deemed to delimit empty strings (for example, \samp{'1,,2'.split(',')} +returns \samp{['1', '', '2']}. The \var{sep} argument may consist of +multiple characters (for example, \samp{'1, 2, 3'.split(', ')} returns +\samp{['1', '2', '3']}. Splitting an empty string with a specified +separator returns an empty list. + +If \var{sep} is not specified or is \code{None}, a different splitting +algorithm is applied. Words are separated by arbitrary length strings of +whitespace characters (spaces, tabs, newlines, returns, and formfeeds). +Consecutive whitespace delimiters are treated as a single delimiter +(\samp{'1 2 3'.split()} returns \samp{['1', '2', '3']}. Splitting an +empty string returns \samp{['']}. \end{methoddesc} \begin{methoddesc}[string]{splitlines}{\optional{keepends}} From rhettinger at users.sourceforge.net Mon Sep 6 02:42:17 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 6 02:42:20 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex, 1.164, 1.165 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8146 Modified Files: libstdtypes.tex Log Message: Add missing close parenthesis. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.164 retrieving revision 1.165 diff -u -d -r1.164 -r1.165 --- libstdtypes.tex 6 Sep 2004 00:12:04 -0000 1.164 +++ libstdtypes.tex 6 Sep 2004 00:42:14 -0000 1.165 @@ -755,16 +755,16 @@ is no limit on the number of splits (all possible splits are made). Consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, \samp{'1,,2'.split(',')} -returns \samp{['1', '', '2']}. The \var{sep} argument may consist of +returns \samp{['1', '', '2']}). The \var{sep} argument may consist of multiple characters (for example, \samp{'1, 2, 3'.split(', ')} returns -\samp{['1', '2', '3']}. Splitting an empty string with a specified +\samp{['1', '2', '3']}). Splitting an empty string with a specified separator returns an empty list. If \var{sep} is not specified or is \code{None}, a different splitting algorithm is applied. Words are separated by arbitrary length strings of whitespace characters (spaces, tabs, newlines, returns, and formfeeds). Consecutive whitespace delimiters are treated as a single delimiter -(\samp{'1 2 3'.split()} returns \samp{['1', '2', '3']}. Splitting an +(\samp{'1 2 3'.split()} returns \samp{['1', '2', '3']}). Splitting an empty string returns \samp{['']}. \end{methoddesc} From rhettinger at users.sourceforge.net Mon Sep 6 03:01:11 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 6 03:01:13 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libstring.tex,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11082 Modified Files: libstring.tex Log Message: Markup nits. Index: libstring.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstring.tex,v retrieving revision 1.60 retrieving revision 1.61 diff -u -d -r1.60 -r1.61 --- libstring.tex 25 Aug 2004 03:09:58 -0000 1.60 +++ libstring.tex 6 Sep 2004 01:01:08 -0000 1.61 @@ -105,15 +105,17 @@ \item \samp{\$\{identifier\}} is equivalent to \samp{\$identifier}. It is required when valid identifier characters follow the placeholder but are - not part of the placeholder, e.g. "\$\{noun\}ification". + not part of the placeholder, such as "\$\{noun\}ification". \end{itemize} Any other appearance of \samp{\$} in the string will result in a \exception{ValueError} being raised. +\versionadded{2.4} + Template strings are used just like normal strings, in that the modulus operator is used to interpolate a dictionary of values into a Template string, -e.g.: +for example: \begin{verbatim} >>> from string import Template @@ -151,7 +153,7 @@ placeholder rule: \begin{itemize} -\item \var{escaped} -- This group matches the escape sequence, i.e. \samp{\$\$} +\item \var{escaped} -- This group matches the escape sequence, \samp{\$\$}, in the default pattern. \item \var{named} -- This group matches the unbraced placeholder name; it should not include the \samp{\$} in capturing group. @@ -242,7 +244,7 @@ \end{funcdesc} \begin{funcdesc}{expandtabs}{s\optional{, tabsize}} - Expand tabs in a string, i.e.\ replace them by one or more spaces, + Expand tabs in a string replacing them by one or more spaces, depending on the current column and the given tab size. The column number is reset to zero after each newline occurring in the string. This doesn't understand other non-printing characters or escape From loewis at users.sourceforge.net Mon Sep 6 08:31:14 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon Sep 6 08:31:18 2004 Subject: [Python-checkins] python/dist/src/Tools/msi msi.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/msi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24599 Modified Files: msi.py Log Message: Add test_difflib_expect.html. Fix open Verbs. Properly add "Edit with IDLE" to TclTk feature. Index: msi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/msi/msi.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- msi.py 1 Sep 2004 14:51:06 -0000 1.5 +++ msi.py 6 Sep 2004 06:31:12 -0000 1.6 @@ -880,6 +880,7 @@ lib.add_file("test.xml") lib.add_file("test.xml.out") lib.add_file("testtar.tar") + lib.add_file("test_difflib_expect.html") lib.glob("*.uue") lib.add_file("readme.txt", src="README") if dir=='decimaltestdata': @@ -1012,7 +1013,7 @@ # will cause pythonw.exe to be installed. tcldata = [] if have_tcl: - tcltkdata = [(tcltk.id, "REGISTRY.tcl"), + tcldata = [(tcltk.id, "REGISTRY.tcl"), (tcltk.id, "pythonw.exe")] add_data(db, "FeatureComponents", [(default_feature.id, "REGISTRY"), @@ -1032,10 +1033,10 @@ ("pyo", "python.exe", "Python.CompiledFile", None, default_feature.id)]) # add_data(db, "MIME") XXX add_data(db, "Verb", - [("py", "open", 1, None, r'-n -e "%1"'), - ("pyw", "open", 1, None, r'-n -e "%1"'), - ("pyc", "open", 1, None, r'-n -e "%1"'), - ("pyo", "open", 1, None, r'-n -e "%1"')]) + [("py", "open", 1, None, r'"%1"'), + ("pyw", "open", 1, None, r'"%1"'), + ("pyc", "open", 1, None, r'"%1"'), + ("pyo", "open", 1, None, r'"%1"')]) add_data(db, "ProgId", [("Python.File", None, None, "Python File", "python_icon.exe", 0), ("Python.NoConFile", None, None, "Python File (no console)", "python_icon.exe", 0), From rhettinger at users.sourceforge.net Mon Sep 6 09:04:11 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 6 09:04:14 2004 Subject: [Python-checkins] python/dist/src/Modules _heapqmodule.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29812/Modules Modified Files: _heapqmodule.c Log Message: Fix erroneous docstring comment. Index: _heapqmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_heapqmodule.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- _heapqmodule.c 20 Jun 2004 09:07:52 -0000 1.6 +++ _heapqmodule.c 6 Sep 2004 07:04:08 -0000 1.7 @@ -186,8 +186,9 @@ This is more efficient than heappop() followed by heappush(), and can be\n\ more appropriate when using a fixed-size heap. Note that the value\n\ returned may be larger than item! That constrains reasonable uses of\n\ -this routine unless written as part of a larger expression:\n\n\ - result = item <= heap[0] and item or heapreplace(heap, item)\n"); +this routine unless written as part of a conditional replacement:\n\n\ + if item > heap[0]:\n\ + item = heapreplace(heap, item)\n"); static PyObject * heapify(PyObject *self, PyObject *heap) From rhettinger at users.sourceforge.net Mon Sep 6 09:04:11 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 6 09:04:15 2004 Subject: [Python-checkins] python/dist/src/Lib heapq.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29812/Lib Modified Files: heapq.py Log Message: Fix erroneous docstring comment. Index: heapq.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/heapq.py,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- heapq.py 20 Jun 2004 09:07:52 -0000 1.25 +++ heapq.py 6 Sep 2004 07:04:09 -0000 1.26 @@ -154,9 +154,10 @@ This is more efficient than heappop() followed by heappush(), and can be more appropriate when using a fixed-size heap. Note that the value returned may be larger than item! That constrains reasonable uses of - this routine unless written as part of a larger expression: + this routine unless written as part of a conditional replacement: - result = item <= heap[0] and item or heapreplace(heap, item) + if item > heap[0]: + item = heapreplace(heap, item) """ returnitem = heap[0] # raises appropriate IndexError if heap is empty heap[0] = item From rhettinger at users.sourceforge.net Mon Sep 6 09:04:12 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 6 09:04:15 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libheapq.tex,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29812/Doc/lib Modified Files: libheapq.tex Log Message: Fix erroneous docstring comment. Index: libheapq.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libheapq.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- libheapq.tex 20 Jun 2004 09:07:53 -0000 1.9 +++ libheapq.tex 6 Sep 2004 07:04:09 -0000 1.10 @@ -60,9 +60,10 @@ by \function{heappush()}, and can be more appropriate when using a fixed-size heap. Note that the value returned may be larger than \var{item}! That constrains reasonable uses of this routine -unless written as part of a larger expression: +unless written as part of a conditional replacement: \begin{verbatim} - result = item <= heap[0] and item or heapreplace(heap, item) + if item > heap[0]: + item = heapreplace(heap, item) \end{verbatim} \end{funcdesc} From rhettinger at users.sourceforge.net Mon Sep 6 17:54:46 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 6 17:54:48 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex, 1.129.8.10, 1.129.8.11 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25015 Modified Files: Tag: release23-maint libstdtypes.tex Log Message: SF bug #901654: split method documentation can be improved Backport to Py2.3. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.129.8.10 retrieving revision 1.129.8.11 diff -u -d -r1.129.8.10 -r1.129.8.11 --- libstdtypes.tex 3 Jun 2004 09:48:25 -0000 1.129.8.10 +++ libstdtypes.tex 6 Sep 2004 15:54:43 -0000 1.129.8.11 @@ -719,8 +719,22 @@ \begin{methoddesc}[string]{split}{\optional{sep \optional{,maxsplit}}} Return a list of the words in the string, using \var{sep} as the delimiter string. If \var{maxsplit} is given, at most \var{maxsplit} -splits are done. If \var{sep} is not specified or \code{None}, any -whitespace string is a separator. +splits are done. (thus, the list will have at most \code{\var{maxsplit}+1} +elements). If \var{maxsplit} is not specified or is zero, then there +is no limit on the number of splits (all possible splits are made). +Consecutive delimiters are not grouped together and are +deemed to delimit empty strings (for example, \samp{'1,,2'.split(',')} +returns \samp{['1', '', '2']}). The \var{sep} argument may consist of +multiple characters (for example, \samp{'1, 2, 3'.split(', ')} returns +\samp{['1', '2', '3']}). Splitting an empty string with a specified +separator returns an empty list. + +If \var{sep} is not specified or is \code{None}, a different splitting +algorithm is applied. Words are separated by arbitrary length strings of +whitespace characters (spaces, tabs, newlines, returns, and formfeeds). +Consecutive whitespace delimiters are treated as a single delimiter +(\samp{'1 2 3'.split()} returns \samp{['1', '2', '3']}). Splitting an +empty string returns \samp{['']}. \end{methoddesc} \begin{methoddesc}[string]{splitlines}{\optional{keepends}} From rhettinger at users.sourceforge.net Mon Sep 6 18:03:39 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 6 18:03:42 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libsignal.tex, 1.25, 1.25.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26496 Modified Files: Tag: release23-maint libsignal.tex Log Message: SF bug #1020540: a wrong link from "frame object" in lib index. Backport. Index: libsignal.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsignal.tex,v retrieving revision 1.25 retrieving revision 1.25.12.1 diff -u -d -r1.25 -r1.25.12.1 --- libsignal.tex 13 Mar 2003 13:56:49 -0000 1.25 +++ libsignal.tex 6 Sep 2004 16:03:37 -0000 1.25.12.1 @@ -139,9 +139,10 @@ \exception{ValueError} exception to be raised. The \var{handler} is called with two arguments: the signal number - and the current stack frame (\code{None} or a frame object; see the - reference manual for a description of frame objects). -\obindex{frame} + and the current stack frame (\code{None} or a frame object; + for a description of frame objects, see the reference manual section + on the standard type hierarchy or see the attribute descriptions in + the \refmodule{inspect} module). \end{funcdesc} \subsection{Example} From rhettinger at users.sourceforge.net Tue Sep 7 00:57:28 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 7 00:57:32 2004 Subject: [Python-checkins] python/dist/src/Modules binascii.c,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8167 Modified Files: binascii.c Log Message: SF #1022953: binascii.a2b_hqx("") raises SystemError Several functions adopted the strategy of altering a full lengthed string copy and resizing afterwards. That would fail if the initial string was short enough (0 or 1) to be interned. Interning precluded the subsequent resizing operation. The solution was to make sure the initial string was at least two characters long. Added tests to verify that all binascii functions do not crater when given an empty string argument. Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.42 retrieving revision 2.43 diff -u -d -r2.42 -r2.43 --- binascii.c 27 Jul 2004 15:03:53 -0000 2.42 +++ binascii.c 6 Sep 2004 22:57:26 -0000 2.43 @@ -276,7 +276,7 @@ } /* We're lazy and allocate to much (fixed up later) */ - if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2)) == NULL ) + if ( (rv=PyString_FromStringAndSize(NULL, bin_len*2+2)) == NULL ) return NULL; ascii_data = (unsigned char *)PyString_AsString(rv); @@ -491,8 +491,10 @@ if ( !PyArg_ParseTuple(args, "t#:a2b_hqx", &ascii_data, &len) ) return NULL; - /* Allocate a string that is too big (fixed later) */ - if ( (rv=PyString_FromStringAndSize(NULL, len)) == NULL ) + /* Allocate a string that is too big (fixed later) + Add two to the initial length to prevent interning which + would preclude subsequent resizing. */ + if ( (rv=PyString_FromStringAndSize(NULL, len+2)) == NULL ) return NULL; bin_data = (unsigned char *)PyString_AsString(rv); @@ -528,6 +530,15 @@ Py_DECREF(rv); return NULL; } + + + assert(PyString_Check(rv)); + assert((bin_data - (unsigned char *)PyString_AsString(rv)) >= 0); + assert(!PyString_CHECK_INTERNED(rv)); + + assert(rv->ob_refcnt == 1); + + _PyString_Resize( &rv, (bin_data - (unsigned char *)PyString_AsString(rv))); if (rv) { @@ -553,7 +564,7 @@ return NULL; /* Worst case: output is twice as big as input (fixed later) */ - if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL ) + if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; out_data = (unsigned char *)PyString_AsString(rv); @@ -602,7 +613,7 @@ return NULL; /* Allocate a buffer that is at least large enough */ - if ( (rv=PyString_FromStringAndSize(NULL, len*2)) == NULL ) + if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; ascii_data = (unsigned char *)PyString_AsString(rv); From rhettinger at users.sourceforge.net Tue Sep 7 00:58:40 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 7 00:58:43 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_binascii.py, 1.18, 1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9212 Modified Files: test_binascii.py Log Message: SF #1022953: binascii.a2b_hqx("") raises SystemError Several functions adopted the strategy of altering a full lengthed string copy and resizing afterwards. That would fail if the initial string was short enough (0 or 1) to be interned. Interning precluded the subsequent resizing operation. The solution was to make sure the initial string was at least two characters long. Added tests to verify that all binascii functions do not crater when given an empty string argument. Index: test_binascii.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binascii.py,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- test_binascii.py 8 Jul 2004 04:22:19 -0000 1.18 +++ test_binascii.py 6 Sep 2004 22:58:37 -0000 1.19 @@ -148,6 +148,16 @@ "0"*75+"=\r\n=FF\r\n=FF\r\n=FF" ) + def test_empty_string(self): + # A test for SF bug #1022953. Make sure SystemError is not raised. + for n in ['b2a_qp', 'a2b_hex', 'b2a_base64', 'a2b_uu', 'a2b_qp', + 'b2a_hex', 'unhexlify', 'hexlify', 'crc32', 'b2a_hqx', + 'a2b_hqx', 'a2b_base64', 'rlecode_hqx', 'b2a_uu', + 'rledecode_hqx']: + f = getattr(binascii, n) + f('') + binascii.crc_hqx('', 0) + def test_main(): test_support.run_unittest(BinASCIITest) From rhettinger at users.sourceforge.net Tue Sep 7 01:02:40 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 7 01:02:43 2004 Subject: [Python-checkins] python/dist/src/Modules binascii.c,2.43,2.44 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10071 Modified Files: binascii.c Log Message: Remove redunandant assertions from last checkin. Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.43 retrieving revision 2.44 diff -u -d -r2.43 -r2.44 --- binascii.c 6 Sep 2004 22:57:26 -0000 2.43 +++ binascii.c 6 Sep 2004 23:02:37 -0000 2.44 @@ -530,15 +530,6 @@ Py_DECREF(rv); return NULL; } - - - assert(PyString_Check(rv)); - assert((bin_data - (unsigned char *)PyString_AsString(rv)) >= 0); - assert(!PyString_CHECK_INTERNED(rv)); - - assert(rv->ob_refcnt == 1); - - _PyString_Resize( &rv, (bin_data - (unsigned char *)PyString_AsString(rv))); if (rv) { From bcannon at users.sourceforge.net Tue Sep 7 01:30:34 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Tue Sep 7 01:30:40 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1127,1.1128 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15172/Misc Modified Files: NEWS Log Message: Ported test__locale to unittest. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1127 retrieving revision 1.1128 diff -u -d -r1.1127 -r1.1128 --- NEWS 2 Sep 2004 16:37:15 -0000 1.1127 +++ NEWS 6 Sep 2004 23:30:27 -0000 1.1128 @@ -4,6 +4,67 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python 2.4 beta 1? +================================ + +*Release date: XXXX-XX-XX* + +Core and builtins +----------------- + +... + +Extension modules +----------------- + +... + +Library +------- + +... + +Build +----- + +... + +C API +----- + +... + +Documentation +------------- + +... + +Tests +----- + +- test__locale ported to unittest + +Windows +------- + +... + +Mac +--- + +... + +New platforms +------------- + +... + +Tools/Demos +----------- + +... + + What's New in Python 2.4 alpha 3? ================================= From bcannon at users.sourceforge.net Tue Sep 7 01:31:04 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Tue Sep 7 01:31:08 2004 Subject: [Python-checkins] python/dist/src/Lib/test test__locale.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15172/Lib/test Modified Files: test__locale.py Log Message: Ported test__locale to unittest. Index: test__locale.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test__locale.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- test__locale.py 20 Aug 2004 03:47:14 -0000 1.6 +++ test__locale.py 6 Sep 2004 23:30:26 -0000 1.7 @@ -1,6 +1,8 @@ -from test.test_support import verbose, TestSkipped -from _locale import setlocale, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo -from _locale import localeconv, Error +from test.test_support import verbose, TestSkipped, run_unittest +from _locale import (setlocale, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo, + localeconv, Error) +from locale import getlocale +import unittest candidate_locales = ['es_UY', 'fr_FR', 'fi_FI', 'es_CO', 'pt_PT', 'it_IT', 'et_EE', 'es_PY', 'no_NO', 'nl_NL', 'lv_LV', 'el_GR', 'be_BY', 'fr_BE', @@ -13,26 +15,32 @@ 'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'es_ES.ISO8859-1', 'fr_FR.ISO8859-15', 'ru_RU.KOI8-R', 'ko_KR.eucKR'] -oldlocale = setlocale(LC_NUMERIC) -try: - saw_locale = 0 - for loc in candidate_locales: - try: - setlocale(LC_NUMERIC, loc) - except Error: - continue - if verbose: - print "locale %r" % loc - saw_locale = 1 - nl_radixchar = nl_langinfo(RADIXCHAR) - li_radixchar = localeconv()['decimal_point'] - if nl_radixchar != li_radixchar: - print "%r != %r" % (nl_radixchar, li_radixchar) - nl_radixchar = nl_langinfo(THOUSEP) - li_radixchar = localeconv()['thousands_sep'] - if nl_radixchar != li_radixchar: - print "%r != %r" % (nl_radixchar, li_radixchar) - if not saw_locale: - raise ImportError, "None of the listed locales found" -finally: - setlocale(LC_NUMERIC, oldlocale) +class _LocaleTests(unittest.TestCase): + + def setUp(self): + self.oldlocale = setlocale(LC_NUMERIC) + + def tearDown(self): + setlocale(LC_NUMERIC, self.oldlocale) + + def test_lc_numeric(self): + for loc in candidate_locales: + try: + setlocale(LC_NUMERIC, loc) + except Error: + continue + for li, lc in ((RADIXCHAR, "decimal_point"), + (THOUSEP, "thousands_sep")): + nl_radixchar = nl_langinfo(li) + li_radixchar = localeconv()[lc] + self.assertEquals(nl_radixchar, li_radixchar, + "%r != %r (%s); " + "supposed to be %s, set to %s" % + (nl_radixchar, li_radixchar, lc, + loc, getlocale(LC_NUMERIC)[0])) + +def test_main(): + run_unittest(_LocaleTests) + +if __name__ == '__main__': + test_main() From facundobatista at users.sourceforge.net Tue Sep 7 05:07:58 2004 From: facundobatista at users.sourceforge.net (facundobatista@users.sourceforge.net) Date: Tue Sep 7 05:08:01 2004 Subject: [Python-checkins] python/nondist/sandbox/decimal/telco telco.py, 1.2, 1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/decimal/telco In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17632 Modified Files: telco.py Log Message: Modified test file name and added instructions if it's not in place Index: telco.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/decimal/telco/telco.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- telco.py 29 Aug 2004 01:03:29 -0000 1.2 +++ telco.py 7 Sep 2004 03:07:41 -0000 1.3 @@ -1,4 +1,6 @@ -""" Telco Benchmark for measuring the performance of decimal calculations +#-*- coding: UTF-8 -*- + +""" Telco Benchmark for measuring the performance of decimal calculations http://www2.hursley.ibm.com/decimal/telco.html http://www2.hursley.ibm.com/decimal/telcoSpec.html @@ -17,7 +19,7 @@ from struct import unpack from time import clock as time from decimal import * -import sys +import sys, os # To run the full test with 1,000,000 entries: python telco.py full test = 'full' not in ' '.join(sys.argv[1:]).lower() @@ -28,7 +30,10 @@ print " Time Rate | Price Btax Dtax | Output" print "------------+----------------------+--------" else: - filename = "EXPON180.1E6" + filename = "expon180.1e6b" + if not os.access(filename, os.F_OK): + print "You must download and unzip the test file from: http://www2.hursley.ibm.com/decimal/expon180-1e6b.zip" + sys.exit(-1) expected = map(Decimal, "1004737.58 57628.30 25042.17".split()) getcontext().rounding = ROUND_DOWN From rhettinger at users.sourceforge.net Tue Sep 7 06:26:47 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 7 06:26:50 2004 Subject: [Python-checkins] python/nondist/sandbox/string alt292.py, 1.1, 1.2 curry292.py, 1.1, 1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/string In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29241 Modified Files: alt292.py curry292.py Log Message: Improve line numbering logic to handle \r, \n, and \r\n. Index: alt292.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/string/alt292.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- alt292.py 28 Aug 2004 19:12:45 -0000 1.1 +++ alt292.py 7 Sep 2004 04:26:43 -0000 1.2 @@ -96,7 +96,7 @@ return '%s' % mapping[named or braced] elif escaped: return '$' - lineno = template.count('\n', 0, mo.start(4)) + 1 + lineno = len(template[:mo.start(4)].splitlines()) raise ValueError('Invalid placeholder on line %d: %r' % (lineno, catchall)) return _pattern.sub(convert, template) @@ -124,7 +124,7 @@ return '${' + braced + '}' elif escaped: return '$' - lineno = template.count('\n', 0, mo.start(4)) + 1 + lineno = len(template[:mo.start(4)].splitlines()) raise ValueError('Invalid placeholder on line %d: %r' % (lineno, catchall)) return _pattern.sub(convert, template) Index: curry292.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/string/curry292.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- curry292.py 29 Aug 2004 21:28:41 -0000 1.1 +++ curry292.py 7 Sep 2004 04:26:44 -0000 1.2 @@ -113,7 +113,7 @@ return '%s' % mapping[named or braced] elif escaped: return '$' - lineno = template.count('\n', 0, mo.start(4)) + 1 + lineno = len(template[:mo.start(4)].splitlines()) raise ValueError('Invalid placeholder on line %d: %r' % (lineno, catchall)) return self.pattern.sub(convert, template) @@ -151,7 +151,7 @@ return '${' + braced + '}' elif escaped: return '$' - lineno = template.count('\n', 0, mo.start(4)) + 1 + lineno = len(template[:mo.start(4)].splitlines()) raise ValueError('Invalid placeholder on line %d: %r' % (lineno, catchall)) return self.pattern.sub(convert, template) From rhettinger at users.sourceforge.net Tue Sep 7 06:41:58 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 7 06:42:00 2004 Subject: [Python-checkins] python/nondist/sandbox/string alt292.py, 1.2, 1.3 curry292.py, 1.2, 1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/string In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31196 Modified Files: alt292.py curry292.py Log Message: * Adopted Martin's suggestion for trapping end user placeholder name errors. Now depends on a Unicode definitions of alphanumeric rather than locale specific definitions. The resulting code is cleaner and will run the same across all platforms and locale settings. * Reformatted the comments in the doctests. Index: alt292.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/string/alt292.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- alt292.py 7 Sep 2004 04:26:43 -0000 1.2 +++ alt292.py 7 Sep 2004 04:41:54 -0000 1.3 @@ -8,7 +8,9 @@ 'the 10 and' -Next, it makes sure the return type is a str if all the inputs are a str. Any unicode components will cause a unicode output. This matches the behavior of other re and string ops: +Next, it makes sure the return type is a str if all the inputs are a str. Any +unicode components will cause a unicode output. This matches the behavior of +other re and string ops: >>> dollarsub('the $xxx and', xxx='10') 'the 10 and' @@ -28,7 +30,8 @@ u'the 10 and' -The ValueErrors are now more specific. They include the line number and the mismatched token: +The ValueErrors are now more specific. They include the line number and the +mismatched token: >>> t = """line one ... line two @@ -40,18 +43,30 @@ ValueError: Invalid placeholder on line 3: '@malformed' -Also, the re pattern was changed just a bit to catch an important class of locale specific errors where a user may use a non-ASCII identifier. The previous implementation would match up to the first non-ASCII character and then return a KeyError if the abbreviated is (hopefully) found. Now, it returns a value error highlighting the problem identifier. Note, we still only accept Python identifiers but have improved error detection: +Also, the re pattern was changed just a bit to catch an important class of +language specific errors where a user may use a non-ASCII identifier. The +previous implementation would match up to the first non-ASCII character and +then return a KeyError if the abbreviated is (hopefully) found. Now, it +returns a value error highlighting the problem identifier. Note, we still +only accept Python identifiers but have improved error detection: ->>> import locale ->>> savloc = locale.setlocale(locale.LC_ALL) ->>> _ = locale.setlocale(locale.LC_ALL, 'spanish') >>> t = u'Returning $ma\u00F1ana or later.' >>> dollarsub(t, {}) Traceback (most recent call last): . . . ValueError: Invalid placeholder on line 1: u'ma\xf1ana' ->>> _ = locale.setlocale(locale.LC_ALL, savloc) + +Exercise safe substitution: + +>>> safedollarsub('$$ $name ${rank}', name='Guido', rank='BDFL') +'$ Guido BDFL' +>>> safedollarsub('$$ $name ${rank}') +'$ $name ${rank}' +>>> safedollarsub('$$ $@malformed ${rank}') +Traceback (most recent call last): + . . . +ValueError: Invalid placeholder on line 1: '@malformed' ''' @@ -65,11 +80,11 @@ \$([_a-z][_a-z0-9]*(?!\w))| # $ and a Python identifier \${([_a-z][_a-z0-9]*)}| # $ and a brace delimited identifier \$(\S*) # Catchall for ill-formed $ expressions -""", _re.IGNORECASE | _re.VERBOSE | _re.LOCALE) +""", _re.IGNORECASE | _re.VERBOSE | _re.UNICODE) # Pattern notes: # # The pattern for $identifier includes a negative lookahead assertion -# to make sure that the identifier is not followed by a locale specific +# to make sure that the identifier is not followed by a Unicode # alphanumeric character other than [_a-z0-9]. The idea is to make sure # not to partially match an ill-formed identifiers containing characters # from other alphabets. Without the assertion the Spanish word for Index: curry292.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/string/curry292.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- curry292.py 7 Sep 2004 04:26:44 -0000 1.2 +++ curry292.py 7 Sep 2004 04:41:54 -0000 1.3 @@ -8,7 +8,9 @@ 'the 10 and' -Next, it makes sure the return type is a str if all the inputs are a str. Any unicode components will cause a unicode output. This matches the behavior of other re and string ops: +Next, it makes sure the return type is a str if all the inputs are a str. Any +unicode components will cause a unicode output. This matches the behavior of +other re and string ops: >>> Template('the $xxx and')(xxx='10') 'the 10 and' @@ -28,7 +30,8 @@ u'the 10 and' -The ValueErrors are now more specific. They include the line number and the mismatched token: +The ValueErrors are now more specific. They include the line number and the +mismatched token: >>> t = """line one ... line two @@ -40,18 +43,19 @@ ValueError: Invalid placeholder on line 3: '@malformed' -Also, the re pattern was changed just a bit to catch an important class of locale specific errors where a user may use a non-ASCII identifier. The previous implementation would match up to the first non-ASCII character and then return a KeyError if the abbreviated is (hopefully) found. Now, it returns a value error highlighting the problem identifier. Note, we still only accept Python identifiers but have improved error detection: +Also, the re pattern was changed just a bit to catch an important class of +language specific errors where a user may use a non-ASCII identifier. The +previous implementation would match up to the first non-ASCII character and +then return a KeyError if the abbreviated is (hopefully) found. Now, it +returns a value error highlighting the problem identifier. Note, we still +only accept Python identifiers but have improved error detection: ->>> import locale ->>> savloc = locale.setlocale(locale.LC_ALL) ->>> _ = locale.setlocale(locale.LC_ALL, 'spanish') >>> t = u'Returning $ma\u00F1ana or later.' >>> Template(t)({}) Traceback (most recent call last): . . . ValueError: Invalid placeholder on line 1: u'ma\xf1ana' ->>> _ = locale.setlocale(locale.LC_ALL, savloc) Exercise safe substitution: @@ -80,11 +84,11 @@ \$([_a-z][_a-z0-9]*(?!\w))| # $ and a Python identifier \${([_a-z][_a-z0-9]*)}| # $ and a brace delimited identifier \$(\S*) # Catchall for ill-formed $ expressions - """, _re.IGNORECASE | _re.VERBOSE | _re.LOCALE) + """, _re.IGNORECASE | _re.VERBOSE | _re.UNICODE) # Pattern notes: # # The pattern for $identifier includes a negative lookahead assertion - # to make sure that the identifier is not followed by a locale specific + # to make sure that the identifier is not followed by a Unicode # alphanumeric character other than [_a-z0-9]. The idea is to make sure # not to partially match an ill-formed identifiers containing characters # from other alphabets. Without the assertion the Spanish word for From rhettinger at users.sourceforge.net Tue Sep 7 07:16:04 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 7 07:16:07 2004 Subject: [Python-checkins] python/nondist/sandbox/string alt292.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/string In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3896 Modified Files: alt292.py Log Message: Improve function names. Index: alt292.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/string/alt292.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- alt292.py 7 Sep 2004 04:41:54 -0000 1.3 +++ alt292.py 7 Sep 2004 05:15:57 -0000 1.4 @@ -2,9 +2,9 @@ First, it is now a function and accepts either mappings or keyword arguments: ->>> dollarsub('the $xxx and', {'xxx':10}) +>>> simplesub('the $xxx and', {'xxx':10}) 'the 10 and' ->>> dollarsub('the $xxx and', xxx='10') +>>> simplesub('the $xxx and', xxx='10') 'the 10 and' @@ -12,21 +12,21 @@ unicode components will cause a unicode output. This matches the behavior of other re and string ops: ->>> dollarsub('the $xxx and', xxx='10') +>>> simplesub('the $xxx and', xxx='10') 'the 10 and' ->>> dollarsub(u'the $xxx and', xxx='10') +>>> simplesub(u'the $xxx and', xxx='10') u'the 10 and' ->>> dollarsub('the $xxx and', xxx=u'10') +>>> simplesub('the $xxx and', xxx=u'10') u'the 10 and' ->>> dollarsub(u'the $xxx and', xxx=u'10') +>>> simplesub(u'the $xxx and', xxx=u'10') u'the 10 and' Non-strings are coerced to the type of the template: ->>> dollarsub('the $xxx and', xxx=10) +>>> simplesub('the $xxx and', xxx=10) 'the 10 and' ->>> dollarsub(u'the $xxx and', xxx=10) +>>> simplesub(u'the $xxx and', xxx=10) u'the 10 and' @@ -37,7 +37,7 @@ ... line two ... the $@malformed token ... line four""" ->>> dollarsub(t, {}) +>>> simplesub(t, {}) Traceback (most recent call last): . . . ValueError: Invalid placeholder on line 3: '@malformed' @@ -51,7 +51,7 @@ only accept Python identifiers but have improved error detection: >>> t = u'Returning $ma\u00F1ana or later.' ->>> dollarsub(t, {}) +>>> simplesub(t, {}) Traceback (most recent call last): . . . ValueError: Invalid placeholder on line 1: u'ma\xf1ana' @@ -59,11 +59,11 @@ Exercise safe substitution: ->>> safedollarsub('$$ $name ${rank}', name='Guido', rank='BDFL') +>>> safesimplesub('$$ $name ${rank}', name='Guido', rank='BDFL') '$ Guido BDFL' ->>> safedollarsub('$$ $name ${rank}') +>>> safesimplesub('$$ $name ${rank}') '$ $name ${rank}' ->>> safedollarsub('$$ $@malformed ${rank}') +>>> safesimplesub('$$ $@malformed ${rank}') Traceback (most recent call last): . . . ValueError: Invalid placeholder on line 1: '@malformed' @@ -101,7 +101,7 @@ del _re -def dollarsub(template, mapping=None, **kwds): +def simplesub(template, mapping=None, **kwds): """A function for supporting $-substitutions.""" if mapping is None: mapping = kwds @@ -116,7 +116,7 @@ (lineno, catchall)) return _pattern.sub(convert, template) -def safedollarsub(template, mapping=None, **kwds): +def safesimplesub(template, mapping=None, **kwds): """A function for $-substitutions. This function is 'safe' in the sense that you will never get KeyErrors if From rhettinger at users.sourceforge.net Tue Sep 7 07:22:18 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 7 07:22:20 2004 Subject: [Python-checkins] python/nondist/sandbox/string mod292.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/string In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4905 Added Files: mod292.py Log Message: Add a version using the % operator. --- NEW FILE: mod292.py --- r''' Doctests for PEP 292's string template functions Now, it makes sure the return type is a str if all the inputs are a str. Any unicode components will cause a unicode output. This matches the behavior of other re and string ops: >>> Template('the $xxx and') % dict(xxx='10') 'the 10 and' >>> Template(u'the $xxx and') % dict(xxx='10') u'the 10 and' >>> Template('the $xxx and') % dict(xxx=u'10') u'the 10 and' >>> Template(u'the $xxx and') % dict(xxx=u'10') u'the 10 and' Non-strings are auto-stringized to the type of the template: >>> Template('the $xxx and') % dict(xxx=10) 'the 10 and' >>> Template(u'the $xxx and') % dict(xxx=10) u'the 10 and' The ValueErrors are now more specific. They include the line number and the mismatched token: >>> t = """line one ... line two ... the $@malformed token ... line four""" >>> Template(t) % dict() Traceback (most recent call last): . . . ValueError: Invalid placeholder on line 3: '@malformed' Also, the re pattern was changed just a bit to catch an important class of language specific errors where a user may use a non-ASCII identifier. The previous implementation would match up to the first non-ASCII character and then return a KeyError if the abbreviated is (hopefully) found. Now, it returns a value error highlighting the problem identifier. Note, we still only accept Python identifiers but have improved error detection: >>> t = u'Returning $ma\u00F1ana or later.' >>> Template(t) % {} Traceback (most recent call last): . . . ValueError: Invalid placeholder on line 1: u'ma\xf1ana' Exercise safe substitution: >>> SafeTemplate('$$ $name ${rank}') % dict(name='Guido', rank='BDFL') '$ Guido BDFL' >>> SafeTemplate('$$ $name ${rank}') % dict() '$ $name ${rank}' >>> SafeTemplate('$$ $@malformed ${rank}') % dict() Traceback (most recent call last): . . . ValueError: Invalid placeholder on line 1: '@malformed' ''' import re as _re class Template: """A string class for supporting $-substitutions.""" __slots__ = ['tstring'] # Search for $$, $identifier, ${identifier}, and any bare $'s pattern = _re.compile(r""" \$(\$)| # Escape sequence of two $ signs \$([_a-z][_a-z0-9]*(?!\w))| # $ and a Python identifier \${([_a-z][_a-z0-9]*)}| # $ and a brace delimited identifier \$(\S*) # Catchall for ill-formed $ expressions """, _re.IGNORECASE | _re.VERBOSE | _re.UNICODE) # Pattern notes: # # The pattern for $identifier includes a negative lookahead assertion # to make sure that the identifier is not followed by a Unicode # alphanumeric character other than [_a-z0-9]. The idea is to make sure # not to partially match an ill-formed identifiers containing characters # from other alphabets. Without the assertion the Spanish word for # tomorrow "ma~nana" (where ~n is 0xF1) would improperly match of "ma" # much to the surprise of the end-user (possibly an non-programmer). # # The catchall pattern has to come last because it captures non-space # characters after a dollar sign not matched by a previous group. Those # captured characters make the error messages more informative. # # The substitution functions rely on the first three patterns matching # with a non-empty string. If that changes, then change lines like # "if named" to "if named is not None". def __init__(self, tstring): self.tstring = tstring def __mod__(self, mapping): """A function for supporting $-substitutions.""" template = self.tstring def convert(mo): escaped, named, braced, catchall = mo.groups() if named or braced: return '%s' % mapping[named or braced] elif escaped: return '$' lineno = len(template[:mo.start(4)].splitlines()) raise ValueError('Invalid placeholder on line %d: %r' % (lineno, catchall)) return self.pattern.sub(convert, template) class SafeTemplate(Template): """A string class for supporting $-substitutions. This class is 'safe' in the sense that you will never get KeyErrors if there are placeholders missing from the interpolation dictionary. In that case, you will get the original placeholder in the value string. """ __slots__ = ['tstring'] def __mod__(self, mapping): """A function for $-substitutions. This function is 'safe' in the sense that you will never get KeyErrors if there are placeholders missing from the interpolation dictionary. In that case, you will get the original placeholder in the value string. """ template = self.tstring def convert(mo): escaped, named, braced, catchall = mo.groups() if named: try: return '%s' % mapping[named] except KeyError: return '$' + named elif braced: try: return '%s' % mapping[braced] except KeyError: return '${' + braced + '}' elif escaped: return '$' lineno = len(template[:mo.start(4)].splitlines()) raise ValueError('Invalid placeholder on line %d: %r' % (lineno, catchall)) return self.pattern.sub(convert, template) del _re if __name__ == '__main__': import doctest print 'Doctest results: ', doctest.testmod() From jhylton at users.sourceforge.net Tue Sep 7 17:28:03 2004 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Tue Sep 7 17:28:06 2004 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.280,1.281 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16529/dist/src/Misc Modified Files: ACKS Log Message: compiler.transformer: correct lineno attribute when possible SF patch #1015989 The basic idea of this patch is to compute lineno attributes for all AST nodes. The actual implementation lead to a lot of restructing and code cleanup. The generated AST nodes now have an optional lineno argument to constructor. Remove the top-level asList(), since it didn't seem to serve any purpose. Add an __iter__ to ast nodes. Use isinstance() instead of explicit type tests. Change transformer to use the new lineno attribute, which replaces three lines of code with one. Use universal newlines so that we can get rid of special-case code for line endings. Use lookup_node() in a few more frequently called, but simple com_xxx methods(). Change string exception to class exception. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.280 retrieving revision 1.281 diff -u -d -r1.280 -r1.281 --- ACKS 29 Aug 2004 22:16:49 -0000 1.280 +++ ACKS 7 Sep 2004 15:28:01 -0000 1.281 @@ -563,6 +563,7 @@ Ken Stox Daniel Stutzbach Paul Swartz +Thenault Sylvain Geoff Talvola William Tanksley Christian Tanzer From jhylton at users.sourceforge.net Tue Sep 7 17:28:03 2004 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Tue Sep 7 17:28:07 2004 Subject: [Python-checkins] python/dist/src/Tools/compiler astgen.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/compiler In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16529/dist/src/Tools/compiler Modified Files: astgen.py Log Message: compiler.transformer: correct lineno attribute when possible SF patch #1015989 The basic idea of this patch is to compute lineno attributes for all AST nodes. The actual implementation lead to a lot of restructing and code cleanup. The generated AST nodes now have an optional lineno argument to constructor. Remove the top-level asList(), since it didn't seem to serve any purpose. Add an __iter__ to ast nodes. Use isinstance() instead of explicit type tests. Change transformer to use the new lineno attribute, which replaces three lines of code with one. Use universal newlines so that we can get rid of special-case code for line endings. Use lookup_node() in a few more frequently called, but simple com_xxx methods(). Change string exception to class exception. Index: astgen.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/compiler/astgen.py,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- astgen.py 2 Aug 2004 06:10:11 -0000 1.8 +++ astgen.py 7 Sep 2004 15:28:01 -0000 1.9 @@ -94,7 +94,6 @@ def gen_source(self): buf = StringIO() print >> buf, "class %s(Node):" % self.name - print >> buf, ' nodes["%s"] = "%s"' % (self.name.lower(), self.name) self._gen_init(buf) print >> buf self._gen_getChildren(buf) @@ -106,12 +105,14 @@ return buf.read() def _gen_init(self, buf): - print >> buf, " def __init__(self, %s):" % self.args + if self.args: + print >> buf, " def __init__(self, %s, lineno=None):" % self.args + else: + print >> buf, " def __init__(self, lineno=None):" if self.argnames: for name in self.argnames: print >> buf, " self.%s = %s" % (name, name) - else: - print >> buf, " pass" + print >> buf, " self.lineno = lineno" if self.init: print >> buf, "".join([" " + line for line in self.init]) @@ -128,15 +129,18 @@ else: print >> buf, " return %s" % clist else: - print >> buf, " children = []" - template = " children.%s(%sself.%s%s)" - for name in self.argnames: - if self.argprops[name] == P_NESTED: - print >> buf, template % ("extend", "flatten(", - name, ")") - else: - print >> buf, template % ("append", "", name, "") - print >> buf, " return tuple(children)" + if len(self.argnames) == 1: + print >> buf, " return tuple(flatten(self.%s))" % self.argnames[0] + else: + print >> buf, " children = []" + template = " children.%s(%sself.%s%s)" + for name in self.argnames: + if self.argprops[name] == P_NESTED: + print >> buf, template % ("extend", "flatten(", + name, ")") + else: + print >> buf, template % ("append", "", name, "") + print >> buf, " return tuple(children)" def _gen_getChildNodes(self, buf): print >> buf, " def getChildNodes(self):" @@ -158,7 +162,7 @@ template = " nodelist.%s(%sself.%s%s)" for name in self.argnames: if self.argprops[name] == P_NONE: - tmp = (" if self.%s is not None:" + tmp = (" if self.%s is not None:\n" " nodelist.append(self.%s)") print >> buf, tmp % (name, name) elif self.argprops[name] == P_NESTED: @@ -226,16 +230,15 @@ ### PROLOGUE """Python abstract syntax node definitions -This file is automatically generated. +This file is automatically generated by Tools/compiler/astgen.py """ -from types import TupleType, ListType from consts import CO_VARARGS, CO_VARKEYWORDS def flatten(list): l = [] for elt in list: t = type(elt) - if t is TupleType or t is ListType: + if t is tuple or t is list: for elt2 in flatten(elt): l.append(elt2) else: @@ -245,29 +248,17 @@ def flatten_nodes(list): return [n for n in flatten(list) if isinstance(n, Node)] -def asList(nodearg): - l = [] - for item in nodearg: - if hasattr(item, "asList"): - l.append(item.asList()) - else: - t = type(item) - if t is TupleType or t is ListType: - l.append(tuple(asList(item))) - else: - l.append(item) - return l - nodes = {} -class Node: # an abstract base class - lineno = None # provide a lineno for nodes that don't have one - def getType(self): - pass # implemented by subclass +class Node: + """Abstract base class for ast nodes.""" def getChildren(self): pass # implemented by subclasses - def asList(self): - return tuple(asList(self.getChildren())) + def __iter__(self): + for n in self.getChildren(): + yield n + def asList(self): # for backwards compatibility + return self.getChildren() def getChildNodes(self): pass # implemented by subclasses @@ -290,6 +281,6 @@ return "Expression(%s)" % (repr(self.node)) ### EPILOGUE -klasses = globals() -for k in nodes.keys(): - nodes[k] = klasses[nodes[k]] +for name, obj in globals().items(): + if isinstance(obj, type) and issubclass(obj, Node): + nodes[name.lower()] = obj From jhylton at users.sourceforge.net Tue Sep 7 17:28:03 2004 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Tue Sep 7 17:28:08 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_compiler.py, 1.6, 1.7 test_transformer.py, 1.2, 1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16529/dist/src/Lib/test Modified Files: test_compiler.py test_transformer.py Log Message: compiler.transformer: correct lineno attribute when possible SF patch #1015989 The basic idea of this patch is to compute lineno attributes for all AST nodes. The actual implementation lead to a lot of restructing and code cleanup. The generated AST nodes now have an optional lineno argument to constructor. Remove the top-level asList(), since it didn't seem to serve any purpose. Add an __iter__ to ast nodes. Use isinstance() instead of explicit type tests. Change transformer to use the new lineno attribute, which replaces three lines of code with one. Use universal newlines so that we can get rid of special-case code for line endings. Use lookup_node() in a few more frequently called, but simple com_xxx methods(). Change string exception to class exception. Index: test_compiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_compiler.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- test_compiler.py 4 Sep 2004 20:09:12 -0000 1.6 +++ test_compiler.py 7 Sep 2004 15:28:01 -0000 1.7 @@ -33,6 +33,65 @@ else: compiler.compile(buf, basename, "exec") + def testLineNo(self): + # Test that all nodes except Module have a correct lineno attribute. + filename = __file__ + if filename.endswith(".pyc") or filename.endswith(".pyo"): + filename = filename[:-1] + tree = compiler.parseFile(filename) + self.check_lineno(tree) + + def check_lineno(self, node): + try: + self._check_lineno(node) + except AssertionError: + print node.__class__, node.lineno + raise + + def _check_lineno(self, node): + if not node.__class__ in NOLINENO: + self.assert_(isinstance(node.lineno, int), + "lineno=%s on %s" % (node.lineno, node.__class__)) + self.assert_(node.lineno > 0, + "lineno=%s on %s" % (node.lineno, node.__class__)) + for child in node.getChildNodes(): + self.check_lineno(child) + +NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard) + +############################################################################### +# code below is just used to trigger some possible errors, for the benefit of +# testLineNo +############################################################################### + +class Toto: + """docstring""" + pass + +a, b = 2, 3 +[c, d] = 5, 6 +l = [(x, y) for x, y in zip(range(5), range(5,10))] +l[0] +l[3:4] +if l: + pass +else: + a, b = b, a + +try: + print yo +except: + yo = 3 +else: + yo += 3 + +try: + a += b +finally: + b = 0 + +############################################################################### + def test_main(): global TEST_ALL TEST_ALL = test.test_support.is_resource_enabled("compiler") Index: test_transformer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_transformer.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- test_transformer.py 18 Jul 2004 06:14:50 -0000 1.2 +++ test_transformer.py 7 Sep 2004 15:28:01 -0000 1.3 @@ -29,9 +29,7 @@ assert vals['b'] == 2 def test_main(): - test_support.run_unittest( - Tests - ) + test_support.run_unittest(Tests) if __name__ == "__main__": test_main() From jhylton at users.sourceforge.net Tue Sep 7 17:28:03 2004 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Tue Sep 7 17:28:08 2004 Subject: [Python-checkins] python/dist/src/Lib/compiler ast.py, 1.25, 1.26 transformer.py, 1.44, 1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/compiler In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16529/dist/src/Lib/compiler Modified Files: ast.py transformer.py Log Message: compiler.transformer: correct lineno attribute when possible SF patch #1015989 The basic idea of this patch is to compute lineno attributes for all AST nodes. The actual implementation lead to a lot of restructing and code cleanup. The generated AST nodes now have an optional lineno argument to constructor. Remove the top-level asList(), since it didn't seem to serve any purpose. Add an __iter__ to ast nodes. Use isinstance() instead of explicit type tests. Change transformer to use the new lineno attribute, which replaces three lines of code with one. Use universal newlines so that we can get rid of special-case code for line endings. Use lookup_node() in a few more frequently called, but simple com_xxx methods(). Change string exception to class exception. Index: ast.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/ast.py,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- ast.py 4 Aug 2004 02:36:17 -0000 1.25 +++ ast.py 7 Sep 2004 15:28:00 -0000 1.26 @@ -1,15 +1,14 @@ """Python abstract syntax node definitions -This file is automatically generated. +This file is automatically generated by Tools/compiler/astgen.py """ -from types import TupleType, ListType from consts import CO_VARARGS, CO_VARKEYWORDS def flatten(list): l = [] for elt in list: [...1164 lines suppressed...] class Yield(Node): - nodes["yield"] = "Yield" - def __init__(self, value): + def __init__(self, value, lineno=None): self.value = value + self.lineno = lineno def getChildren(self): return self.value, @@ -1335,6 +1311,6 @@ def __repr__(self): return "Yield(%s)" % (repr(self.value),) -klasses = globals() -for k in nodes.keys(): - nodes[k] = klasses[nodes[k]] +for name, obj in globals().items(): + if isinstance(obj, type) and issubclass(obj, Node): + nodes[name.lower()] = obj Index: transformer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/transformer.py,v retrieving revision 1.44 retrieving revision 1.45 diff -u -d -r1.44 -r1.45 --- transformer.py 31 Aug 2004 10:07:01 -0000 1.44 +++ transformer.py 7 Sep 2004 15:28:00 -0000 1.45 @@ -14,7 +14,10 @@ # # Modifications and improvements for Python 2.0 by Jeremy Hylton and # Mark Hammond - +# +# Some fixes to try to have correct line number on almost all nodes +# (except Module, Discard and Stmt) added by Sylvain Thenault +# # Portions of this file are: # Copyright (C) 1997-1998 Greg Stein. All Rights Reserved. # @@ -22,21 +25,20 @@ # http://www.opensource.org/licenses/bsd-license.html # and replace OWNER, ORGANIZATION, and YEAR as appropriate. -from ast import * +from compiler.ast import * import parser -# Care must be taken to use only symbols and tokens defined in Python -# 1.5.2 for code branches executed in 1.5.2 import symbol import token import sys -error = 'walker.error' +class WalkerError(StandardError): + pass from consts import CO_VARARGS, CO_VARKEYWORDS from consts import OP_ASSIGN, OP_DELETE, OP_APPLY def parseFile(path): - f = open(path) + f = open(path, "U") # XXX The parser API tolerates files without a trailing newline, # but not strings without a trailing newline. Always add an extra # newline to the file contents, since we're going through the string @@ -68,6 +70,16 @@ l.append(item) return l +def extractLineNo(ast): + if not isinstance(ast[1], tuple): + # get a terminal node + return ast[2] + for child in ast[1:]: + if isinstance(child, tuple): + lineno = extractLineNo(child) + if lineno is not None: + return lineno + def Node(*args): kind = args[0] if nodes.has_key(kind): @@ -77,7 +89,7 @@ print nodes[kind], len(args), args raise else: - raise error, "Can't find appropriate Node type: %s" % str(args) + raise WalkerEror, "Can't find appropriate Node type: %s" % str(args) #return apply(ast.Node, args) class Transformer: @@ -108,17 +120,14 @@ def transform(self, tree): """Transform an AST into a modified parse tree.""" - if type(tree) != type(()) and type(tree) != type([]): + if not (isinstance(tree, tuple) or isinstance(tree, list)): tree = parser.ast2tuple(tree, line_info=1) return self.compile_node(tree) def parsesuite(self, text): """Return a modified parse tree for the given suite text.""" - # Hack for handling non-native line endings on non-DOS like OSs. - # this can go now we have universal newlines? - text = text.replace('\x0d', '') return self.transform(parser.suite(text)) - + def parseexpr(self, text): """Return a modified parse tree for the given expression text.""" return self.transform(parser.expr(text)) @@ -156,7 +165,7 @@ if n == symbol.classdef: return self.classdef(node[1:]) - raise error, ('unexpected node type', n) + raise WalkerEror, ('unexpected node type', n) def single_input(self, node): ### do we want to do anything about being "interactive" ? @@ -254,9 +263,8 @@ assert isinstance(code, Stmt) assert isinstance(code.nodes[0], Discard) del code.nodes[0] - n = Function(decorators, name, names, defaults, flags, doc, code) - n.lineno = lineno - return n + return Function(decorators, name, names, defaults, flags, doc, code, + lineno=lineno) def lambdef(self, nodelist): # lambdef: 'lambda' [varargslist] ':' test @@ -269,9 +277,7 @@ # code for lambda code = self.com_node(nodelist[-1]) - n = Lambda(names, defaults, flags, code) - n.lineno = nodelist[1][2] - return n + return Lambda(names, defaults, flags, code, lineno=nodelist[1][2]) def classdef(self, nodelist): # classdef: 'class' NAME ['(' testlist ')'] ':' suite @@ -291,9 +297,7 @@ assert isinstance(code.nodes[0], Discard) del code.nodes[0] - n = Class(name, bases, doc, code) - n.lineno = nodelist[1][2] - return n + return Class(name, bases, doc, code, lineno=nodelist[1][2]) def stmt(self, nodelist): return self.com_stmt(nodelist[0]) @@ -310,31 +314,31 @@ return Stmt(stmts) def parameters(self, nodelist): - raise error + raise WalkerEror def varargslist(self, nodelist): - raise error + raise WalkerEror def fpdef(self, nodelist): - raise error + raise WalkerEror def fplist(self, nodelist): - raise error + raise WalkerEror def dotted_name(self, nodelist): - raise error + raise WalkerEror def comp_op(self, nodelist): - raise error + raise WalkerEror def trailer(self, nodelist): - raise error + raise WalkerEror def sliceop(self, nodelist): - raise error + raise WalkerEror def argument(self, nodelist): - raise error + raise WalkerEror # -------------------------------------------------------------- # @@ -346,21 +350,17 @@ en = nodelist[-1] exprNode = self.lookup_node(en)(en[1:]) if len(nodelist) == 1: - n = Discard(exprNode) - n.lineno = exprNode.lineno - return n + return Discard(exprNode, lineno=exprNode.lineno) if nodelist[1][0] == token.EQUAL: nodesl = [] for i in range(0, len(nodelist) - 2, 2): nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN)) - n = Assign(nodesl, exprNode) - n.lineno = nodelist[1][2] + return Assign(nodesl, exprNode, lineno=nodelist[1][2]) else: lval = self.com_augassign(nodelist[0]) op = self.com_augassign_op(nodelist[1]) - n = AugAssign(lval, op[1], exprNode) - n.lineno = op[2] - return n + return AugAssign(lval, op[1], exprNode, lineno=op[2]) + raise WalkerError, "can't get here" def print_stmt(self, nodelist): # print ([ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ]) @@ -379,45 +379,29 @@ for i in range(start, len(nodelist), 2): items.append(self.com_node(nodelist[i])) if nodelist[-1][0] == token.COMMA: - n = Print(items, dest) - n.lineno = nodelist[0][2] - return n - n = Printnl(items, dest) - n.lineno = nodelist[0][2] - return n + return Print(items, dest, lineno=nodelist[0][2]) + return Printnl(items, dest, lineno=nodelist[0][2]) def del_stmt(self, nodelist): return self.com_assign(nodelist[1], OP_DELETE) def pass_stmt(self, nodelist): - n = Pass() - n.lineno = nodelist[0][2] - return n + return Pass(lineno=nodelist[0][2]) def break_stmt(self, nodelist): - n = Break() - n.lineno = nodelist[0][2] - return n + return Break(lineno=nodelist[0][2]) def continue_stmt(self, nodelist): - n = Continue() - n.lineno = nodelist[0][2] - return n + return Continue(lineno=nodelist[0][2]) def return_stmt(self, nodelist): # return: [testlist] if len(nodelist) < 2: - n = Return(Const(None)) - n.lineno = nodelist[0][2] - return n - n = Return(self.com_node(nodelist[1])) - n.lineno = nodelist[0][2] - return n + return Return(Const(None), lineno=nodelist[0][2]) + return Return(self.com_node(nodelist[1]), lineno=nodelist[0][2]) def yield_stmt(self, nodelist): - n = Yield(self.com_node(nodelist[1])) - n.lineno = nodelist[0][2] - return n + return Yield(self.com_node(nodelist[1]), lineno=nodelist[0][2]) def raise_stmt(self, nodelist): # raise: [test [',' test [',' test]]] @@ -433,9 +417,7 @@ expr1 = self.com_node(nodelist[1]) else: expr1 = None - n = Raise(expr1, expr2, expr3) - n.lineno = nodelist[0][2] - return n + return Raise(expr1, expr2, expr3, lineno=nodelist[0][2]) def import_stmt(self, nodelist): # import_stmt: import_name | import_from @@ -444,9 +426,8 @@ def import_name(self, nodelist): # import_name: 'import' dotted_as_names - n = Import(self.com_dotted_as_names(nodelist[1])) - n.lineno = nodelist[0][2] - return n + return Import(self.com_dotted_as_names(nodelist[1]), + lineno=nodelist[0][2]) def import_from(self, nodelist): # import_from: 'from' dotted_name 'import' ('*' | @@ -456,21 +437,19 @@ assert nodelist[2][1] == 'import' fromname = self.com_dotted_name(nodelist[1]) if nodelist[3][0] == token.STAR: - n = From(fromname, [('*', None)]) + # TODO(jhylton): where is the lineno? + return From(fromname, [('*', None)]) else: node = nodelist[3 + (nodelist[3][0] == token.LPAR)] - n = From(fromname, self.com_import_as_names(node)) - n.lineno = nodelist[0][2] - return n + return From(fromname, self.com_import_as_names(node), + lineno=nodelist[0][2]) def global_stmt(self, nodelist): # global: NAME (',' NAME)* names = [] for i in range(1, len(nodelist), 2): names.append(nodelist[i][1]) - n = Global(names) - n.lineno = nodelist[0][2] - return n + return Global(names, lineno=nodelist[0][2]) def exec_stmt(self, nodelist): # exec_stmt: 'exec' expr ['in' expr [',' expr]] @@ -484,9 +463,7 @@ else: expr2 = expr3 = None - n = Exec(expr1, expr2, expr3) - n.lineno = nodelist[0][2] - return n + return Exec(expr1, expr2, expr3, lineno=nodelist[0][2]) def assert_stmt(self, nodelist): # 'assert': test, [',' test] @@ -495,9 +472,7 @@ expr2 = self.com_node(nodelist[3]) else: expr2 = None - n = Assert(expr1, expr2) - n.lineno = nodelist[0][2] - return n + return Assert(expr1, expr2, lineno=nodelist[0][2]) def if_stmt(self, nodelist): # if: test ':' suite ('elif' test ':' suite)* ['else' ':' suite] @@ -512,9 +487,7 @@ ## elseNode.lineno = nodelist[-1][1][2] else: elseNode = None - n = If(tests, elseNode) - n.lineno = nodelist[0][2] - return n + return If(tests, elseNode, lineno=nodelist[0][2]) def while_stmt(self, nodelist): # 'while' test ':' suite ['else' ':' suite] @@ -527,9 +500,7 @@ else: elseNode = None - n = While(testNode, bodyNode, elseNode) - n.lineno = nodelist[0][2] - return n + return While(testNode, bodyNode, elseNode, lineno=nodelist[0][2]) def for_stmt(self, nodelist): # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] @@ -543,9 +514,8 @@ else: elseNode = None - n = For(assignNode, listNode, bodyNode, elseNode) - n.lineno = nodelist[0][2] - return n + return For(assignNode, listNode, bodyNode, elseNode, + lineno=nodelist[0][2]) def try_stmt(self, nodelist): # 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] @@ -601,9 +571,7 @@ # 'not' not_test | comparison result = self.com_node(nodelist[-1]) if len(nodelist) == 2: - n = Not(result) - n.lineno = nodelist[0][2] - return n + return Not(result, lineno=nodelist[0][2]) return result def comparison(self, nodelist): @@ -637,9 +605,7 @@ # the two have very different semantics and results (note that the # latter form is always true) - n = Compare(node, results) - n.lineno = lineno - return n + return Compare(node, results, lineno=lineno) def expr(self, nodelist): # xor_expr ('|' xor_expr)* @@ -659,11 +625,9 @@ for i in range(2, len(nodelist), 2): right = self.com_node(nodelist[i]) if nodelist[i-1][0] == token.LEFTSHIFT: - node = LeftShift([node, right]) - node.lineno = nodelist[1][2] + node = LeftShift([node, right], lineno=nodelist[1][2]) elif nodelist[i-1][0] == token.RIGHTSHIFT: - node = RightShift([node, right]) - node.lineno = nodelist[1][2] + node = RightShift([node, right], lineno=nodelist[1][2]) else: raise ValueError, "unexpected token: %s" % nodelist[i-1][0] return node @@ -673,11 +637,9 @@ for i in range(2, len(nodelist), 2): right = self.com_node(nodelist[i]) if nodelist[i-1][0] == token.PLUS: - node = Add([node, right]) - node.lineno = nodelist[1][2] + node = Add([node, right], lineno=nodelist[1][2]) elif nodelist[i-1][0] == token.MINUS: - node = Sub([node, right]) - node.lineno = nodelist[1][2] + node = Sub([node, right], lineno=nodelist[1][2]) else: raise ValueError, "unexpected token: %s" % nodelist[i-1][0] return node @@ -703,17 +665,14 @@ def factor(self, nodelist): elt = nodelist[0] t = elt[0] - node = self.com_node(nodelist[-1]) + node = self.lookup_node(nodelist[-1])(nodelist[-1][1:]) # need to handle (unary op)constant here... if t == token.PLUS: - node = UnaryAdd(node) - node.lineno = elt[2] + return UnaryAdd(node, lineno=elt[2]) elif t == token.MINUS: - node = UnarySub(node) - node.lineno = elt[2] + return UnarySub(node, lineno=elt[2]) elif t == token.TILDE: - node = Invert(node) - node.lineno = elt[2] + node = Invert(node, lineno=elt[2]) return node def power(self, nodelist): @@ -722,31 +681,26 @@ for i in range(1, len(nodelist)): elt = nodelist[i] if elt[0] == token.DOUBLESTAR: - n = Power([node, self.com_node(nodelist[i+1])]) - n.lineno = elt[2] - return n + return Power([node, self.com_node(nodelist[i+1])], + lineno=elt[2]) node = self.com_apply_trailer(node, elt) return node def atom(self, nodelist): - n = self._atom_dispatch[nodelist[0][0]](nodelist) + return self._atom_dispatch[nodelist[0][0]](nodelist) n.lineno = nodelist[0][2] return n def atom_lpar(self, nodelist): if nodelist[1][0] == token.RPAR: - n = Tuple(()) - n.lineno = nodelist[0][2] - return n + return Tuple(()) return self.com_node(nodelist[1]) def atom_lsqb(self, nodelist): if nodelist[1][0] == token.RSQB: - n = List(()) - n.lineno = nodelist[0][2] - return n + return List(()) return self.com_list_constructor(nodelist[1]) def atom_lbrace(self, nodelist): @@ -755,16 +709,12 @@ return self.com_dictmaker(nodelist[1]) def atom_backquote(self, nodelist): - n = Backquote(self.com_node(nodelist[1])) - n.lineno = nodelist[0][2] - return n + return Backquote(self.com_node(nodelist[1])) def atom_number(self, nodelist): ### need to verify this matches compile.c k = eval(nodelist[0][1]) - n = Const(k) - n.lineno = nodelist[0][2] - return n + return Const(k, lineno=nodelist[0][2]) def decode_literal(self, lit): if self.encoding: @@ -781,15 +731,10 @@ k = '' for node in nodelist: k += self.decode_literal(node[1]) - n = Const(k) - n.lineno = nodelist[0][2] - return n + return Const(k, lineno=nodelist[0][2]) def atom_name(self, nodelist): - ### any processing to do? - n = Name(nodelist[0][1]) - n.lineno = nodelist[0][2] - return n + return Name(nodelist[0][1], lineno=nodelist[0][2]) # -------------------------------------------------------------- # @@ -807,6 +752,8 @@ def lookup_node(self, node): return self._dispatch[node[0]] + _callers = {} + def com_node(self, node): # Note: compile.c has handling in com_node for del_stmt, pass_stmt, # break_stmt, stmt, small_stmt, flow_stmt, simple_stmt, @@ -865,6 +812,7 @@ i = i + 2 elif len(defaults): # Treat "(a=1, b)" as "(a=1, b=None)" + print nodelist[i] defaults.append(Const(None)) i = i + 1 @@ -938,10 +886,9 @@ def com_try_finally(self, nodelist): # try_fin_stmt: "try" ":" suite "finally" ":" suite - n = TryFinally(self.com_node(nodelist[2]), - self.com_node(nodelist[5])) - n.lineno = nodelist[0][2] - return n + return TryFinally(self.com_node(nodelist[2]), + self.com_node(nodelist[5]), + lineno=nodelist[0][2]) def com_try_except(self, nodelist): # try_except: 'try' ':' suite (except_clause ':' suite)* ['else' suite] @@ -965,9 +912,8 @@ if node[0] == token.NAME: elseNode = self.com_node(nodelist[i+2]) - n = TryExcept(self.com_node(nodelist[2]), clauses, elseNode) - n.lineno = nodelist[0][2] - return n + return TryExcept(self.com_node(nodelist[2]), clauses, elseNode, + lineno=nodelist[0][2]) def com_augassign_op(self, node): assert node[0] == symbol.augassign @@ -1031,7 +977,7 @@ assigns = [] for i in range(1, len(node), 2): assigns.append(self.com_assign(node[i], assigning)) - return AssTuple(assigns) + return AssTuple(assigns, lineno=extractLineNo(node)) def com_assign_list(self, node, assigning): assigns = [] @@ -1041,12 +987,10 @@ raise SyntaxError, "can't assign to list comprehension" assert node[i + 1][0] == token.COMMA, node[i + 1] assigns.append(self.com_assign(node[i], assigning)) - return AssList(assigns) + return AssList(assigns, lineno=extractLineNo(node)) def com_assign_name(self, node, assigning): - n = AssName(node[1], assigning) - n.lineno = node[2] - return n + return AssName(node[1], assigning, lineno=node[2]) def com_assign_trailer(self, primary, node, assigning): t = node[1][0] @@ -1059,7 +1003,7 @@ raise SyntaxError, "unknown trailer type: %s" % t def com_assign_attr(self, primary, node, assigning): - return AssAttr(primary, node[1], assigning) + return AssAttr(primary, node[1], assigning, lineno=node[-1]) def com_binary(self, constructor, nodelist): "Compile 'NODE (OP NODE)*' into (type, [ node1, ..., nodeN ])." @@ -1071,7 +1015,7 @@ for i in range(0, l, 2): n = nodelist[i] items.append(self.lookup_node(n)(n[1:])) - return constructor(items) + return constructor(items, lineno=extractLineNo(nodelist)) def com_stmt(self, node): result = self.lookup_node(node)(node[1:]) @@ -1081,7 +1025,7 @@ return Stmt([result]) def com_append_stmt(self, stmts, node): - result = self.com_node(node) + result = self.lookup_node(node)(node[1:]) assert result is not None if isinstance(result, Stmt): stmts.extend(result.nodes) @@ -1100,7 +1044,7 @@ elif nodelist[i][0] == token.COMMA: continue values.append(self.com_node(nodelist[i])) - return List(values) + return List(values, lineno=values[0].lineno) def com_list_comprehension(self, expr, node): # list_iter: list_for | list_if @@ -1125,8 +1069,7 @@ node = self.com_list_iter(node[5]) elif t == 'if': test = self.com_node(node[2]) - newif = ListCompIf(test) - newif.lineno = node[1][2] + newif = ListCompIf(test, lineno=node[1][2]) newfor.ifs.append(newif) if len(node) == 3: node = None @@ -1136,9 +1079,7 @@ raise SyntaxError, \ ("unexpected list comprehension element: %s %d" % (node, lineno)) - n = ListComp(expr, fors) - n.lineno = lineno - return n + return ListComp(expr, fors, lineno=lineno) def com_list_iter(self, node): assert node[0] == symbol.list_iter @@ -1163,8 +1104,8 @@ if t == 'for': assignNode = self.com_assign(node[2], OP_ASSIGN) genNode = self.com_node(node[4]) - newfor = GenExprFor(assignNode, genNode, []) - newfor.lineno = node[1][2] + newfor = GenExprFor(assignNode, genNode, [], + lineno=node[1][2]) fors.append(newfor) if (len(node)) == 5: node = None @@ -1172,8 +1113,7 @@ node = self.com_gen_iter(node[5]) elif t == 'if': test = self.com_node(node[2]) - newif = GenExprIf(test) - newif.lineno = node[1][2] + newif = GenExprIf(test, lineno=node[1][2]) newfor.ifs.append(newif) if len(node) == 3: node = None @@ -1184,9 +1124,7 @@ ("unexpected generator expression element: %s %d" % (node, lineno)) fors[0].is_outmost = True - n = GenExpr(GenExprInner(expr, fors)) - n.lineno = lineno - return n + return GenExpr(GenExprInner(expr, fors), lineno=lineno) def com_gen_iter(self, node): assert node[0] == symbol.gen_iter @@ -1214,13 +1152,11 @@ def com_select_member(self, primaryNode, nodelist): if nodelist[0] != token.NAME: raise SyntaxError, "member must be a name" - n = Getattr(primaryNode, nodelist[1]) - n.lineno = nodelist[2] - return n + return Getattr(primaryNode, nodelist[1], lineno=nodelist[2]) def com_call_function(self, primaryNode, nodelist): if nodelist[0] == token.RPAR: - return CallFunc(primaryNode, []) + return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist)) args = [] kw = 0 len_nodelist = len(nodelist) @@ -1253,8 +1189,8 @@ dstar_node = self.com_node(ch) else: raise SyntaxError, 'unknown node type: %s' % tok - - return CallFunc(primaryNode, args, star_node, dstar_node) + return CallFunc(primaryNode, args, star_node, dstar_node, + lineno=extractLineNo(nodelist)) def com_argument(self, nodelist, kw): if len(nodelist) == 3 and nodelist[2][0] == symbol.gen_for: @@ -1270,8 +1206,7 @@ n = n[1] if n[0] != token.NAME: raise SyntaxError, "keyword can't be an expression (%s)"%n[0] - node = Keyword(n[1], result) - node.lineno = n[2] + node = Keyword(n[1], result, lineno=n[2]) return 1, node def com_subscriptlist(self, primary, nodelist, assigning): @@ -1291,8 +1226,8 @@ subscripts = [] for i in range(1, len(nodelist), 2): subscripts.append(self.com_subscript(nodelist[i])) - - return Subscript(primary, assigning, subscripts) + return Subscript(primary, assigning, subscripts, + lineno=extractLineNo(nodelist)) def com_subscript(self, node): # slice_item: expression | proper_slice | ellipsis @@ -1338,8 +1273,7 @@ items.append(Const(None)) else: items.append(self.com_node(ch[2])) - - return Sliceobj(items) + return Sliceobj(items, lineno=extractLineNo(node)) def com_slice(self, primary, node, assigning): # short_slice: [lower_bound] ":" [upper_bound] @@ -1352,7 +1286,8 @@ elif len(node) == 4: lower = self.com_node(node[1]) upper = self.com_node(node[3]) - return Slice(primary, assigning, lower, upper) + return Slice(primary, assigning, lower, upper, + lineno=extractLineNo(node)) def get_docstring(self, node, n=None): if n is None: From jhylton at users.sourceforge.net Tue Sep 7 17:36:59 2004 From: jhylton at users.sourceforge.net (jhylton@users.sourceforge.net) Date: Tue Sep 7 17:37:02 2004 Subject: [Python-checkins] python/dist/src/Lib/compiler transformer.py, 1.45, 1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/compiler In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18071/dist/src/Lib/compiler Modified Files: transformer.py Log Message: Remove debugging print (not triggered by test suite) and add XXX comment about how the code should raise a SyntaxError. Index: transformer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/transformer.py,v retrieving revision 1.45 retrieving revision 1.46 diff -u -d -r1.45 -r1.46 --- transformer.py 7 Sep 2004 15:28:00 -0000 1.45 +++ transformer.py 7 Sep 2004 15:36:48 -0000 1.46 @@ -811,8 +811,8 @@ defaults.append(self.com_node(nodelist[i + 1])) i = i + 2 elif len(defaults): + # XXX This should be a syntax error. # Treat "(a=1, b)" as "(a=1, b=None)" - print nodelist[i] defaults.append(Const(None)) i = i + 1 From loewis at users.sourceforge.net Tue Sep 7 17:36:59 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue Sep 7 17:37:02 2004 Subject: [Python-checkins] python/dist/src/PCbuild launcher.vcproj, NONE, 1.1 pcbuild.sln, 1.3, 1.4 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18065 Modified Files: pcbuild.sln Added Files: launcher.vcproj Log Message: Add launcher program --- NEW FILE: launcher.vcproj --- Index: pcbuild.sln =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pcbuild.sln,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- pcbuild.sln 20 Jul 2004 14:37:47 -0000 1.3 +++ pcbuild.sln 7 Sep 2004 15:36:46 -0000 1.4 @@ -79,6 +79,10 @@ {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launcher", "launcher.vcproj", "{065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -181,6 +185,12 @@ {680CDC79-9CCA-4282-9A8D-927CB0DB55B2}.Release.Build.0 = Release|Win32 {680CDC79-9CCA-4282-9A8D-927CB0DB55B2}.ReleaseItanium.ActiveCfg = Release|Win32 {680CDC79-9CCA-4282-9A8D-927CB0DB55B2}.ReleaseItanium.Build.0 = Release|Win32 + {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.Debug.ActiveCfg = Debug|Win32 + {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.Debug.Build.0 = Debug|Win32 + {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.Release.ActiveCfg = Release|Win32 + {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.Release.Build.0 = Release|Win32 + {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32 + {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.ReleaseItanium.Build.0 = ReleaseItanium|Win32 EndGlobalSection GlobalSection(SolutionItems) = postSolution readme.txt = readme.txt From loewis at users.sourceforge.net Tue Sep 7 17:37:29 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue Sep 7 17:37:31 2004 Subject: [Python-checkins] python/dist/src/Tools/msi msilib.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/msi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18193 Modified Files: msilib.py Log Message: Support Python 2.2. Index: msilib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/msi/msilib.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- msilib.py 22 Aug 2004 19:42:56 -0000 1.2 +++ msilib.py 7 Sep 2004 15:37:26 -0000 1.3 @@ -7,6 +7,11 @@ from win32com.client import constants import re, string, os, sets, glob, popen2, sys, _winreg +try: + basestring +except NameError: + basestring = (str, unicode) + Win64 = 0 # Partially taken from Wine From loewis at users.sourceforge.net Tue Sep 7 17:39:32 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue Sep 7 17:39:35 2004 Subject: [Python-checkins] python/dist/src/Tools/msi msi.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/msi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18571 Modified Files: msi.py Log Message: Implement conditional extensions through launcher.exe. Index: msi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/msi/msi.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- msi.py 6 Sep 2004 06:31:12 -0000 1.6 +++ msi.py 7 Sep 2004 15:39:29 -0000 1.7 @@ -135,10 +135,6 @@ # b) it is NT, the user is privileged, and has chosen per-machine installation sys32cond = "(Windows9x or (Privileged and ALLUSERS))" -# Install extensions if the feature goes into -# INSTALLSTATE_ADVERTISED or INSTALLSTATE_LOCAL -want_extensions = "(&Extensions = 1) or (&Extensions = 3)" - def build_database(): """Generate an empty database, with just the schema and the Summary information stream.""" @@ -164,15 +160,6 @@ # back in case the installation is interrupted msilib.change_sequence(sequence.InstallExecuteSequence, "RemoveExistingProducts", 1510) - # Conditionalize Extension information - msilib.change_sequence(sequence.InstallExecuteSequence, - "RegisterClassInfo", cond=want_extensions) - msilib.change_sequence(sequence.InstallExecuteSequence, - "RegisterExtensionInfo", cond=want_extensions) - msilib.change_sequence(sequence.InstallExecuteSequence, - "RegisterProgIdInfo", cond=want_extensions) - msilib.change_sequence(sequence.InstallExecuteSequence, - "RegisterMIMEInfo", cond=want_extensions) msilib.add_tables(db, sequence) # We cannot set ALLUSERS in the property table, as this cannot be # reset if the user choses a per-user installation. Instead, we @@ -825,6 +812,8 @@ root.add_file("PCBuild/python.exe") root.start_component("pythonw.exe", keyfile="pythonw.exe") root.add_file("PCBuild/pythonw.exe") + root.start_component("launcher.exe", feature=ext_feature, keyfile="launcher.exe") + root.add_file("PCBuild/launcher.exe") # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table" dlldir = PyDirectory(db, cab, root, srcdir, "DLLDIR", ".") @@ -998,7 +987,8 @@ if have_tcl: tcldata = [ ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", 4, - "&%s <> 2" % ext_feature.id, "py.IDLE")] + "&%s <> 2" % ext_feature.id, + "py.IDLE")] add_data(db, "Component", # msidbComponentAttributesRegistryKeyPath = 4 [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", 4, None, @@ -1027,16 +1017,16 @@ pat3 = r"Software\Classes\%sPython.%sFile" # Advertised extensions add_data(db, "Extension", - [("py", "python.exe", "Python.File", None, default_feature.id), - ("pyw", "pythonw.exe", "Python.NoConFile", None, default_feature.id), - ("pyc", "python.exe", "Python.CompiledFile", None, default_feature.id), - ("pyo", "python.exe", "Python.CompiledFile", None, default_feature.id)]) + [("py", "launcher.exe", "Python.File", None, ext_feature.id), + ("pyw", "launcher.exe", "Python.NoConFile", None, ext_feature.id), + ("pyc", "launcher.exe", "Python.CompiledFile", None, ext_feature.id), + ("pyo", "launcher.exe", "Python.CompiledFile", None, ext_feature.id)]) # add_data(db, "MIME") XXX add_data(db, "Verb", - [("py", "open", 1, None, r'"%1"'), + [("py", "open", 1, None, r'-console "%1"'), ("pyw", "open", 1, None, r'"%1"'), - ("pyc", "open", 1, None, r'"%1"'), - ("pyo", "open", 1, None, r'"%1"')]) + ("pyc", "open", 1, None, r'-console "%1"'), + ("pyo", "open", 1, None, r'-console "%1"')]) add_data(db, "ProgId", [("Python.File", None, None, "Python File", "python_icon.exe", 0), ("Python.NoConFile", None, None, "Python File (no console)", "python_icon.exe", 0), From loewis at users.sourceforge.net Tue Sep 7 17:40:14 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue Sep 7 17:40:16 2004 Subject: [Python-checkins] python/dist/src/PC WinMain.c,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18738 Modified Files: WinMain.c Log Message: Add support for launcher.exe Index: WinMain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/WinMain.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- WinMain.c 2 Aug 2002 02:27:12 -0000 1.8 +++ WinMain.c 7 Sep 2004 15:40:12 -0000 1.9 @@ -2,9 +2,25 @@ #define WIN32_LEAN_AND_MEAN #include +#include #include "Python.h" +#ifdef LAUNCHER +/* Q105305 suggests this routine to adjust the handles. */ +static void adjust_file(DWORD handle, FILE* f, char* mode) +{ + int hCrt; + FILE *hf; + hCrt = _open_osfhandle((intptr_t)GetStdHandle(handle), _O_TEXT); + hf = _fdopen(hCrt, mode); + *f = *hf; + setvbuf(f, NULL, _IONBF, 0); + /* Alternatively, we could use __set_app_type and _set_osfhnd, + but that appears to be undocumented. */ +} +#endif + int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ HINSTANCE hPrevInstance, /* handle to previous instance */ @@ -12,5 +28,19 @@ int nCmdShow /* show state of window */ ) { +#ifdef LAUNCHER + int i; + if (__argc > 1 && strcmp(__argv[1], "-console") == 0) { + /* Allocate a console, and remove the -console argument. */ + AllocConsole(); + for (i = 2; i < __argc; i++) + __argv[i-1] = __argv[i]; + __argc--; + /* Make stdin, stdout, stderr use the newly allocated OS handles. */ + adjust_file(STD_INPUT_HANDLE, stdin, "r"); + adjust_file(STD_OUTPUT_HANDLE, stdout, "w"); + adjust_file(STD_ERROR_HANDLE, stderr, "w"); + } +#endif return Py_Main(__argc, __argv); } From tmick at users.sourceforge.net Tue Sep 7 19:48:29 2004 From: tmick at users.sourceforge.net (tmick@users.sourceforge.net) Date: Tue Sep 7 19:48:32 2004 Subject: [Python-checkins] python/dist/src/Modules socketmodule.c, 1.304, 1.305 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10162 Modified Files: socketmodule.c Log Message: Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.304 retrieving revision 1.305 diff -u -d -r1.304 -r1.305 --- socketmodule.c 26 Aug 2004 00:51:16 -0000 1.304 +++ socketmodule.c 7 Sep 2004 17:48:26 -0000 1.305 @@ -257,7 +257,19 @@ # define O_NONBLOCK O_NDELAY #endif -#include "addrinfo.h" +/* include Python's addrinfo.h unless it causes trouble */ +#if defined(__sgi) && _COMPILER_VERSION>700 && defined(_SS_ALIGNSIZE) + /* Do not include addinfo.h on some newer IRIX versions. + * _SS_ALIGNSIZE is defined in sys/socket.h by 6.5.21, + * for example, but not by 6.5.10. + */ +#elif defined(_MSC_VER) && _MSC_VER>1200 + /* Do not include addrinfo.h for MSVC7 or greater. 'addrinfo' and + * EAI_* constants are defined in (the already included) ws2tcpip.h. + */ +#else +# include "addrinfo.h" +#endif #ifndef HAVE_INET_PTON int inet_pton(int af, const char *src, void *dst); From bwarsaw at users.sourceforge.net Tue Sep 7 21:14:45 2004 From: bwarsaw at users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue Sep 7 21:14:48 2004 Subject: [Python-checkins] python/nondist/sandbox/string alt292.py, 1.4, 1.5 curry292.py, 1.3, 1.4 mod292.py, 1.1, 1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/string In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28009 Modified Files: alt292.py curry292.py mod292.py Log Message: tqs fiddling for emacs happification Index: alt292.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/string/alt292.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- alt292.py 7 Sep 2004 05:15:57 -0000 1.4 +++ alt292.py 7 Sep 2004 19:14:42 -0000 1.5 @@ -1,4 +1,4 @@ -r''' Doctests for PEP 292's string template functions +r"""Doctests for PEP 292's string template functions First, it is now a function and accepts either mappings or keyword arguments: @@ -33,10 +33,10 @@ The ValueErrors are now more specific. They include the line number and the mismatched token: ->>> t = """line one +>>> t = '''line one ... line two ... the $@malformed token -... line four""" +... line four''' >>> simplesub(t, {}) Traceback (most recent call last): . . . @@ -68,7 +68,7 @@ . . . ValueError: Invalid placeholder on line 1: '@malformed' -''' +""" Index: curry292.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/string/curry292.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- curry292.py 7 Sep 2004 04:41:54 -0000 1.3 +++ curry292.py 7 Sep 2004 19:14:43 -0000 1.4 @@ -1,4 +1,4 @@ -r''' Doctests for PEP 292's string template functions +r"""Doctests for PEP 292's string template functions First, it is now a function and accepts either mappings or keyword arguments: @@ -33,10 +33,10 @@ The ValueErrors are now more specific. They include the line number and the mismatched token: ->>> t = """line one +>>> t = '''line one ... line two ... the $@malformed token -... line four""" +... line four''' >>> Template(t)({}) Traceback (most recent call last): . . . @@ -68,7 +68,7 @@ . . . ValueError: Invalid placeholder on line 1: '@malformed' -''' +""" @@ -134,9 +134,10 @@ def __call__(self, mapping=None, **kwds): """A function for $-substitutions. - This function is 'safe' in the sense that you will never get KeyErrors if - there are placeholders missing from the interpolation dictionary. In that - case, you will get the original placeholder in the value string. + This function is 'safe' in the sense that you will never get KeyErrors + if there are placeholders missing from the interpolation dictionary. + In that case, you will get the original placeholder in the value + string. """ if mapping is None: mapping = kwds Index: mod292.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/string/mod292.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- mod292.py 7 Sep 2004 05:22:16 -0000 1.1 +++ mod292.py 7 Sep 2004 19:14:43 -0000 1.2 @@ -1,4 +1,4 @@ -r''' Doctests for PEP 292's string template functions +r"""Doctests for PEP 292's string template functions Now, it makes sure the return type is a str if all the inputs are a str. Any unicode components will cause a unicode output. This matches the behavior of @@ -25,10 +25,10 @@ The ValueErrors are now more specific. They include the line number and the mismatched token: ->>> t = """line one +>>> t = '''line one ... line two ... the $@malformed token -... line four""" +... line four''' >>> Template(t) % dict() Traceback (most recent call last): . . . @@ -60,7 +60,7 @@ . . . ValueError: Invalid placeholder on line 1: '@malformed' -''' +""" @@ -124,9 +124,10 @@ def __mod__(self, mapping): """A function for $-substitutions. - This function is 'safe' in the sense that you will never get KeyErrors if - there are placeholders missing from the interpolation dictionary. In that - case, you will get the original placeholder in the value string. + This function is 'safe' in the sense that you will never get KeyErrors + if there are placeholders missing from the interpolation dictionary. + In that case, you will get the original placeholder in the value + string. """ template = self.tstring def convert(mo): From doerwalter at users.sourceforge.net Tue Sep 7 22:24:24 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:26 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_codecs.py, 1.12, 1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Lib/test Modified Files: test_codecs.py Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: test_codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codecs.py,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- test_codecs.py 10 Jul 2004 12:06:10 -0000 1.12 +++ test_codecs.py 7 Sep 2004 20:24:21 -0000 1.13 @@ -3,7 +3,45 @@ import codecs import StringIO -class UTF16Test(unittest.TestCase): +class Queue(object): + """ + queue: write bytes at one end, read bytes from the other end + """ + def __init__(self): + self._buffer = "" + + def write(self, chars): + self._buffer += chars + + def read(self, size=-1): + if size<0: + s = self._buffer + self._buffer = "" + return s + else: + s = self._buffer[:size] + self._buffer = self._buffer[size:] + return s + +class PartialReadTest(unittest.TestCase): + def check_partial(self, encoding, input, partialresults): + # get a StreamReader for the encoding and feed the bytestring version + # of input to the reader byte by byte. Read every available from + # the StreamReader and check that the results equal the appropriate + # entries from partialresults. + q = Queue() + r = codecs.getreader(encoding)(q) + result = u"" + for (c, partialresult) in zip(input.encode(encoding), partialresults): + q.write(c) + result += r.read() + self.assertEqual(result, partialresult) + # check that there's nothing left in the buffers + self.assertEqual(r.read(), u"") + self.assertEqual(r.bytebuffer, "") + self.assertEqual(r.charbuffer, u"") + +class UTF16Test(PartialReadTest): spamle = '\xff\xfes\x00p\x00a\x00m\x00s\x00p\x00a\x00m\x00' spambe = '\xfe\xff\x00s\x00p\x00a\x00m\x00s\x00p\x00a\x00m' @@ -23,6 +61,81 @@ f = reader(s) self.assertEquals(f.read(), u"spamspam") + def test_partial(self): + self.check_partial( + "utf-16", + u"\x00\xff\u0100\uffff", + [ + u"", # first byte of BOM read + u"", # second byte of BOM read => byteorder known + u"", + u"\x00", + u"\x00", + u"\x00\xff", + u"\x00\xff", + u"\x00\xff\u0100", + u"\x00\xff\u0100", + u"\x00\xff\u0100\uffff", + ] + ) + +class UTF16LETest(PartialReadTest): + + def test_partial(self): + self.check_partial( + "utf-16-le", + u"\x00\xff\u0100\uffff", + [ + u"", + u"\x00", + u"\x00", + u"\x00\xff", + u"\x00\xff", + u"\x00\xff\u0100", + u"\x00\xff\u0100", + u"\x00\xff\u0100\uffff", + ] + ) + +class UTF16BETest(PartialReadTest): + + def test_partial(self): + self.check_partial( + "utf-16-be", + u"\x00\xff\u0100\uffff", + [ + u"", + u"\x00", + u"\x00", + u"\x00\xff", + u"\x00\xff", + u"\x00\xff\u0100", + u"\x00\xff\u0100", + u"\x00\xff\u0100\uffff", + ] + ) + +class UTF8Test(PartialReadTest): + + def test_partial(self): + self.check_partial( + "utf-8", + u"\x00\xff\u07ff\u0800\uffff", + [ + u"\x00", + u"\x00", + u"\x00\xff", + u"\x00\xff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff\u0800", + u"\x00\xff\u07ff\u0800", + u"\x00\xff\u07ff\u0800", + u"\x00\xff\u07ff\u0800\uffff", + ] + ) + class EscapeDecodeTest(unittest.TestCase): def test_empty_escape_decode(self): self.assertEquals(codecs.escape_decode(""), ("", 0)) @@ -348,6 +461,9 @@ def test_main(): test_support.run_unittest( UTF16Test, + UTF16LETest, + UTF16BETest, + UTF8Test, EscapeDecodeTest, RecodingTest, PunycodeTest, From doerwalter at users.sourceforge.net Tue Sep 7 22:24:23 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:27 2004 Subject: [Python-checkins] python/dist/src/Lib codecs.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Lib Modified Files: codecs.py Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/codecs.py,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- codecs.py 26 Feb 2004 15:22:17 -0000 1.33 +++ codecs.py 7 Sep 2004 20:24:04 -0000 1.34 @@ -228,12 +228,22 @@ """ self.stream = stream self.errors = errors + self.bytebuffer = "" + self.charbuffer = u"" - def read(self, size=-1): + def decode(self, input, errors='strict'): + raise NotImplementedError + + def read(self, size=-1, chars=-1): """ Decodes data from the stream self.stream and returns the resulting object. + chars indicates the number of characters to read from the + stream. read() will never return more than chars + characters, but it might return less, if there are not enough + characters available. + size indicates the approximate maximum number of bytes to read from the stream for decoding purposes. The decoder can modify this setting as appropriate. The default value @@ -248,54 +258,70 @@ on the stream, these should be read too. """ - # Unsliced reading: - if size < 0: - return self.decode(self.stream.read(), self.errors)[0] - - # Sliced reading: - read = self.stream.read - decode = self.decode - data = read(size) - i = 0 - while 1: - try: - object, decodedbytes = decode(data, self.errors) - except ValueError, why: - # This method is slow but should work under pretty much - # all conditions; at most 10 tries are made - i = i + 1 - newdata = read(1) - if not newdata or i > 10: - raise - data = data + newdata + # read until we get the required number of characters (if available) + done = False + while True: + # can the request can be satisfied from the character buffer? + if chars < 0: + if self.charbuffer: + done = True else: - return object + if len(self.charbuffer) >= chars: + done = True + if done: + if chars < 0: + result = self.charbuffer + self.charbuffer = u"" + break + else: + result = self.charbuffer[:chars] + self.charbuffer = self.charbuffer[chars:] + break + # we need more data + if size < 0: + newdata = self.stream.read() + else: + newdata = self.stream.read(size) + data = self.bytebuffer + newdata + object, decodedbytes = self.decode(data, self.errors) + # keep undecoded bytes until the next call + self.bytebuffer = data[decodedbytes:] + # put new characters in the character buffer + self.charbuffer += object + # there was no data available + if not newdata: + done = True + return result - def readline(self, size=None): + def readline(self, size=None, keepends=True): """ Read one line from the input stream and return the decoded data. - Note: Unlike the .readlines() method, this method inherits - the line breaking knowledge from the underlying stream's - .readline() method -- there is currently no support for - line breaking using the codec decoder due to lack of line - buffering. Subclasses should however, if possible, try to - implement this method using their own knowledge of line - breaking. - - size, if given, is passed as size argument to the stream's - .readline() method. + size, if given, is passed as size argument to the + read() method. """ if size is None: - line = self.stream.readline() - else: - line = self.stream.readline(size) - return self.decode(line, self.errors)[0] - + size = 10 + line = u"" + while True: + data = self.read(size) + line += data + pos = line.find("\n") + if pos>=0: + self.charbuffer = line[pos+1:] + self.charbuffer + if keepends: + line = line[:pos+1] + else: + line = line[:pos] + return line + elif not data: + return line + if size<8000: + size *= 2 - def readlines(self, sizehint=None): + def readlines(self, sizehint=None, keepends=True): """ Read all lines available on the input stream and return them as list of lines. @@ -307,8 +333,8 @@ way to finding the true end-of-line. """ - data = self.stream.read() - return self.decode(data, self.errors)[0].splitlines(1) + data = self.read() + return self.splitlines(keepends) def reset(self): From doerwalter at users.sourceforge.net Tue Sep 7 22:24:24 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:28 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1128,1.1129 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Misc Modified Files: NEWS Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1128 retrieving revision 1.1129 diff -u -d -r1.1128 -r1.1129 --- NEWS 6 Sep 2004 23:30:27 -0000 1.1128 +++ NEWS 7 Sep 2004 20:24:21 -0000 1.1129 @@ -22,7 +22,14 @@ Library ------- -... +- SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support + decoding incomplete input (when the input stream is temporarily exhausted). + ``codecs.StreamReader`` now implements buffering, which enables proper + readline support for the UTF-16 decoders. ``codecs.StreamReader.read()`` + has a new argument ``chars`` which specifies the number of characters to + return. ``codecs.StreamReader.readline()`` and + ``codecs.StreamReader.readlines()`` have a new argument ``keepends``. + Trailing "\n"s will be stripped from the lines if ``keepends`` is false. Build ----- @@ -32,7 +39,9 @@ C API ----- -... +- SF patch #998993: ``PyUnicode_DecodeUTF8Stateful`` and + ``PyUnicode_DecodeUTF16Stateful`` have been added, which implement stateful + decoding. Documentation ------------- From doerwalter at users.sourceforge.net Tue Sep 7 22:24:24 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:30 2004 Subject: [Python-checkins] python/dist/src/Modules _codecsmodule.c, 2.19, 2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Modules Modified Files: _codecsmodule.c Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: _codecsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_codecsmodule.c,v retrieving revision 2.19 retrieving revision 2.20 diff -u -d -r2.19 -r2.20 --- _codecsmodule.c 10 Jul 2004 21:41:14 -0000 2.19 +++ _codecsmodule.c 7 Sep 2004 20:24:22 -0000 2.20 @@ -269,13 +269,20 @@ const char *data; int size; const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "t#|z:utf_8_decode", - &data, &size, &errors)) - return NULL; + int final = 0; + int consumed; + PyObject *decoded = NULL; - return codec_tuple(PyUnicode_DecodeUTF8(data, size, errors), - size); + if (!PyArg_ParseTuple(args, "t#|zi:utf_8_decode", + &data, &size, &errors, &final)) + return NULL; + consumed = size; + + decoded = PyUnicode_DecodeUTF8Stateful(data, size, errors, + final ? NULL : &consumed); + if (decoded == NULL) + return NULL; + return codec_tuple(decoded, consumed); } static PyObject * @@ -286,12 +293,19 @@ int size; const char *errors = NULL; int byteorder = 0; - - if (!PyArg_ParseTuple(args, "t#|z:utf_16_decode", - &data, &size, &errors)) + int final = 0; + int consumed; + PyObject *decoded; + + if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode", + &data, &size, &errors, &final)) return NULL; - return codec_tuple(PyUnicode_DecodeUTF16(data, size, errors, &byteorder), - size); + consumed = size; + decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, + final ? NULL : &consumed); + if (decoded == NULL) + return NULL; + return codec_tuple(decoded, consumed); } static PyObject * @@ -302,12 +316,20 @@ int size; const char *errors = NULL; int byteorder = -1; + int final = 0; + int consumed; + PyObject *decoded = NULL; - if (!PyArg_ParseTuple(args, "t#|z:utf_16_le_decode", - &data, &size, &errors)) + if (!PyArg_ParseTuple(args, "t#|zi:utf_16_le_decode", + &data, &size, &errors, &final)) return NULL; - return codec_tuple(PyUnicode_DecodeUTF16(data, size, errors, &byteorder), - size); + consumed = size; + decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, + &byteorder, final ? NULL : &consumed); + if (decoded == NULL) + return NULL; + return codec_tuple(decoded, consumed); + } static PyObject * @@ -318,12 +340,19 @@ int size; const char *errors = NULL; int byteorder = 1; + int final = 0; + int consumed; + PyObject *decoded = NULL; - if (!PyArg_ParseTuple(args, "t#|z:utf_16_be_decode", - &data, &size, &errors)) + if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode", + &data, &size, &errors, &final)) return NULL; - return codec_tuple(PyUnicode_DecodeUTF16(data, size, errors, &byteorder), - size); + consumed = size; + decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, + &byteorder, final ? NULL : &consumed); + if (decoded == NULL) + return NULL; + return codec_tuple(decoded, consumed); } /* This non-standard version also provides access to the byteorder @@ -343,15 +372,19 @@ const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; - - if (!PyArg_ParseTuple(args, "t#|zi:utf_16_ex_decode", - &data, &size, &errors, &byteorder)) + int final = 0; + int consumed; + + if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode", + &data, &size, &errors, &byteorder, &final)) return NULL; - unicode = PyUnicode_DecodeUTF16(data, size, errors, &byteorder); + consumed = size; + unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, + final ? NULL : &consumed); if (unicode == NULL) return NULL; - tuple = Py_BuildValue("Oii", unicode, size, byteorder); + tuple = Py_BuildValue("Oii", unicode, consumed, byteorder); Py_DECREF(unicode); return tuple; } From doerwalter at users.sourceforge.net Tue Sep 7 22:24:25 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:31 2004 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c, 2.223, 2.224 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Objects Modified Files: unicodeobject.c Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.223 retrieving revision 2.224 diff -u -d -r2.223 -r2.224 --- unicodeobject.c 27 Aug 2004 22:35:44 -0000 2.223 +++ unicodeobject.c 7 Sep 2004 20:24:22 -0000 2.224 @@ -1136,6 +1136,14 @@ int size, const char *errors) { + return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL); +} + +PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, + int size, + const char *errors, + int *consumed) +{ const char *starts = s; int n; int startinpos; @@ -1153,8 +1161,11 @@ unicode = _PyUnicode_New(size); if (!unicode) return NULL; - if (size == 0) + if (size == 0) { + if (consumed) + *consumed = 0; return (PyObject *)unicode; + } /* Unpack UTF-8 encoded data */ p = unicode->str; @@ -1172,10 +1183,14 @@ n = utf8_code_length[ch]; if (s + n > e) { - errmsg = "unexpected end of data"; - startinpos = s-starts; - endinpos = size; - goto utf8Error; + if (consumed) + break; + else { + errmsg = "unexpected end of data"; + startinpos = s-starts; + endinpos = size; + goto utf8Error; + } } switch (n) { @@ -1293,6 +1308,8 @@ (PyObject **)&unicode, &outpos, &p)) goto onError; } + if (consumed) + *consumed = s-starts; /* Adjust length */ if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0) @@ -1428,6 +1445,16 @@ const char *errors, int *byteorder) { + return PyUnicode_DecodeUTF16Stateful(s, size, errors, byteorder, NULL); +} + +PyObject * +PyUnicode_DecodeUTF16Stateful(const char *s, + int size, + const char *errors, + int *byteorder, + int *consumed) +{ const char *starts = s; int startinpos; int endinpos; @@ -1467,26 +1494,28 @@ mark is skipped, in all other modes, it is copied to the output stream as-is (giving a ZWNBSP character). */ if (bo == 0) { - const Py_UNICODE bom = (q[ihi] << 8) | q[ilo]; + if (size >= 2) { + const Py_UNICODE bom = (q[ihi] << 8) | q[ilo]; #ifdef BYTEORDER_IS_LITTLE_ENDIAN - if (bom == 0xFEFF) { - q += 2; - bo = -1; - } - else if (bom == 0xFFFE) { - q += 2; - bo = 1; - } + if (bom == 0xFEFF) { + q += 2; + bo = -1; + } + else if (bom == 0xFFFE) { + q += 2; + bo = 1; + } #else - if (bom == 0xFEFF) { - q += 2; - bo = 1; - } - else if (bom == 0xFFFE) { - q += 2; - bo = -1; - } + if (bom == 0xFEFF) { + q += 2; + bo = 1; + } + else if (bom == 0xFFFE) { + q += 2; + bo = -1; + } #endif + } } if (bo == -1) { @@ -1502,8 +1531,10 @@ while (q < e) { Py_UNICODE ch; - /* remaing bytes at the end? (size should be even) */ + /* remaining bytes at the end? (size should be even) */ if (e-q<2) { + if (consumed) + break; errmsg = "truncated data"; startinpos = ((const char *)q)-starts; endinpos = ((const char *)e)-starts; @@ -1565,6 +1596,9 @@ if (byteorder) *byteorder = bo; + if (consumed) + *consumed = (const char *)q-starts; + /* Adjust length */ if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0) goto onError; From doerwalter at users.sourceforge.net Tue Sep 7 22:24:23 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:31 2004 Subject: [Python-checkins] python/dist/src/Lib/encodings utf_16.py, 1.4, 1.5 utf_16_be.py, 1.3, 1.4 utf_16_le.py, 1.3, 1.4 utf_8.py, 1.2, 1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Lib/encodings Modified Files: utf_16.py utf_16_be.py utf_16_le.py utf_8.py Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: utf_16.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/utf_16.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- utf_16.py 8 Aug 2002 20:19:19 -0000 1.4 +++ utf_16.py 7 Sep 2004 20:24:21 -0000 1.5 @@ -10,54 +10,40 @@ ### Codec APIs -class Codec(codecs.Codec): +encode = codecs.utf_16_encode - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.utf_16_encode - decode = codecs.utf_16_decode +def decode(input, errors='strict'): + return codecs.utf_16_decode(input, errors, True) -class StreamWriter(Codec,codecs.StreamWriter): +class StreamWriter(codecs.StreamWriter): def __init__(self, stream, errors='strict'): - self.bom_written = 0 + self.bom_written = False codecs.StreamWriter.__init__(self, stream, errors) - def write(self, data): - result = codecs.StreamWriter.write(self, data) - if not self.bom_written: - self.bom_written = 1 - if sys.byteorder == 'little': - self.encode = codecs.utf_16_le_encode - else: - self.encode = codecs.utf_16_be_encode + def encode(self, input, errors='strict'): + self.bom_written = True + result = codecs.utf_16_encode(input, errors) + if sys.byteorder == 'little': + self.encode = codecs.utf_16_le_encode + else: + self.encode = codecs.utf_16_be_encode return result -class StreamReader(Codec,codecs.StreamReader): - def __init__(self, stream, errors='strict'): - self.bom_read = 0 - codecs.StreamReader.__init__(self, stream, errors) - - def read(self, size=-1): - if not self.bom_read: - signature = self.stream.read(2) - if signature == codecs.BOM_BE: - self.decode = codecs.utf_16_be_decode - elif signature == codecs.BOM_LE: - self.decode = codecs.utf_16_le_decode - else: - raise UnicodeError,"UTF-16 stream does not start with BOM" - if size > 2: - size -= 2 - elif size >= 0: - size = 0 - self.bom_read = 1 - return codecs.StreamReader.read(self, size) +class StreamReader(codecs.StreamReader): - def readline(self, size=None): - raise NotImplementedError, '.readline() is not implemented for UTF-16' + def decode(self, input, errors='strict'): + (object, consumed, byteorder) = \ + codecs.utf_16_ex_decode(input, errors, 0, False) + if byteorder == -1: + self.decode = codecs.utf_16_le_decode + elif byteorder == 1: + self.decode = codecs.utf_16_be_decode + elif consumed>=2: + raise UnicodeError,"UTF-16 stream does not start with BOM" + return (object, consumed) ### encodings module API def getregentry(): - return (Codec.encode,Codec.decode,StreamReader,StreamWriter) + return (encode,decode,StreamReader,StreamWriter) Index: utf_16_be.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/utf_16_be.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- utf_16_be.py 8 Aug 2002 20:19:19 -0000 1.3 +++ utf_16_be.py 7 Sep 2004 20:24:21 -0000 1.4 @@ -10,23 +10,19 @@ ### Codec APIs -class Codec(codecs.Codec): - - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.utf_16_be_encode - decode = codecs.utf_16_be_decode +encode = codecs.utf_16_be_encode -class StreamWriter(Codec,codecs.StreamWriter): - pass +def decode(input, errors='strict'): + return codecs.utf_16_be_decode(input, errors, True) -class StreamReader(Codec,codecs.StreamReader): +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_16_be_encode - def readline(self, size=None): - raise NotImplementedError, '.readline() is not implemented for UTF-16-BE' +class StreamReader(codecs.StreamReader): + decode = codecs.utf_16_be_decode ### encodings module API def getregentry(): - return (Codec.encode,Codec.decode,StreamReader,StreamWriter) + return (encode,decode,StreamReader,StreamWriter) Index: utf_16_le.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/utf_16_le.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- utf_16_le.py 8 Aug 2002 20:19:19 -0000 1.3 +++ utf_16_le.py 7 Sep 2004 20:24:21 -0000 1.4 @@ -10,23 +10,20 @@ ### Codec APIs -class Codec(codecs.Codec): +encode = codecs.utf_16_le_encode - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.utf_16_le_encode - decode = codecs.utf_16_le_decode +def decode(input, errors='strict'): + return codecs.utf_16_le_decode(input, errors, True) -class StreamWriter(Codec,codecs.StreamWriter): - pass +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_16_le_encode -class StreamReader(Codec,codecs.StreamReader): +class StreamReader(codecs.StreamReader): + decode = codecs.utf_16_le_decode - def readline(self, size=None): - raise NotImplementedError, '.readline() is not implemented for UTF-16-LE' ### encodings module API def getregentry(): - return (Codec.encode,Codec.decode,StreamReader,StreamWriter) + return (encode,decode,StreamReader,StreamWriter) Index: utf_8.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/utf_8.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- utf_8.py 8 Aug 2002 20:19:19 -0000 1.2 +++ utf_8.py 7 Sep 2004 20:24:21 -0000 1.3 @@ -10,21 +10,19 @@ ### Codec APIs -class Codec(codecs.Codec): +encode = codecs.utf_8_encode - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.utf_8_encode - decode = codecs.utf_8_decode +def decode(input, errors='strict'): + return codecs.utf_8_decode(input, errors, True) -class StreamWriter(Codec,codecs.StreamWriter): - pass +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_8_encode -class StreamReader(Codec,codecs.StreamReader): - pass +class StreamReader(codecs.StreamReader): + decode = codecs.utf_8_decode ### encodings module API def getregentry(): - return (Codec.encode,Codec.decode,StreamReader,StreamWriter) + return (encode,decode,StreamReader,StreamWriter) From doerwalter at users.sourceforge.net Tue Sep 7 22:24:36 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:39 2004 Subject: [Python-checkins] python/dist/src/Doc/api concrete.tex,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Doc/api Modified Files: concrete.tex Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.55 retrieving revision 1.56 diff -u -d -r1.55 -r1.56 --- concrete.tex 7 Aug 2004 20:19:24 -0000 1.55 +++ concrete.tex 7 Sep 2004 20:24:04 -0000 1.56 @@ -1076,6 +1076,17 @@ by the codec. \end{cfuncdesc} +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUTF8Stateful}{const char *s, + int size, + const char *errors, + int *consumed} + If \var{consumed} is \NULL{}, behaves like \cfunction{PyUnicode_DecodeUTF8()}. + If \var{consumed} is not \NULL{}, trailing incomplete UTF-8 byte sequences + will not be treated as an error. Those bytes will not be decoded and the + number of bytes that have been decoded will be stored in \var{consumed}. + \versionadded{2.4} +\end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeUTF8}{const Py_UNICODE *s, int size, const char *errors} @@ -1121,6 +1132,20 @@ Returns \NULL{} if an exception was raised by the codec. \end{cfuncdesc} +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUTF16Stateful}{const char *s, + int size, + const char *errors, + int *byteorder, + int *consumed} + If \var{consumed} is \NULL{}, behaves like + \cfunction{PyUnicode_DecodeUTF16()}. If \var{consumed} is not \NULL{}, + \cfunction{PyUnicode_DecodeUTF16Stateful()} will not treat trailing incomplete + UTF-16 byte sequences (i.e. an odd number of bytes or a split surrogate pair) + as an error. Those bytes will not be decoded and the number of bytes that + have been decoded will be stored in \var{consumed}. + \versionadded{2.4} +\end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeUTF16}{const Py_UNICODE *s, int size, const char *errors, From doerwalter at users.sourceforge.net Tue Sep 7 22:24:37 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:40 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libcodecs.tex,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Doc/lib Modified Files: libcodecs.tex Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: libcodecs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcodecs.tex,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- libcodecs.tex 18 Jul 2004 03:06:26 -0000 1.32 +++ libcodecs.tex 7 Sep 2004 20:24:04 -0000 1.33 @@ -394,9 +394,14 @@ be extended with \function{register_error()}. \end{classdesc} -\begin{methoddesc}{read}{\optional{size}} +\begin{methoddesc}{read}{\optional{size\optional{, chars}}} Decodes data from the stream and returns the resulting object. + \var{chars} indicates the number of characters to read from the + stream. \function{read()} will never return more than \vars{chars} + characters, but it might return less, if there are not enough + characters available. + \var{size} indicates the approximate maximum number of bytes to read from the stream for decoding purposes. The decoder can modify this setting as appropriate. The default value -1 indicates to read and @@ -407,29 +412,29 @@ read as much data as is allowed within the definition of the encoding and the given size, e.g. if optional encoding endings or state markers are available on the stream, these should be read too. + + \versionchanged[\var{chars} argument added]{2.4} \end{methoddesc} -\begin{methoddesc}{readline}{[size]} +\begin{methoddesc}{readline}{\optional{size\optional{, keepends}}} Read one line from the input stream and return the decoded data. - Unlike the \method{readlines()} method, this method inherits - the line breaking knowledge from the underlying stream's - \method{readline()} method -- there is currently no support for line - breaking using the codec decoder due to lack of line buffering. - Sublcasses should however, if possible, try to implement this method - using their own knowledge of line breaking. - \var{size}, if given, is passed as size argument to the stream's \method{readline()} method. + + If \var{keepends} is false lineends will be stripped from the + lines returned. + + \versionchanged[\var{keepends} argument added]{2.4} \end{methoddesc} -\begin{methoddesc}{readlines}{[sizehint]} +\begin{methoddesc}{readlines}{\optional{sizehint\optional{, keepends}}} Read all lines available on the input stream and return them as list of lines. Line breaks are implemented using the codec's decoder method and are - included in the list entries. + included in the list entries if \var{keepends} is true. \var{sizehint}, if given, is passed as \var{size} argument to the stream's \method{read()} method. From doerwalter at users.sourceforge.net Tue Sep 7 22:24:37 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 7 22:24:40 2004 Subject: [Python-checkins] python/dist/src/Include unicodeobject.h, 2.45, 2.46 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7801/Include Modified Files: unicodeobject.h Log Message: SF patch #998993: The UTF-8 and the UTF-16 stateful decoders now support decoding incomplete input (when the input stream is temporarily exhausted). codecs.StreamReader now implements buffering, which enables proper readline support for the UTF-16 decoders. codecs.StreamReader.read() has a new argument chars which specifies the number of characters to return. codecs.StreamReader.readline() and codecs.StreamReader.readlines() have a new argument keepends. Trailing "\n"s will be stripped from the lines if keepends is false. Added C APIs PyUnicode_DecodeUTF8Stateful and PyUnicode_DecodeUTF16Stateful. Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.45 retrieving revision 2.46 diff -u -d -r2.45 -r2.46 --- unicodeobject.h 4 Aug 2004 07:38:33 -0000 2.45 +++ unicodeobject.h 7 Sep 2004 20:24:04 -0000 2.46 @@ -160,7 +160,9 @@ # define PyUnicode_DecodeLatin1 PyUnicodeUCS2_DecodeLatin1 # define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS2_DecodeRawUnicodeEscape # define PyUnicode_DecodeUTF16 PyUnicodeUCS2_DecodeUTF16 +# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS2_DecodeUTF16Stateful # define PyUnicode_DecodeUTF8 PyUnicodeUCS2_DecodeUTF8 +# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS2_DecodeUTF8Stateful # define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS2_DecodeUnicodeEscape # define PyUnicode_Encode PyUnicodeUCS2_Encode # define PyUnicode_EncodeASCII PyUnicodeUCS2_EncodeASCII @@ -233,7 +235,9 @@ # define PyUnicode_DecodeLatin1 PyUnicodeUCS4_DecodeLatin1 # define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS4_DecodeRawUnicodeEscape # define PyUnicode_DecodeUTF16 PyUnicodeUCS4_DecodeUTF16 +# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS4_DecodeUTF16Stateful # define PyUnicode_DecodeUTF8 PyUnicodeUCS4_DecodeUTF8 +# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS4_DecodeUTF8Stateful # define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS4_DecodeUnicodeEscape # define PyUnicode_Encode PyUnicodeUCS4_Encode # define PyUnicode_EncodeASCII PyUnicodeUCS4_EncodeASCII @@ -658,6 +662,13 @@ const char *errors /* error handling */ ); +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8Stateful( + const char *string, /* UTF-8 encoded string */ + int length, /* size of string */ + const char *errors, /* error handling */ + int *consumed /* bytes consumed */ + ); + PyAPI_FUNC(PyObject*) PyUnicode_AsUTF8String( PyObject *unicode /* Unicode object */ ); @@ -702,6 +713,16 @@ exit */ ); +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16Stateful( + const char *string, /* UTF-16 encoded string */ + int length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder, /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + int *consumed /* bytes consumed */ + ); + /* Returns a Python string using the UTF-16 encoding in native byte order. The string always starts with a BOM mark. */ From goodger at users.sourceforge.net Wed Sep 8 02:11:27 2004 From: goodger at users.sourceforge.net (goodger@users.sourceforge.net) Date: Wed Sep 8 02:11:31 2004 Subject: [Python-checkins] python/nondist/peps pep-0334.txt, NONE, 1.1 pep-0000.txt, 1.288, 1.289 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19275 Modified Files: pep-0000.txt Added Files: pep-0334.txt Log Message: added PEP 334, "Simple Coroutines via SuspendIteration", by Clark C. Evans --- NEW FILE: pep-0334.txt --- PEP: 334 Title: Simple Coroutines via SuspendIteration Version: $Revision: 1.1 $ Last-Modified: $Date: 2004/09/08 00:11:18 $ Author: Clark C. Evans Status: Draft Type: Standards Track Python-Version: 3.0 Content-Type: text/x-rst Created: 26-Aug-2004 Post-History: Abstract ======== Asynchronous application frameworks such as Twisted [1]_ and Peak [2]_, are based on a cooperative multitasking via event queues or deferred execution. While this approach to application development does not involve threads and thus avoids a whole class of problems [3]_, it creates a different sort of programming challenge. When an I/O operation would block, a user request must suspend so that other requests can proceed. The concept of a coroutine [4]_ promises to help the application developer grapple with this state management difficulty. This PEP proposes a limited approach to coroutines based on an extension to the iterator protocol [5]_. Currently, an iterator may raise a StopIteration exception to indicate that it is done producing values. This proposal adds another exception to this protocol, SuspendIteration, which indicates that the given iterator may have more values to produce, but is unable to do so at this time. Rationale ========= There are two current approaches to bringing co-routines to Python. Christian Tismer's Stackless [6]_ involves a ground-up restructuring of Python's execution model by hacking the 'C' stack. While this approach works, its operation is hard to describe and keep portable. A related approach is to compile Python code to Parrot [7]_, a register-based virtual machine, which has coroutines. Unfortunately, neither of these solutions is portable with IronPython (CLR) or Jython (JavaVM). It is thought that a more limited approach, based on iterators, could provide a coroutine facility to application programmers and still be portable across runtimes. * Iterators keep their state in local variables that are not on the "C" stack. Iterators can be viewed as classes, with state stored in member variables that are persistent across calls to its next() method. * While an uncaught exception may terminate a function's execution, an uncaught exception need not invalidate an iterator. The proposed exception, SuspendIteration, uses this feature. In other words, just because one call to next() results in an exception does not necessarily need to imply that the iterator itself is no longer capable of producing values. There are four places where this new exception impacts: * The simple generator [8]_ mechanism could be extended to safely 'catch' this SuspendIteration exception, stuff away its current state, and pass the exception on to the caller. * Various iterator filters [9]_ in the standard library, such as itertools.izip should be made aware of this exception so that it can transparently propagate SuspendIteration. * Iterators generated from I/O operations, such as a file or socket reader, could be modified to have a non-blocking variety. This option would raise a subclass of SuspendIteration if the requested operation would block. * The asyncore library could be updated to provide a basic 'runner' that pulls from an iterator; if the SuspendIteration exception is caught, then it moves on to the next iterator in its runlist [10]_. External frameworks like Twisted would provide alternative implementations, perhaps based on FreeBSD's kqueue or Linux's epoll. While these may seem dramatic changes, it is a very small amount of work compared with the utility provided by continuations. Semantics ========= This section will explain, at a high level, how the introduction of this new SuspendIteration exception would behave. Simple Iterators ---------------- The current functionality of iterators is best seen with a simple example which produces two values 'one' and 'two'. :: class States: def __iter__(self): self._next = self.state_one return self def next(self): return self._next() def state_one(self): self._next = self.state_two return "one" def state_two(self): self._next = self.state_stop return "two" def state_stop(self): raise StopIteration print list(States()) An equivalent iteration could, of course, be created by the following generator:: def States(): yield 'one' yield 'two' print list(States()) Introducing SuspendIteration ---------------------------- Suppose that between producing 'one' and 'two', the generator above could block on a socket read. In this case, we would want to raise SuspendIteration to signal that the iterator is not done producing, but is unable to provide a value at the current moment. :: from random import randint from time import sleep class SuspendIteration(Exception): pass class NonBlockingResource: """Randomly unable to produce the second value""" def __iter__(self): self._next = self.state_one return self def next(self): return self._next() def state_one(self): self._next = self.state_suspend return "one" def state_suspend(self): rand = randint(1,10) if 2 == rand: self._next = self.state_two return self.state_two() raise SuspendIteration() def state_two(self): self._next = self.state_stop return "two" def state_stop(self): raise StopIteration def sleeplist(iterator, timeout = .1): """ Do other things (e.g. sleep) while resource is unable to provide the next value """ it = iter(iterator) retval = [] while True: try: retval.append(it.next()) except SuspendIteration: sleep(timeout) continue except StopIteration: break return retval print sleeplist(NonBlockingResource()) In a real-world situation, the NonBlockingResource would be a file iterator, socket handle, or other I/O based producer. The sleeplist would instead be an async reactor, such as those found in asyncore or Twisted. The non-blocking resource could, of course, be written as a generator:: def NonBlockingResource(): yield "one" while True: rand = randint(1,10) if 2 == rand: break raise SuspendIteration() yield "two" It is not necessary to add a keyword, 'suspend', since most real content generators will not be in application code, they will be in low-level I/O based operations. Since most programmers need not be exposed to the SuspendIteration() mechanism, a keyword is not needed. Application Iterators --------------------- The previous example is rather contrived, a more 'real-world' example would be a web page generator which yields HTML content, and pulls from a database. Note that this is an example of neither the 'producer' nor the 'consumer', but rather of a filter. :: def ListAlbums(cursor): cursor.execute("SELECT title, artist FROM album") yield '' for (title, artist) in cursor: yield '' % (title, artist) yield '
TitleArtist
%s%s
' The problem, of course, is that the database may block for some time before any rows are returned, and that during execution, rows may be returned in blocks of 10 or 100 at a time. Ideally, if the database blocks for the next set of rows, another user connection could be serviced. Note the complete absence of SuspendIterator in the above code. If done correctly, application developers would be able to focus on functionality rather than concurrency issues. The iterator created by the above generator should do the magic necessary to maintain state, yet pass the exception through to a lower-level async framework. Here is an example of what the corresponding iterator would look like if coded up as a class:: class ListAlbums: def __init__(self, cursor): self.cursor = cursor def __iter__(self): self.cursor.execute("SELECT title, artist FROM album") self._iter = iter(self._cursor) self._next = self.state_head return self def next(self): return self._next() def state_head(self): self._next = self.state_cursor return "" def state_tail(self): self._next = self.state_stop return "
\ TitleArtist
" def state_cursor(self): try: (title,artist) = self._iter.next() return '%s%s' % (title, artist) except StopIteration: self._next = self.state_tail return self.next() except SuspendIteration: # just pass-through raise def state_stop(self): raise StopIteration Complicating Factors -------------------- While the above example is straight-forward, things are a bit more complicated if the intermediate generator 'condenses' values, that is, it pulls in two or more values for each value it produces. For example, :: def pair(iterLeft,iterRight): rhs = iter(iterRight) lhs = iter(iterLeft) while True: yield (rhs.next(), lhs.next()) In this case, the corresponding iterator behavior has to be a bit more subtle to handle the case of either the right or left iterator raising SuspendIteration. It seems to be a matter of decomposing the generator to recognize intermediate states where a SuspendIterator exception from the producing context could happen. :: class pair: def __init__(self, iterLeft, iterRight): self.iterLeft = iterLeft self.iterRight = iterRight def __iter__(self): self.rhs = iter(iterRight) self.lhs = iter(iterLeft) self._temp_rhs = None self._temp_lhs = None self._next = self.state_rhs return self def next(self): return self._next() def state_rhs(self): self._temp_rhs = self.rhs.next() self._next = self.state_lhs return self.next() def state_lhs(self): self._temp_lhs = self.lhs.next() self._next = self.state_pair return self.next() def state_pair(self): self._next = self.state_rhs return (self._temp_rhs, self._temp_lhs) This proposal assumes that a corresponding iterator written using this class-based method is possible for existing generators. The challenge seems to be the identification of distinct states within the generator where suspension could occur. Resource Cleanup ---------------- The current generator mechanism has a strange interaction with exceptions where a 'yield' statement is not allowed within a try/finally block. The SuspendIterator exception provides another similar issue. The impacts of this issue are not clear. However it may be that re-writing the generator into a state machine, as the previous section did, could resolve this issue allowing for the situation to be no-worse than, and perhaps even removing the yield/finally situation. More investigation is needed in this area. API and Limitations ------------------- This proposal only covers 'suspending' a chain of iterators, and does not cover (of course) suspending general functions, methods, or "C" extension function. While there could be no direct support for creating generators in "C" code, native "C" iterators which comply with the SuspendIterator semantics are certainly possible. Low-Level Implementation ======================== The author of the PEP is not yet familiar with the Python execution model to comment in this area. References ========== .. [1] Twisted (http://twistedmatrix.com) .. [2] Peak (http://peak.telecommunity.com) .. [3] C10K (http://www.kegel.com/c10k.html) .. [4] Coroutines (http://c2.com/cgi/wiki?CallWithCurrentContinuation) .. [5] PEP 234, Iterators (http://www.python.org/peps/pep-0234.html) .. [6] Stackless Python (http://stackless.com) .. [7] Parrot /w coroutines (http://www.sidhe.org/~dan/blog/archives/000178.html) .. [8] PEP 255, Simple Generators (http://www.python.org/peps/pep-0255.html) .. [9] itertools - Functions creating iterators (http://docs.python.org/lib/module-itertools.html) .. [10] Microthreads in Python, David Mertz (http://www-106.ibm.com/developerworks/linux/library/l-pythrd.html) Copyright ========= This document has been placed in the public domain. .. Local Variables: mode: indented-text indent-tabs-mode: nil sentence-end-double-space: t fill-column: 70 End: Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.288 retrieving revision 1.289 diff -u -d -r1.288 -r1.289 --- pep-0000.txt 1 Sep 2004 16:18:20 -0000 1.288 +++ pep-0000.txt 8 Sep 2004 00:11:18 -0000 1.289 @@ -121,6 +121,7 @@ S 330 Python Bytecode Verification Pelletier S 331 Locale-Independent Float/String conversions Reis S 332 Byte vectors and String/Unicode Unification Montanaro + S 334 Simple Coroutines via SuspendIteration Evans S 754 IEEE 754 Floating Point Special Values Warnes Finished PEPs (done, implemented in CVS) @@ -362,6 +363,7 @@ S 331 Locale-Independent Float/String conversions Reis S 332 Byte vectors and String/Unicode Unification Montanaro I 333 Python Web Server Gateway Interface v1.0 Eby + S 334 Simple Coroutines via SuspendIteration Evans SR 666 Reject Foolish Indentation Creighton S 754 IEEE 754 Floating Point Special Values Warnes I 3000 Python 3.0 Plans Kuchling, Cannon From bcannon at users.sourceforge.net Wed Sep 8 04:02:50 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Wed Sep 8 04:02:54 2004 Subject: [Python-checkins] python/dist/src/Lib/test test__locale.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5361/Lib/test Modified Files: test__locale.py Log Message: Remove usage of locale.getlocale in favor or setlocale(LC_NUMERIC, None) . Also added a comment about why the code is bother to see what setlocale thinks the set locale is. Closes bug #1023798. Index: test__locale.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test__locale.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- test__locale.py 6 Sep 2004 23:30:26 -0000 1.7 +++ test__locale.py 8 Sep 2004 02:02:41 -0000 1.8 @@ -1,7 +1,6 @@ from test.test_support import verbose, TestSkipped, run_unittest from _locale import (setlocale, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo, localeconv, Error) -from locale import getlocale import unittest candidate_locales = ['es_UY', 'fr_FR', 'fi_FI', 'es_CO', 'pt_PT', 'it_IT', @@ -33,11 +32,18 @@ (THOUSEP, "thousands_sep")): nl_radixchar = nl_langinfo(li) li_radixchar = localeconv()[lc] + # Both with seeing what the locale is set to in order to detect + # when setlocale lies and says it accepted the locale setting + # but in actuality didn't use it (as seen in OS X 10.3) + try: + set_locale = setlocale(LC_NUMERIC) + except Error: + set_locale = "" self.assertEquals(nl_radixchar, li_radixchar, - "%r != %r (%s); " + "%s != %s (%s); " "supposed to be %s, set to %s" % (nl_radixchar, li_radixchar, lc, - loc, getlocale(LC_NUMERIC)[0])) + loc, set_locale)) def test_main(): run_unittest(_LocaleTests) From loewis at users.sourceforge.net Wed Sep 8 17:56:41 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed Sep 8 17:56:48 2004 Subject: [Python-checkins] python/dist/src/PC WinMain.c,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22557 Modified Files: WinMain.c Log Message: Revert creation of launcher.exe Index: WinMain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/WinMain.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- WinMain.c 7 Sep 2004 15:40:12 -0000 1.9 +++ WinMain.c 8 Sep 2004 15:56:39 -0000 1.10 @@ -2,25 +2,9 @@ #define WIN32_LEAN_AND_MEAN #include -#include #include "Python.h" -#ifdef LAUNCHER -/* Q105305 suggests this routine to adjust the handles. */ -static void adjust_file(DWORD handle, FILE* f, char* mode) -{ - int hCrt; - FILE *hf; - hCrt = _open_osfhandle((intptr_t)GetStdHandle(handle), _O_TEXT); - hf = _fdopen(hCrt, mode); - *f = *hf; - setvbuf(f, NULL, _IONBF, 0); - /* Alternatively, we could use __set_app_type and _set_osfhnd, - but that appears to be undocumented. */ -} -#endif - int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ HINSTANCE hPrevInstance, /* handle to previous instance */ @@ -28,19 +12,5 @@ int nCmdShow /* show state of window */ ) { -#ifdef LAUNCHER - int i; - if (__argc > 1 && strcmp(__argv[1], "-console") == 0) { - /* Allocate a console, and remove the -console argument. */ - AllocConsole(); - for (i = 2; i < __argc; i++) - __argv[i-1] = __argv[i]; - __argc--; - /* Make stdin, stdout, stderr use the newly allocated OS handles. */ - adjust_file(STD_INPUT_HANDLE, stdin, "r"); - adjust_file(STD_OUTPUT_HANDLE, stdout, "w"); - adjust_file(STD_ERROR_HANDLE, stderr, "w"); - } -#endif return Py_Main(__argc, __argv); } From loewis at users.sourceforge.net Wed Sep 8 17:57:38 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed Sep 8 17:57:41 2004 Subject: [Python-checkins] python/dist/src/PCbuild pcbuild.sln, 1.4, 1.5 launcher.vcproj, 1.1, NONE Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22711 Modified Files: pcbuild.sln Removed Files: launcher.vcproj Log Message: Revert creation of launcher.exe Index: pcbuild.sln =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pcbuild.sln,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- pcbuild.sln 7 Sep 2004 15:36:46 -0000 1.4 +++ pcbuild.sln 8 Sep 2004 15:57:36 -0000 1.5 @@ -79,10 +79,6 @@ {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launcher", "launcher.vcproj", "{065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -185,12 +181,6 @@ {680CDC79-9CCA-4282-9A8D-927CB0DB55B2}.Release.Build.0 = Release|Win32 {680CDC79-9CCA-4282-9A8D-927CB0DB55B2}.ReleaseItanium.ActiveCfg = Release|Win32 {680CDC79-9CCA-4282-9A8D-927CB0DB55B2}.ReleaseItanium.Build.0 = Release|Win32 - {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.Debug.ActiveCfg = Debug|Win32 - {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.Debug.Build.0 = Debug|Win32 - {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.Release.ActiveCfg = Release|Win32 - {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.Release.Build.0 = Release|Win32 - {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.ReleaseItanium.ActiveCfg = ReleaseItanium|Win32 - {065D53DF-5D8E-4CBD-AE32-B9E29D4FC5C6}.ReleaseItanium.Build.0 = ReleaseItanium|Win32 EndGlobalSection GlobalSection(SolutionItems) = postSolution readme.txt = readme.txt --- launcher.vcproj DELETED --- From loewis at users.sourceforge.net Wed Sep 8 18:09:17 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed Sep 8 18:09:20 2004 Subject: [Python-checkins] python/dist/src/Tools/msi msi.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/msi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25037 Modified Files: msi.py Log Message: Revert creation of launcher.exe. Install python[w].exe on demand also as extpy[w].exe Index: msi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/msi/msi.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- msi.py 7 Sep 2004 15:39:29 -0000 1.7 +++ msi.py 8 Sep 2004 16:09:14 -0000 1.8 @@ -812,8 +812,10 @@ root.add_file("PCBuild/python.exe") root.start_component("pythonw.exe", keyfile="pythonw.exe") root.add_file("PCBuild/pythonw.exe") - root.start_component("launcher.exe", feature=ext_feature, keyfile="launcher.exe") - root.add_file("PCBuild/launcher.exe") + root.start_component("extpy.exe", feature=ext_feature, keyfile="extpy.exe") + root.add_file("extpy.exe", src="PCBuild/python.exe") + root.start_component("extpyw.exe", feature=ext_feature, keyfile="extpyw.exe") + root.add_file("extpyw.exe", src="PCBuild/pythonw.exe") # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table" dlldir = PyDirectory(db, cab, root, srcdir, "DLLDIR", ".") @@ -1017,16 +1019,16 @@ pat3 = r"Software\Classes\%sPython.%sFile" # Advertised extensions add_data(db, "Extension", - [("py", "launcher.exe", "Python.File", None, ext_feature.id), - ("pyw", "launcher.exe", "Python.NoConFile", None, ext_feature.id), - ("pyc", "launcher.exe", "Python.CompiledFile", None, ext_feature.id), - ("pyo", "launcher.exe", "Python.CompiledFile", None, ext_feature.id)]) + [("py", "extpy.exe", "Python.File", None, ext_feature.id), + ("pyw", "extpyw.exe", "Python.NoConFile", None, ext_feature.id), + ("pyc", "extpy.exe", "Python.CompiledFile", None, ext_feature.id), + ("pyo", "extpy.exe", "Python.CompiledFile", None, ext_feature.id)]) # add_data(db, "MIME") XXX add_data(db, "Verb", - [("py", "open", 1, None, r'-console "%1"'), + [("py", "open", 1, None, r'"%1"'), ("pyw", "open", 1, None, r'"%1"'), - ("pyc", "open", 1, None, r'-console "%1"'), - ("pyo", "open", 1, None, r'-console "%1"')]) + ("pyc", "open", 1, None, r'"%1"'), + ("pyo", "open", 1, None, r'"%1"')]) add_data(db, "ProgId", [("Python.File", None, None, "Python File", "python_icon.exe", 0), ("Python.NoConFile", None, None, "Python File (no console)", "python_icon.exe", 0), From fdrake at users.sourceforge.net Thu Sep 9 00:57:05 2004 From: fdrake at users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu Sep 9 00:57:08 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_htmlparser.py, 1.13, 1.14 test_sgmllib.py, 1.6, 1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4822/Lib/test Modified Files: test_htmlparser.py test_sgmllib.py Log Message: add tests that make sure buffer boundaries are handled properly for SGML comments (see SF patch #901369) Index: test_htmlparser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_htmlparser.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- test_htmlparser.py 8 Jul 2004 04:22:19 -0000 1.13 +++ test_htmlparser.py 8 Sep 2004 22:57:01 -0000 1.14 @@ -243,6 +243,19 @@ self._run_check(["
"], output) self._run_check([""], output) + output = [("comment", "abc")] + self._run_check(["", ""], output) + self._run_check(["<", "!--abc-->"], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check(["", ""], output) + def test_starttag_junk_chars(self): self._parse_error("") self._parse_error("") Index: test_sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sgmllib.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- test_sgmllib.py 29 Apr 2003 22:12:55 -0000 1.6 +++ test_sgmllib.py 8 Sep 2004 22:57:01 -0000 1.7 @@ -307,6 +307,19 @@ self.check_events([""], output) self.check_events([""], output) + output = [("comment", "abc")] + self._run_check(["", ""], output) + self._run_check(["<", "!--abc-->"], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check([""], output) + self._run_check(["", ""], output) + def _test_starttag_junk_chars(self): self.check_parse_error("<") self.check_parse_error("<>") From fdrake at users.sourceforge.net Thu Sep 9 00:58:38 2004 From: fdrake at users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu Sep 9 00:58:41 2004 Subject: [Python-checkins] python/dist/src/Lib HTMLParser.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5108 Modified Files: HTMLParser.py Log Message: remove unnecessary override of base class method Index: HTMLParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/HTMLParser.py,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- HTMLParser.py 5 Jun 2004 15:31:45 -0000 1.14 +++ HTMLParser.py 8 Sep 2004 22:58:36 -0000 1.15 @@ -208,19 +208,6 @@ i = self.updatepos(i, n) self.rawdata = rawdata[i:] - # Internal -- parse comment, return end or -1 if not terminated - def parse_comment(self, i, report=1): - rawdata = self.rawdata - assert rawdata[i:i+4] == ' %s' % (filename, newname) + +img_1074.jpg --> Ashley_0.jpg +img_1076.jpg --> Ashley_1.jpg +img_1077.jpg --> Ashley_2.jpg +\end{verbatim} + +For internationalization applications, it may be appropriate to coerce all +templates to \class{unicode}. This can be done with subclassing and +overriding the \method{__init__} method: + +\begin{verbatim} +>>> class UnicodeTemplate(unicode, Template): +... def __init__(self, template): +... self.template = unicode(template) +>>> t = UnicodeTemplate('Knights who say $what') +>>> t.substitute(what='Ni') +u'Knights who say Ni' +>>> t.capitalize() +u'Knights who say $what' +\end{verbatim} + + \section{Working with Binary Data Record Layouts\label{binary-formats}} The \ulink{\module{struct}}{../lib/module-struct.html} module provides From pje at users.sourceforge.net Tue Sep 14 08:02:31 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Tue Sep 14 08:02:34 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16633 Modified Files: pep-0333.txt Log Message: Fix expect/continue language per: http://mail.python.org/pipermail/web-sig/2004-August/000633.html and add general notes re: advanced HTTP features per: http://mail.python.org/pipermail/web-sig/2004-August/000641.html Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- pep-0333.txt 14 Sep 2004 05:06:44 -0000 1.9 +++ pep-0333.txt 14 Sep 2004 06:02:28 -0000 1.10 @@ -1141,22 +1141,22 @@ HTTP 1.1 Expect/Continue ------------------------ -Servers and gateways **must** provide transparent support for HTTP -1.1's "expect/continue" mechanism, if they implement HTTP 1.1. This +Servers and gateways that implement HTTP 1.1 **must** provide +transparent support for HTTP 1.1's "expect/continue" mechanism. This may be done in any of several ways: -1. Reject all client requests containing an ``Expect: 100-continue`` - header with a "417 Expectation failed" error. Such requests should - not be forwarded to an application object. - -2. Respond to requests containing an ``Expect: 100-continue`` request +1. Respond to requests containing an ``Expect: 100-continue`` request with an immediate "100 Continue" response, and proceed normally. -3. Proceed with the request normally, but provide the application +2. Proceed with the request normally, but provide the application with a ``wsgi.input`` stream that will send the "100 Continue" response if/when the application first attempts to read from the input stream. The read request must then remain blocked until the client responds. + +3. Wait until the client decides that the server does not support + expect/continue, and sends the request body on its own. (This + is suboptimal, and is not recommended.) Note that these behavior restrictions do not apply for HTTP 1.0 requests, or for requests that are not directed to an application @@ -1164,6 +1164,41 @@ 2616, sections 8.2.3 and 10.1.1. +Other HTTP Features +------------------- + +In general, servers and gateways should "play dumb" and allow the +application complete control over its output. They should only make +changes that do not alter the effective semantics of the application's +response. It is always possible for the application developer to add +middleware components to supply additional features, so server/gateway +developers should be conservative in their implementation. In a sense, +a server should consider itself to be like an HTTP "proxy server", with +the application being an HTTP "origin server". + +Applying this principle to a variety of HTTP features, it should be +clear that a server **may** handle cache validation via the +``If-None-Match`` and ``If-Modified-Since`` request headers and the +``Last-Modified`` and ``ETag`` response headers. However, it is +not required to do this, and the application **should** perform its +own cache validation if it wants to support that feature, since +the server/gateway is not required to do such validation. + +Similarly, a server **may** re-encode or transport-encode an +application's response, but the application **should** use a +suitable encoding on its own. A server **may** use chunked +encoding or transmit byte ranges of the application's response +if requested by the client, and the application doesn't natively +support byte ranges. Again, however, the application **should** +perform this function on its own if desired. + +Note that these restrictions on applications do not necessarily mean +that every application must reimplement every HTTP feature; many HTTP +features can be partially or fully implemented by middleware +components, thus freeing both server and application authors from +implementing the same features over and over again. + + Questions and Answers ===================== From rhettinger at users.sourceforge.net Tue Sep 14 08:32:23 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 14 08:32:26 2004 Subject: [Python-checkins] python/dist/src/Doc/tut tut.tex,1.249,1.250 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20327 Modified Files: tut.tex Log Message: Tweak the wording. Improve examples. Make more brief. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.249 retrieving revision 1.250 diff -u -d -r1.249 -r1.250 --- tut.tex 14 Sep 2004 05:21:42 -0000 1.249 +++ tut.tex 14 Sep 2004 06:32:20 -0000 1.250 @@ -4841,26 +4841,26 @@ The \ulink{\module{string}}{../lib/module-string.html} module includes a versatile \class{Template} class with a simplified syntax suitable for editing by end-users. This allows users to customize their applications -without having to alter the Python program. +without having to alter the application. -The format uses \samp{\$} for placeholder names that are valid Python +The format uses placeholder names formed by \samp{\$} with valid Python identifiers (alphanumeric characters and underscores). Surrounding the placeholder with braces allows it to be followed by more alphanumeric letters -with no intervening spaces. \samp{\$\$} is the way to create a single escaped +with no intervening spaces. Writing \samp{\$\$} creates a single escaped \samp{\$}: \begin{verbatim} >>> from string import Template >>> t = Template('${village}folk send $$10 to $cause.') ->>> t.substitute(village='nottingham', cause='the ditch fund') -'nottinghamfolk send $10 to the ditch fund.' +>>> t.substitute(village='Nottingham', cause='the ditch fund') +'Nottinghamfolk send $10 to the ditch fund.' \end{verbatim} The \method{substitute} method raises a \exception{KeyError} when a -placeholder is not supplied in a dictionary or a keyword argument. -For mail-merge style applications, user supplied data may be incomplete -and the \method{safe_substitute} method may be more appropriate --- it -will leave placeholders unchanged if data is missing: +placeholder is not supplied in a dictionary or a keyword argument. For +mail-merge style applications, user supplied data may be incomplete and the +\method{safe_substitute} method may be more appropriate --- it will leave +placeholders unchanged if data is missing: \begin{verbatim} >>> t = Template('Return the $item to $owner.') @@ -4875,7 +4875,7 @@ Template subclasses can specify a custom delimiter. For example, a batch renaming utility for a photo browser may elect to use percent signs for -metadata such as the current date, image sequence number, or file format: +placeholders such as the current date, image sequence number, or file format: \begin{verbatim} >>> import time, os.path @@ -4885,11 +4885,11 @@ >>> fmt = raw_input('Enter rename style (%d-date %n-seqnum %f-format): ') Enter rename style (%d-date %n-seqnum %f-format): Ashley_%n%f ->>> rename = BatchRename(fmt) +>>> t = BatchRename(fmt) >>> date = time.strftime('%d%b%y') >>> for i, filename in enumerate(photofiles): ... base, ext = os.path.splitext(filename) -... newname = rename.substitute(d=date, n=i, f=ext) +... newname = t.substitute(d=date, n=i, f=ext) ... print '%s --> %s' % (filename, newname) img_1074.jpg --> Ashley_0.jpg @@ -4897,20 +4897,9 @@ img_1077.jpg --> Ashley_2.jpg \end{verbatim} -For internationalization applications, it may be appropriate to coerce all -templates to \class{unicode}. This can be done with subclassing and -overriding the \method{__init__} method: - -\begin{verbatim} ->>> class UnicodeTemplate(unicode, Template): -... def __init__(self, template): -... self.template = unicode(template) ->>> t = UnicodeTemplate('Knights who say $what') ->>> t.substitute(what='Ni') -u'Knights who say Ni' ->>> t.capitalize() -u'Knights who say $what' -\end{verbatim} +Another application for templating is separating program logic from the +details of multiple output formats. The makes it possible to substitute +custom templates for XML files, plain text reports, and HMTL web reports. \section{Working with Binary Data Record Layouts\label{binary-formats}} From rhettinger at users.sourceforge.net Tue Sep 14 09:34:40 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 14 09:34:46 2004 Subject: [Python-checkins] python/nondist/peps pep-0318.txt,1.34,1.35 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29524 Modified Files: pep-0318.txt Log Message: Include Guido's rationale for the order of application and for the decorator declaration syntax allowing functions with arguments. Index: pep-0318.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0318.txt,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- pep-0318.txt 3 Sep 2004 09:32:50 -0000 1.34 +++ pep-0318.txt 14 Sep 2004 07:34:23 -0000 1.35 @@ -250,6 +250,14 @@ decorators are near the function declaration. The @ sign makes it clear that something new is going on here. +The rationale for the `order of application`_ (bottom to top) is that it +matches the usual order for function-application. In mathematics, +composition of functions (g o f)(x) translates to g(f(x)). In Python, +``@g @f def foo()`` translates to ``foo=g(f(foo)``. + +.. _order of application: + http://mail.python.org/pipermail/python-dev/2004-September/048874.html + The decorator statement is limited in what it can accept -- arbitrary expressions will not work. Guido preferred this because of a `gut feeling`_. @@ -257,6 +265,25 @@ .. _gut feeling: http://mail.python.org/pipermail/python-dev/2004-August/046711.html +The current syntax also allows decorator declarations to call a +function that returns a decorator:: + + @decomaker(argA, argB, ...) + def func(arg1, arg2, ...): + pass + +This is equivalent to:: + + func = decomaker(argA, argB, ...)(func) + +The rationale for having a function that returns a decorator is that +the part after the @ sign can be considered to be an expression +(though syntactically restricted to just a function), and whatever +that expression returns is called. See `declaration arguments`_. + +.. _declaration arguments: + http://mail.python.org/pipermail/python-dev/2004-September/048874.html + Syntax Alternatives =================== From loewis at users.sourceforge.net Tue Sep 14 09:52:24 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue Sep 14 09:52:28 2004 Subject: [Python-checkins] python/dist/src/Doc/ref ref2.tex,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32047 Modified Files: ref2.tex Log Message: Remove claims that Python source code is ASCII. Fixes #1026038. Index: ref2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref2.tex,v retrieving revision 1.54 retrieving revision 1.55 diff -u -d -r1.54 -r1.55 --- ref2.tex 18 Aug 2004 13:25:05 -0000 1.54 +++ ref2.tex 14 Sep 2004 07:52:22 -0000 1.55 @@ -73,6 +73,8 @@ \subsection{Encoding declarations\label{encodings}} +\index{source character set} +\index{encodings} If a comment in the first or second line of the Python script matches the regular expression \regexp{coding[=:]\e s*([-\e w.]+)}, this comment is @@ -385,16 +387,18 @@ \production{longstringitem} {\token{longstringchar} | \token{escapeseq}} \production{shortstringchar} - {} + {} \production{longstringchar} - {} + {} \production{escapeseq} {"\e" } \end{productionlist} One syntactic restriction not indicated by these productions is that whitespace is not allowed between the \grammartoken{stringprefix} and -the rest of the string literal. +the rest of the string literal. The source character set is defined +by the encoding declaration; it is \ASCII if no encoding declaration +is given in the source file; see \ref{encodings}. \index{triple-quoted string} \index{Unicode Consortium} @@ -447,8 +451,8 @@ \lineiii{\e U\var{xxxxxxxx}} {Character with 32-bit hex value \var{xxxxxxxx} (Unicode only)}{(2)} \lineiii{\e v} {\ASCII{} Vertical Tab (VT)}{} -\lineiii{\e\var{ooo}} {\ASCII{} character with octal value \var{ooo}}{(3)} -\lineiii{\e x\var{hh}} {\ASCII{} character with hex value \var{hh}}{(4)} +\lineiii{\e\var{ooo}} {Character with octal value \var{ooo}}{(3,5)} +\lineiii{\e x\var{hh}} {Character with hex value \var{hh}}{(4,5)} \end{tableiii} \index{ASCII@\ASCII} @@ -469,6 +473,12 @@ As in Standard C, up to three octal digits are accepted. \item[(4)] Unlike in Standard C, at most two hex digits are accepted. +\item[(5)] + In a string literal, hexadecimal and octal escapes denote the + byte with the given value; it is not necessary that the byte + encodes a character in the source character set. In a Unicode + literal, these escapes denote a Unicode character with the given + value. \end{itemize} From doerwalter at users.sourceforge.net Tue Sep 14 11:40:48 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 14 11:40:50 2004 Subject: [Python-checkins] python/dist/src/Lib string.py,1.80,1.81 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16636/Lib Modified Files: string.py Log Message: Enhance the docstrings for unicode.split() and string.split() to make it clear that it is possible to pass None as the separator argument to get the default "any whitespace" separator. Index: string.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/string.py,v retrieving revision 1.80 retrieving revision 1.81 diff -u -d -r1.80 -r1.81 --- string.py 14 Sep 2004 02:34:08 -0000 1.80 +++ string.py 14 Sep 2004 09:40:45 -0000 1.81 @@ -282,7 +282,7 @@ Return a list of the words in the string s, using sep as the delimiter string. If maxsplit is given, splits at no more than maxsplit places (resulting in at most maxsplit+1 words). If sep - is not specified, any whitespace string is a separator. + is not specified or None, any whitespace string is a separator. (split and splitfields are synonymous) From doerwalter at users.sourceforge.net Tue Sep 14 11:40:47 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 14 11:40:51 2004 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c, 2.224, 2.225 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16636/Objects Modified Files: unicodeobject.c Log Message: Enhance the docstrings for unicode.split() and string.split() to make it clear that it is possible to pass None as the separator argument to get the default "any whitespace" separator. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.224 retrieving revision 2.225 diff -u -d -r2.224 -r2.225 --- unicodeobject.c 7 Sep 2004 20:24:22 -0000 2.224 +++ unicodeobject.c 14 Sep 2004 09:40:44 -0000 2.225 @@ -5987,8 +5987,8 @@ \n\ Return a list of the words in S, using sep as the\n\ delimiter string. If maxsplit is given, at most maxsplit\n\ -splits are done. If sep is not specified, any whitespace string\n\ -is a separator."); +splits are done. If sep is not specified or None, +any whitespace string is a separator."); static PyObject* unicode_split(PyUnicodeObject *self, PyObject *args) From doerwalter at users.sourceforge.net Tue Sep 14 11:45:12 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 14 11:45:16 2004 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c, 2.225, 2.226 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17104/Objects Modified Files: unicodeobject.c Log Message: Make the hint about the None default less ambiguous. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.225 retrieving revision 2.226 diff -u -d -r2.225 -r2.226 --- unicodeobject.c 14 Sep 2004 09:40:44 -0000 2.225 +++ unicodeobject.c 14 Sep 2004 09:45:10 -0000 2.226 @@ -5987,7 +5987,7 @@ \n\ Return a list of the words in S, using sep as the\n\ delimiter string. If maxsplit is given, at most maxsplit\n\ -splits are done. If sep is not specified or None, +splits are done. If sep is not specified or is None, any whitespace string is a separator."); static PyObject* From doerwalter at users.sourceforge.net Tue Sep 14 11:45:12 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Tue Sep 14 11:45:17 2004 Subject: [Python-checkins] python/dist/src/Lib string.py,1.81,1.82 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17104/Lib Modified Files: string.py Log Message: Make the hint about the None default less ambiguous. Index: string.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/string.py,v retrieving revision 1.81 retrieving revision 1.82 diff -u -d -r1.81 -r1.82 --- string.py 14 Sep 2004 09:40:45 -0000 1.81 +++ string.py 14 Sep 2004 09:45:10 -0000 1.82 @@ -282,7 +282,7 @@ Return a list of the words in the string s, using sep as the delimiter string. If maxsplit is given, splits at no more than maxsplit places (resulting in at most maxsplit+1 words). If sep - is not specified or None, any whitespace string is a separator. + is not specified or is None, any whitespace string is a separator. (split and splitfields are synonymous) From montanaro at users.sourceforge.net Tue Sep 14 18:32:05 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue Sep 14 18:32:08 2004 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.87,1.88 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26872/Lib Modified Files: httplib.py Log Message: Search from the end of the host/port combination to find the colon which separates ip address from the port to accommodate ipv6 addresses. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.87 retrieving revision 1.88 diff -u -d -r1.87 -r1.88 --- httplib.py 18 Aug 2004 12:46:25 -0000 1.87 +++ httplib.py 14 Sep 2004 16:32:01 -0000 1.88 @@ -524,7 +524,7 @@ def _set_hostport(self, host, port): if port is None: - i = host.find(':') + i = host.rfind(':') if i >= 0: try: port = int(host[i+1:]) From montanaro at users.sourceforge.net Tue Sep 14 18:32:05 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue Sep 14 18:32:09 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_httplib.py, 1.13, 1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26872/Lib/test Modified Files: test_httplib.py Log Message: Search from the end of the host/port combination to find the colon which separates ip address from the port to accommodate ipv6 addresses. Index: test_httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_httplib.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- test_httplib.py 7 Aug 2004 16:28:14 -0000 1.13 +++ test_httplib.py 14 Sep 2004 16:32:02 -0000 1.14 @@ -118,6 +118,13 @@ else: print "Expect InvalidURL" + for hp in ("[fe80::207:e9ff:fe9b]:8000", "www.python.org:80", + "www.python.org"): + try: + h = httplib.HTTP(hp) + except httplib.InvalidURL: + print "InvalidURL raised erroneously" + # test response with multiple message headers with the same field name. text = ('HTTP/1.1 200 OK\r\n' 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n' From mwh at users.sourceforge.net Tue Sep 14 19:09:49 2004 From: mwh at users.sourceforge.net (mwh@users.sourceforge.net) Date: Tue Sep 14 19:09:52 2004 Subject: [Python-checkins] python/dist/src/Objects object.c,2.221,2.222 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2545 Modified Files: object.c Log Message: Move a comment back to its rightful location. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.221 retrieving revision 2.222 diff -u -d -r2.221 -r2.222 --- object.c 7 Aug 2004 04:55:30 -0000 2.221 +++ object.c 14 Sep 2004 17:09:47 -0000 2.222 @@ -1176,8 +1176,6 @@ return (PyObject **) ((char *)obj + dictoffset); } -/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */ - PyObject * PyObject_SelfIter(PyObject *obj) { @@ -1185,6 +1183,8 @@ return obj; } +/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */ + PyObject * PyObject_GenericGetAttr(PyObject *obj, PyObject *name) { From mwh at users.sourceforge.net Tue Sep 14 19:19:11 2004 From: mwh at users.sourceforge.net (mwh@users.sourceforge.net) Date: Tue Sep 14 19:19:15 2004 Subject: [Python-checkins] python/dist/src/Objects moduleobject.c,2.47,2.48 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4425 Modified Files: moduleobject.c Log Message: Make the word "module" appear in the error string for calling the module type with silly arguments. (The exact name can be quibbled over, if you care). This was partially inspired by bug #1014215 and so on, but is also just a good idea. Index: moduleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v retrieving revision 2.47 retrieving revision 2.48 diff -u -d -r2.47 -r2.48 --- moduleobject.c 16 Jul 2003 22:04:11 -0000 2.47 +++ moduleobject.c 14 Sep 2004 17:19:09 -0000 2.48 @@ -151,7 +151,7 @@ { static char *kwlist[] = {"name", "doc", NULL}; PyObject *dict, *name = Py_None, *doc = Py_None; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__", kwlist, &name, &doc)) return -1; dict = m->md_dict; From montanaro at users.sourceforge.net Tue Sep 14 19:55:24 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue Sep 14 19:55:27 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_httplib.py, 1.14, 1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12172/Lib/test Modified Files: test_httplib.py Log Message: missed the obvious test case and corresponding fix Index: test_httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_httplib.py,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- test_httplib.py 14 Sep 2004 16:32:02 -0000 1.14 +++ test_httplib.py 14 Sep 2004 17:55:21 -0000 1.15 @@ -119,7 +119,7 @@ print "Expect InvalidURL" for hp in ("[fe80::207:e9ff:fe9b]:8000", "www.python.org:80", - "www.python.org"): + "www.python.org", "[fe80::207:e9ff:fe9b]"): try: h = httplib.HTTP(hp) except httplib.InvalidURL: From montanaro at users.sourceforge.net Tue Sep 14 19:55:24 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue Sep 14 19:55:28 2004 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.88,1.89 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12172/Lib Modified Files: httplib.py Log Message: missed the obvious test case and corresponding fix Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.88 retrieving revision 1.89 diff -u -d -r1.88 -r1.89 --- httplib.py 14 Sep 2004 16:32:01 -0000 1.88 +++ httplib.py 14 Sep 2004 17:55:21 -0000 1.89 @@ -525,7 +525,8 @@ def _set_hostport(self, host, port): if port is None: i = host.rfind(':') - if i >= 0: + j = host.rfind(']') # ipv6 addresses have [...] + if i > j: try: port = int(host[i+1:]) except ValueError: From montanaro at users.sourceforge.net Tue Sep 14 19:58:49 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue Sep 14 19:58:52 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1133,1.1134 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12627 Modified Files: NEWS Log Message: mention httplib ipv6 fix Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1133 retrieving revision 1.1134 diff -u -d -r1.1133 -r1.1134 --- NEWS 13 Sep 2004 08:53:15 -0000 1.1133 +++ NEWS 14 Sep 2004 17:58:31 -0000 1.1134 @@ -42,6 +42,8 @@ encourage people to stitch doctests together via doctest's unittest integration features instead. It would help if those were documented. +- httplib now handles ipv6 address/port pairs. + Build ----- From loewis at users.sourceforge.net Tue Sep 14 23:45:46 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue Sep 14 23:45:50 2004 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.89,1.90 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2020/Lib Modified Files: httplib.py Log Message: Strip square brackets from IPv6 address. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.89 retrieving revision 1.90 diff -u -d -r1.89 -r1.90 --- httplib.py 14 Sep 2004 17:55:21 -0000 1.89 +++ httplib.py 14 Sep 2004 21:45:35 -0000 1.90 @@ -534,6 +534,8 @@ host = host[:i] else: port = self.default_port + if host[0] == '[' and host[-1] == ']': + host = host[1:-1] self.host = host self.port = port From loewis at users.sourceforge.net Tue Sep 14 23:45:46 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue Sep 14 23:45:51 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_httplib.py, 1.15, 1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2020/Lib/test Modified Files: test_httplib.py Log Message: Strip square brackets from IPv6 address. Index: test_httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_httplib.py,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- test_httplib.py 14 Sep 2004 17:55:21 -0000 1.15 +++ test_httplib.py 14 Sep 2004 21:45:36 -0000 1.16 @@ -118,12 +118,17 @@ else: print "Expect InvalidURL" - for hp in ("[fe80::207:e9ff:fe9b]:8000", "www.python.org:80", - "www.python.org", "[fe80::207:e9ff:fe9b]"): + for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000), + ("www.python.org:80", "www.python.org", 80), + ("www.python.org", "www.python.org", 80), + ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)): try: - h = httplib.HTTP(hp) + http = httplib.HTTP(hp) except httplib.InvalidURL: print "InvalidURL raised erroneously" + c = http._conn + if h != c.host: raise AssertionError, ("Host incorrectly parsed", h, c.host) + if p != c.port: raise AssertionError, ("Port incorrectly parsed", p, c.host) # test response with multiple message headers with the same field name. text = ('HTTP/1.1 200 OK\r\n' From loewis at users.sourceforge.net Wed Sep 15 08:02:57 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed Sep 15 08:03:00 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_tempfile.py, 1.17, 1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21350/Lib/test Modified Files: test_tempfile.py Log Message: Patch #1026986: Add OpenBSD 3.5 and 3.6 to list of broken systems. Index: test_tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_tempfile.py,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- test_tempfile.py 31 Mar 2004 18:53:29 -0000 1.17 +++ test_tempfile.py 15 Sep 2004 06:02:54 -0000 1.18 @@ -27,6 +27,8 @@ # number of files that can be opened at one time (see ulimit -n) if sys.platform == 'mac': TEST_FILES = 32 +elif sys.platform == 'openbsd3': + TEST_FILES = 48 else: TEST_FILES = 100 From loewis at users.sourceforge.net Wed Sep 15 08:02:57 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed Sep 15 08:03:01 2004 Subject: [Python-checkins] python/dist/src configure, 1.455, 1.456 configure.in, 1.468, 1.469 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21350 Modified Files: configure configure.in Log Message: Patch #1026986: Add OpenBSD 3.5 and 3.6 to list of broken systems. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.455 retrieving revision 1.456 diff -u -d -r1.455 -r1.456 --- configure 25 Aug 2004 23:59:39 -0000 1.455 +++ configure 15 Sep 2004 06:02:47 -0000 1.456 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.467 . +# From configure.in Revision: 1.468 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for python 2.4. # @@ -1477,7 +1477,7 @@ # On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined, # even though select is a POSIX function. Reported by J. Ribbens. # Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish. - OpenBSD/2.* | OpenBSD/3.[01234]) + OpenBSD/2.* | OpenBSD/3.[0123456]) define_xopen_source=no;; # On Solaris 2.6, sys/wait.h is inconsistent in the usage # of union __?sigval. Reported by Stuart Bishop. Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.468 retrieving revision 1.469 diff -u -d -r1.468 -r1.469 --- configure.in 25 Aug 2004 23:55:59 -0000 1.468 +++ configure.in 15 Sep 2004 06:02:53 -0000 1.469 @@ -140,7 +140,7 @@ # On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined, # even though select is a POSIX function. Reported by J. Ribbens. # Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish. - OpenBSD/2.* | OpenBSD/3.@<:@01234@:>@) + OpenBSD/2.* | OpenBSD/3.@<:@0123456@:>@) define_xopen_source=no;; # On Solaris 2.6, sys/wait.h is inconsistent in the usage # of union __?sigval. Reported by Stuart Bishop. From theller at users.sourceforge.net Wed Sep 15 13:41:39 2004 From: theller at users.sourceforge.net (theller@users.sourceforge.net) Date: Wed Sep 15 13:41:42 2004 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c, 2.226, 2.227 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12214 Modified Files: unicodeobject.c Log Message: Add a missing line continuation character. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.226 retrieving revision 2.227 diff -u -d -r2.226 -r2.227 --- unicodeobject.c 14 Sep 2004 09:45:10 -0000 2.226 +++ unicodeobject.c 15 Sep 2004 11:41:32 -0000 2.227 @@ -5987,7 +5987,7 @@ \n\ Return a list of the words in S, using sep as the\n\ delimiter string. If maxsplit is given, at most maxsplit\n\ -splits are done. If sep is not specified or is None, +splits are done. If sep is not specified or is None,\n\ any whitespace string is a separator."); static PyObject* From pje at users.sourceforge.net Wed Sep 15 19:05:26 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Wed Sep 15 19:05:30 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18247 Modified Files: pep-0333.txt Log Message: Clarify the meaning of "string" for platforms where 'str' objects can contain Unicode (e.g. Jython, IronPython, Python 3000, etc.), per discussion at: http://mail.python.org/pipermail/web-sig/2004-September/000860.html Also, misc. copy edits. Only one open issue left! Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- pep-0333.txt 14 Sep 2004 06:02:28 -0000 1.10 +++ pep-0333.txt 15 Sep 2004 17:05:22 -0000 1.11 @@ -756,6 +756,22 @@ is, they must either be ISO-8859-1 characters, or use RFC 2047 MIME encoding. +On Python platforms where the ``str`` or ``StringType`` type is in +fact Unicode-based (e.g. Jython, IronPython, Python 3000, etc.), all +"strings" referred to in this specification must contain only +code points representable in ISO-8859-1 encoding (``\u0000`` through +``\u00FF``, inclusive). It is a fatal error for an application to +supply strings containing any other Unicode character or code point. +Similarly, servers and gateways **must not** supply +strings to an application containing any other Unicode characters. + +Again, all strings referred to in this specification **must** be +of type ``str`` or ``StringType``, and **must not** be of type +``unicode`` or ``UnicodeType``. And, even if a given platform allows +for more than 8 bits per character in ``str``/``StringType`` objects, +only the lower 8 bits may be used, for any value referred to in +this specification as a "string". + Multiple Invocations -------------------- @@ -1223,7 +1239,7 @@ offering any such value-added services. 2. Why can you call ``write()`` *and* yield strings/return an - iterator? Shouldn't we pick just one way? + iterable? Shouldn't we pick just one way? If we supported only the iteration approach, then current frameworks that assume the availability of "push" suffer. But, if @@ -1237,11 +1253,11 @@ 3. What's the ``close()`` for? - When writes are done from during the execution of an application + When writes are done during the execution of an application object, the application can ensure that resources are released using a try/finally block. But, if the application returns an - iterator, any resources used will not be released until the - iterator is garbage collected. The ``close()`` idiom allows an + iterable, any resources used will not be released until the + iterable is garbage collected. The ``close()`` idiom allows an application to release critical resources at the end of a request, and it's forward-compatible with the support for try/finally in generators that's proposed by PEP 325. @@ -1347,14 +1363,6 @@ Open Issues =========== -* Byte strings: future versions of Python may replace today's - 8-bit strings with some kind of "byte array" type. Some sort - of future-proofing would be good to have, and strategies for - this should be discussed on Web-SIG and Python-Dev. Nearly - every string in WSGI is potentially affected by this, although - some contexts should perhaps continue to allow strings as long as - they're pure ASCII. - * Required CGI variables: should we really be requiring all of the variables named? Some of them seem reasonable to be optional. From pje at users.sourceforge.net Wed Sep 15 22:41:19 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Wed Sep 15 22:41:22 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv450 Modified Files: pep-0333.txt Log Message: Flesh out CGI variable definitions, and slightly loosen server-side requirements for providing variables that may be empty. That's the last of the open issues, so it's time for another posting, and a last call for issues prior to finalization. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- pep-0333.txt 15 Sep 2004 17:05:22 -0000 1.11 +++ pep-0333.txt 15 Sep 2004 20:41:16 -0000 1.12 @@ -350,47 +350,63 @@ The ``environ`` dictionary is required to contain these CGI environment variables, as defined by the Common Gateway Interface -specification [2]_. The following variables **must** be present, but -**may** be an empty string, if there is no more appropriate value for -them: +specification [2]_. The following variables **must** be present, +unless their value would be an empty string, in which case they +**may** be omitted, except as otherwise noted below. -* ``REQUEST_METHOD`` +``REQUEST_METHOD`` + The HTTP request method, such as ``"GET"`` or ``"POST"``. This + cannot ever be an empty string, and so is always required. -* ``SCRIPT_NAME`` (The initial portion of the request URL's "path" - that corresponds to the application object, so that the application - knows its virtual "location".) +``SCRIPT_NAME`` + The initial portion of the request URL's "path" that corresponds to + the application object, so that the application knows its virtual + "location". This **may** be an empty string, if the application + corresponds to the "root" of the server. -* ``PATH_INFO`` (The remainder of the request URL's "path", - designating the virtual "location" of the request's target within - the application) +``PATH_INFO`` + The remainder of the request URL's "path", designating the virtual + "location" of the request's target within the application. This + **may** be an empty string, if the request URL targets the + application root and does not have a trailing slash. -* ``QUERY_STRING`` +``QUERY_STRING`` + The portion of the request URL that follows the ``"?"``, if any. + May be empty or absent. -* ``CONTENT_TYPE`` +``CONTENT_TYPE`` + The contents of any ``Content-Type`` fields in the HTTP request. + May be empty or absent. -* ``CONTENT_LENGTH`` +``CONTENT_LENGTH`` + The contents of any ``Content-Length`` fields in the HTTP request. + May be empty or absent. -* ``SERVER_NAME`` and ``SERVER_PORT`` (which, when combined with - ``SCRIPT_NAME`` and ``PATH_INFO``, should complete the URL. Note, - however, that ``HTTP_HOST``, if present, should be used in - preference to ``SERVER_NAME`` for constructing the URL. See the - `URL Reconstruction`_ section below for more detail.) +``SERVER_NAME``, ``SERVER_PORT`` + When combined with ``SCRIPT_NAME`` and ``PATH_INFO``, these variables + can be used to complete the URL. Note, however, that ``HTTP_HOST``, + if present, should be used in preference to ``SERVER_NAME`` for + reconstructing the request URL. See the `URL Reconstruction`_ + section below for more detail. ``SERVER_NAME`` and ``SERVER_PORT`` + can never be empty strings, and so are always required. -* Variables corresponding to the client-supplied HTTP headers (i.e., - variables whose names begin with ``"HTTP_"``). +``HTTP_`` Variables + Variables corresponding to the client-supplied HTTP headers (i.e., + variables whose names begin with ``"HTTP_"``). The presence or + absence of these variables should correspond with the presence or + absence of the appropriate HTTP header in the request. -In general, a server or gateway should attempt to provide as many +In general, a server or gateway **should** attempt to provide as many other CGI variables as are applicable, including e.g. the nonstandard SSL variables such as ``HTTPS=on``, if an SSL connection is in effect. -However, an application that uses any variables other than the ones +However, an application that uses any CGI variables other than the ones listed above are necessarily non-portable to web servers that do not support the relevant extensions. -A WSGI-compliant server or gateway *should* document what variables it -provides, along with their definitions as appropriate. Applications -*should* check for the presence of any nonstandard variables they -require, and have a fallback plan in the event such a variable is -absent. +A WSGI-compliant server or gateway **should** document what variables +it provides, along with their definitions as appropriate. Applications +**should** check for the presence of any variables they require, and +have a fallback plan in the event such a variable is absent. Note: missing variables (such as ``REMOTE_USER`` when no authentication has occurred) should be left out of the ``environ`` @@ -867,8 +883,8 @@ if environ['SERVER_PORT'] != '80': url += ':' + environ['SERVER_PORT'] - url += environ['SCRIPT_NAME'] - url += environ['PATH_INFO'] + url += environ.get('SCRIPT_NAME','') + url += environ.get('PATH_INFO','') if environ.get('QUERY_STRING'): url += '?' + environ['QUERY_STRING'] @@ -1360,13 +1376,6 @@ developers. -Open Issues -=========== - -* Required CGI variables: should we really be requiring all of the - variables named? Some of them seem reasonable to be optional. - - Acknowledgements ================ From bcannon at users.sourceforge.net Thu Sep 16 01:26:26 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Thu Sep 16 01:26:29 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_httplib.py, 1.16, 1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12254/Lib/test Modified Files: test_httplib.py Log Message: Remove tabs. Index: test_httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_httplib.py,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- test_httplib.py 14 Sep 2004 21:45:36 -0000 1.16 +++ test_httplib.py 15 Sep 2004 23:26:23 -0000 1.17 @@ -121,14 +121,14 @@ for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000), ("www.python.org:80", "www.python.org", 80), ("www.python.org", "www.python.org", 80), - ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)): + ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)): try: http = httplib.HTTP(hp) except httplib.InvalidURL: print "InvalidURL raised erroneously" - c = http._conn - if h != c.host: raise AssertionError, ("Host incorrectly parsed", h, c.host) - if p != c.port: raise AssertionError, ("Port incorrectly parsed", p, c.host) + c = http._conn + if h != c.host: raise AssertionError, ("Host incorrectly parsed", h, c.host) + if p != c.port: raise AssertionError, ("Port incorrectly parsed", p, c.host) # test response with multiple message headers with the same field name. text = ('HTTP/1.1 200 OK\r\n' From bcannon at users.sourceforge.net Thu Sep 16 01:26:26 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Thu Sep 16 01:26:30 2004 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.90,1.91 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12254/Lib Modified Files: httplib.py Log Message: Remove tabs. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.90 retrieving revision 1.91 diff -u -d -r1.90 -r1.91 --- httplib.py 14 Sep 2004 21:45:35 -0000 1.90 +++ httplib.py 15 Sep 2004 23:26:22 -0000 1.91 @@ -534,8 +534,8 @@ host = host[:i] else: port = self.default_port - if host[0] == '[' and host[-1] == ']': - host = host[1:-1] + if host[0] == '[' and host[-1] == ']': + host = host[1:-1] self.host = host self.port = port From tim_one at users.sourceforge.net Thu Sep 16 02:09:22 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 16 02:09:25 2004 Subject: [Python-checkins] python/dist/src/Lib string.py,1.82,1.83 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20958/Lib Modified Files: string.py Log Message: Whitespace normalization. Index: string.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/string.py,v retrieving revision 1.82 retrieving revision 1.83 diff -u -d -r1.82 -r1.83 --- string.py 14 Sep 2004 09:45:10 -0000 1.82 +++ string.py 16 Sep 2004 00:09:11 -0000 1.83 @@ -178,7 +178,7 @@ mapping = _multimap(kws, args[0]) else: mapping = args[0] - delimiter = self.delimiter[-1] + delimiter = self.delimiter[-1] # Helper function for .sub() def convert(mo): named = mo.group('named') From tim_one at users.sourceforge.net Thu Sep 16 02:09:22 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 16 02:09:25 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_httplib.py, 1.17, 1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20958/Lib/test Modified Files: test_httplib.py Log Message: Whitespace normalization. Index: test_httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_httplib.py,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- test_httplib.py 15 Sep 2004 23:26:23 -0000 1.17 +++ test_httplib.py 16 Sep 2004 00:09:19 -0000 1.18 @@ -118,7 +118,7 @@ else: print "Expect InvalidURL" - for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000), + for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000), ("www.python.org:80", "www.python.org", 80), ("www.python.org", "www.python.org", 80), ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)): From tim_one at users.sourceforge.net Thu Sep 16 03:30:50 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 16 03:30:53 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py, 1.48, 1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3145/Lib/test Modified Files: test_datetime.py Log Message: SF bug #1028306: date-datetime comparison Treat comparing a date to a datetime like a mixed-type comparison. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.48 retrieving revision 1.49 diff -u -d -r1.48 -r1.49 --- test_datetime.py 20 Jun 2004 02:50:15 -0000 1.48 +++ test_datetime.py 16 Sep 2004 01:30:47 -0000 1.49 @@ -3151,6 +3151,48 @@ fstart += HOUR +############################################################################# +# oddballs + +class Oddballs(unittest.TestCase): + + def test_bug_1028306(self): + # Trying to compare a date to a datetime should act like a mixed- + # type comparison, despite that datetime is a subclass of date. + as_date = date.today() + as_datetime = datetime.combine(as_date, time()) + self.assert_(as_date != as_datetime) + self.assert_(as_datetime != as_date) + self.assert_(not as_date == as_datetime) + self.assert_(not as_datetime == as_date) + self.assertRaises(TypeError, lambda: as_date < as_datetime) + self.assertRaises(TypeError, lambda: as_datetime < as_date) + self.assertRaises(TypeError, lambda: as_date <= as_datetime) + self.assertRaises(TypeError, lambda: as_datetime <= as_date) + self.assertRaises(TypeError, lambda: as_date > as_datetime) + self.assertRaises(TypeError, lambda: as_datetime > as_date) + self.assertRaises(TypeError, lambda: as_date >= as_datetime) + self.assertRaises(TypeError, lambda: as_datetime >= as_date) + + # Neverthelss, comparison should work with the base-class (date) + # projection if use of a date method is forced. + self.assert_(as_date.__eq__(as_datetime)) + different_day = (as_date.day + 1) % 20 + 1 + self.assert_(not as_date.__eq__(as_datetime.replace(day= + different_day))) + + # And date should compare with other subclasses of date. If a + # subclass wants to stop this, it's up to the subclass to do so. + date_sc = SubclassDate(as_date.year, as_date.month, as_date.day) + self.assertEqual(as_date, date_sc) + self.assertEqual(date_sc, as_date) + + # Ditto for datetimes. + datetime_sc = SubclassDatetime(as_datetime.year, as_datetime.month, + as_date.day, 0, 0, 0) + self.assertEqual(as_datetime, datetime_sc) + self.assertEqual(datetime_sc, as_datetime) + def test_suite(): allsuites = [unittest.makeSuite(klass, 'test') for klass in (TestModule, @@ -3163,6 +3205,7 @@ TestTimeTZ, TestDateTimeTZ, TestTimezoneConversions, + Oddballs, ) ] return unittest.TestSuite(allsuites) From tim_one at users.sourceforge.net Thu Sep 16 03:30:52 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 16 03:30:56 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1134,1.1135 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3145/Misc Modified Files: NEWS Log Message: SF bug #1028306: date-datetime comparison Treat comparing a date to a datetime like a mixed-type comparison. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1134 retrieving revision 1.1135 diff -u -d -r1.1134 -r1.1135 --- NEWS 14 Sep 2004 17:58:31 -0000 1.1134 +++ NEWS 16 Sep 2004 01:30:48 -0000 1.1135 @@ -22,6 +22,16 @@ Library ------- +- SF bug #1028306: Trying to compare a ``datetime.date`` to a + ``datetime.datetime`` mistakenly compared only the year, month and day. + Now it acts like a mixed-type comparison: ``False`` for ``==``, + ``True`` for ``!=``, and raises ``TypeError`` for other comparison + operators. Because datetime is a subclass of date, comparing only the + base class (date) members can still be done, if that's desired, by + forcing using of the approprate date method; e.g., + ``a_date.__eq__(a_datetime)`` is true if and only if the year, month + and day members of ``a_date`` and ``a_datetime`` are equal. + - bdist_rpm now supports command line options --force-arch, {pre,post}-install, {pre,post}-uninstall, and {prep,build,install,clean,verify}-script. From tim_one at users.sourceforge.net Thu Sep 16 03:30:52 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 16 03:30:57 2004 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c, 1.74, 1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3145/Modules Modified Files: datetimemodule.c Log Message: SF bug #1028306: date-datetime comparison Treat comparing a date to a datetime like a mixed-type comparison. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.74 retrieving revision 1.75 diff -u -d -r1.74 -r1.75 --- datetimemodule.c 20 Jun 2004 22:41:32 -0000 1.74 +++ datetimemodule.c 16 Sep 2004 01:30:50 -0000 1.75 @@ -4075,7 +4075,17 @@ int offset1, offset2; if (! PyDateTime_Check(other)) { - if (PyObject_HasAttrString(other, "timetuple")) { + /* If other has a "timetuple" attr, that's an advertised + * hook for other classes to ask to get comparison control. + * However, date instances have a timetuple attr, and we + * don't want to allow that comparison. Because datetime + * is a subclass of date, when mixing date and datetime + * in a comparison, Python gives datetime the first shot + * (it's the more specific subtype). So we can stop that + * combination here reliably. + */ + if (PyObject_HasAttrString(other, "timetuple") && + ! PyDate_Check(other)) { /* A hook for other kinds of datetime objects. */ Py_INCREF(Py_NotImplemented); return Py_NotImplemented; From pje at users.sourceforge.net Thu Sep 16 03:56:47 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Thu Sep 16 03:56:52 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7190 Modified Files: pep-0333.txt Log Message: Fix some minor errors found during actual implementation of example code. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- pep-0333.txt 15 Sep 2004 20:41:16 -0000 1.12 +++ pep-0333.txt 16 Sep 2004 01:56:44 -0000 1.13 @@ -198,8 +198,7 @@ def run_with_cgi(application): - environ = {} - environ.update(os.environ) + environ = dict(os.environ.items()) environ['wsgi.input'] = sys.stdin environ['wsgi.errors'] = sys.stderr environ['wsgi.version'] = (1,0) @@ -207,9 +206,6 @@ environ['wsgi.multiprocess'] = True environ['wsgi.last_call'] = True - # XXX really should set defaults for WSGI-required variables; - # see "environ Variables" section below - if environ.get('HTTPS','off') in ('on','1'): environ['wsgi.url_scheme'] = 'https' else: @@ -251,6 +247,8 @@ try: for data in result: write(data) + if not headers_sent: + write('') # force headers to be sent finally: if hasattr(result,'close'): result.close() From montanaro at users.sourceforge.net Thu Sep 16 05:28:15 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu Sep 16 05:28:19 2004 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c, 2.227, 2.228 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21892 Modified Files: unicodeobject.c Log Message: Initialize sep and seplen to suppress warning from gcc. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.227 retrieving revision 2.228 diff -u -d -r2.227 -r2.228 --- unicodeobject.c 15 Sep 2004 11:41:32 -0000 2.227 +++ unicodeobject.c 16 Sep 2004 03:28:13 -0000 2.228 @@ -4013,15 +4013,15 @@ PyUnicode_Join(PyObject *separator, PyObject *seq) { PyObject *internal_separator = NULL; - const Py_UNICODE *sep; - size_t seplen; + const Py_UNICODE blank = ' '; + const Py_UNICODE *sep = ␣ + size_t seplen = 1; PyUnicodeObject *res = NULL; /* the result */ size_t res_alloc = 100; /* # allocated bytes for string in res */ size_t res_used; /* # used bytes */ Py_UNICODE *res_p; /* pointer to free byte in res's string area */ PyObject *fseq; /* PySequence_Fast(seq) */ int seqlen; /* len(fseq) -- number of items in sequence */ - const Py_UNICODE blank = ' '; PyObject *item; int i; From montanaro at users.sourceforge.net Thu Sep 16 05:31:24 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu Sep 16 05:31:27 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_httplib.py, 1.12, 1.12.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22458/Lib/test Modified Files: Tag: release23-maint test_httplib.py Log Message: backport ipv6 address fix Index: test_httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_httplib.py,v retrieving revision 1.12 retrieving revision 1.12.6.1 diff -u -d -r1.12 -r1.12.6.1 --- test_httplib.py 8 Jul 2003 12:36:58 -0000 1.12 +++ test_httplib.py 16 Sep 2004 03:31:21 -0000 1.12.6.1 @@ -80,6 +80,18 @@ else: print "Expect InvalidURL" + for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000), + ("www.python.org:80", "www.python.org", 80), + ("www.python.org", "www.python.org", 80), + ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)): + try: + http = httplib.HTTP(hp) + except httplib.InvalidURL: + print "InvalidURL raised erroneously" + c = http._conn + if h != c.host: raise AssertionError, ("Host incorrectly parsed", h, c.host) + if p != c.port: raise AssertionError, ("Port incorrectly parsed", p, c.host) + # test response with multiple message headers with the same field name. text = ('HTTP/1.1 200 OK\r\n' 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n' From montanaro at users.sourceforge.net Thu Sep 16 05:31:24 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu Sep 16 05:31:28 2004 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.79.8.2,1.79.8.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22458/Lib Modified Files: Tag: release23-maint httplib.py Log Message: backport ipv6 address fix Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.79.8.2 retrieving revision 1.79.8.3 diff -u -d -r1.79.8.2 -r1.79.8.3 --- httplib.py 2 Nov 2003 16:51:38 -0000 1.79.8.2 +++ httplib.py 16 Sep 2004 03:31:21 -0000 1.79.8.3 @@ -510,8 +510,9 @@ def _set_hostport(self, host, port): if port is None: - i = host.find(':') - if i >= 0: + i = host.rfind(':') + j = host.rfind(']') # ipv6 addresses have [...] + if i > j: try: port = int(host[i+1:]) except ValueError: @@ -519,6 +520,8 @@ host = host[:i] else: port = self.default_port + if host[0] == '[' and host[-1] == ']': + host = host[1:-1] self.host = host self.port = port From anthonybaxter at users.sourceforge.net Thu Sep 16 18:04:56 2004 From: anthonybaxter at users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Thu Sep 16 18:04:59 2004 Subject: [Python-checkins] python/nondist/peps pep-0320.txt,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32334 Modified Files: pep-0320.txt Log Message: Oct 12 for b1. Index: pep-0320.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0320.txt,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- pep-0320.txt 4 Sep 2004 22:49:54 -0000 1.17 +++ pep-0320.txt 16 Sep 2004 16:04:53 -0000 1.18 @@ -33,6 +33,8 @@ Sept 3: alpha 3 [completed] + October 11/12: beta 1 [scheduled] + Completed features for 2.4 PEP 218 Builtin Set Objects. From rhettinger at users.sourceforge.net Thu Sep 16 18:42:03 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 16 18:42:06 2004 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.416,2.417 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7202 Modified Files: ceval.c Log Message: SF bug #1014215: Unspecific errors with metaclass High level error message was stomping useful detailed messages from lower level routines. The new approach is to augment string error messages returned by the low level routines. The provides both high and low level information. If the exception value is not a string, no changes are made. To see the improved messages in action, type: import random class R(random): pass class B(bool): pass Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.416 retrieving revision 2.417 diff -u -d -r2.416 -r2.417 --- ceval.c 29 Aug 2004 15:51:52 -0000 2.416 +++ ceval.c 16 Sep 2004 16:41:57 -0000 2.417 @@ -4086,10 +4086,22 @@ /* A type error here likely means that the user passed in a base that was not a class (such the random module instead of the random.random type). Help them out with - a more informative error message */ - PyErr_SetString(PyExc_TypeError, - "Error when calling the metaclass.\n" \ - "Make sure the base arguments are valid."); + by augmenting the error message with more information.*/ + + PyObject *ptype, *pvalue, *ptraceback; + + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + if (PyString_Check(pvalue)) { + PyObject *newmsg; + newmsg = PyString_FromFormat( + "Error when calling the metaclass bases\n %s", + PyString_AS_STRING(pvalue)); + if (newmsg != NULL) { + Py_DECREF(pvalue); + pvalue = newmsg; + } + } + PyErr_Restore(ptype, pvalue, ptraceback); } return result; } From pje at users.sourceforge.net Thu Sep 16 23:22:42 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Thu Sep 16 23:22:46 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4421 Modified Files: pep-0333.txt Log Message: Allow applications to yield empty strings, and require middleware to respect applications' block boundaries, so that asynchronous applications can potentially pause their output while waiting for (non-browser) I/O. See these posts and the associated threads for the discussion: http://mail.python.org/pipermail/web-sig/2004-September/000868.html http://mail.python.org/pipermail/web-sig/2004-September/000880.html Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- pep-0333.txt 16 Sep 2004 01:56:44 -0000 1.13 +++ pep-0333.txt 16 Sep 2004 21:22:39 -0000 1.14 @@ -246,9 +246,10 @@ result = application(environ, start_response) try: for data in result: - write(data) + if data: # don't send headers until body appears + write(data) if not headers_sent: - write('') # force headers to be sent + write('') # send headers now if body was empty finally: if hasattr(result,'close'): result.close() @@ -579,10 +580,11 @@ forced to bear the pain of its error.) The ``start_response`` callable **must not** actually transmit the -HTTP headers. It must store them until the first ``write`` call, -or until after the first iteration of the application return value. -This is to ensure that buffered applications can replace their -originally intended output with error output, up until the last +HTTP headers. It must store them until the first ``write`` call that +is passed a non-empty string, or until after the first iteration of +the application return value that yields a non-empty string. This is +to ensure that buffered and asynchronous applications can replace +their originally intended output with error output, up until the last possible moment. The ``exc_info`` argument, if supplied, must be a Python @@ -690,11 +692,12 @@ boundaries (for "server push"), or just before time-consuming tasks (such as reading another block of an on-disk file). -WSGI servers and gateways **must not** delay the transmission -of any block; they **must** either fully transmit the block to -the client, or guarantee that they will continue transmission -even while the application is producing its next block. A -server/gateway may provide this guarantee in one of two ways: +WSGI servers, gateways, and middleware **must not** delay the +transmission of any block; they **must** either fully transmit +the block to the client, or guarantee that they will continue +transmission even while the application is producing its next block. +A server/gateway or middleware may provide this guarantee in one of +three ways: 1. Send the entire block to the operating system (and request that any O/S buffers be flushed) before returning control @@ -703,6 +706,9 @@ 2. Use a different thread to ensure that the block continues to be transmitted while the application produces the next block. + +3. (Middleware only) send the entire block to its parent + gateway/server By providing this guarantee, WSGI allows applications to ensure that transmission will not become stalled at an arbitrary point @@ -711,6 +717,34 @@ multipart boundaries should be transmitted in full to the client. +Middleware Handling of Block Boundaries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to better support asynchronous applications and servers, +middleware components **must not** block iteration waiting for +multiple values from an application iterable. If the middleware +needs to accumulate more data from the application before it can +produce any output, it **must** yield an empty string. + +To put this requirement another way, a middleware component **must +yield at least one value** each time its underlying application +yields a value. If the middleware cannot yield any other value, +it must yield an empty string. + +This requirement ensures that asynchronous applications and servers +can conspire to reduce the number of threads that are required +to run a given number of application instances simultaneously. + +Note also that this requirement means that middleware **must** +return an iterable as soon as its underlying application returns +an iterable. It is also forbidden for middleware to use the +``write()`` callable to transmit data that is yielded by an +underlying application. Middleware may only use their parent +server's ``write()`` callable to transmit data that the +underlying application sent using a middleware-provided ``write()`` +callable. + + The ``write()`` Callable ~~~~~~~~~~~~~~~~~~~~~~~~ From pje at users.sourceforge.net Fri Sep 17 00:04:38 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Fri Sep 17 00:04:49 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12356 Modified Files: pep-0333.txt Log Message: Fix "hop-by-hop" headers issues raised in section 2 of this post: http://mail.python.org/pipermail/web-sig/2004-September/000879.html This ended up simplifying the language regarding who controls what headers, and eliminated the previous complexity regarding logging of suppressed headers. Thanks for the comments, James! Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- pep-0333.txt 16 Sep 2004 21:22:39 -0000 1.14 +++ pep-0333.txt 16 Sep 2004 22:04:35 -0000 1.15 @@ -565,19 +565,15 @@ case-insensitive, so be sure to take that into consideration when examining application-supplied headers!) -If the application supplies headers that would affect the persistence -of the client's connection (e.g. ``Connection:``, "keep-alives", etc.), -the server or gateway is permitted to discard or modify these headers, -if the server cannot or will not conform to the application's requested -semantics. E.g., if the application requests a persistent connection -but the server wishes transience, or vice versa. - -However, if a server or gateway discards or overrides any application -header for any reason, it **must** record this action in a log (such as -the ``wsgi.errors`` log) for the benefit of the application author. -(However, it **may** also give administrators the option of suppressing -such output, so that users who cannot fix a broken application are not -forced to bear the pain of its error.) +Applications and middleware are forbidden from using HTTP/1.1 +"hop-by-hop" features or headers, any equivalent features in HTTP/1.0, +or any headers that would affect the persistence of the client's +connection to the web server. These features are the +exclusive province of the actual web server, and a server or gateway +**should** consider it a fatal error for an application to attempt +using them, and raise an error if they are supplied to +``start_response()``. (For more specifics on "hop-by-hop" features and +headers, please see the `Other HTTP Features`_ section below.) The ``start_response`` callable **must not** actually transmit the HTTP headers. It must store them until the first ``write`` call that @@ -660,6 +656,12 @@ when doing this, or else fall back to one of the other strategies for dealing with the absence of ``Content-Length``. +(Note: applications and middleware **must not** apply any kind of +``Transfer-Encoding`` to their output, such as chunking or gzipping; +as "hop-by-hop" operations, these encodings are the province of the +actual web server/gateway. See `Other HTTP Features`_ below, for +more details.) + Buffering and Streaming ----------------------- @@ -1240,7 +1242,17 @@ a server should consider itself to be like an HTTP "proxy server", with the application being an HTTP "origin server". -Applying this principle to a variety of HTTP features, it should be +However, because WSGI servers and applications do not communicate via +HTTP, what RFC 2616 calls "hop-by-hop" headers do not apply to WSGI +internal communications. WSGI applications **must not** generate any +"hop-by-hop" headers [4]_, attempt to use HTTP features that would +require them to generate such headers, or rely on the content of +any incoming "hop-by-hop" headers in the ``environ`` dictionary. +WSGI servers **must** handle any supported inbound "hop-by-hop" headers +on their own, such as by decoding any inbound ``Transfer-Encoding``, +including chunked encoding if applicable. + +Applying these principles to a variety of HTTP features, it should be clear that a server **may** handle cache validation via the ``If-None-Match`` and ``If-Modified-Since`` request headers and the ``Last-Modified`` and ``ETag`` response headers. However, it is @@ -1250,11 +1262,11 @@ Similarly, a server **may** re-encode or transport-encode an application's response, but the application **should** use a -suitable encoding on its own. A server **may** use chunked -encoding or transmit byte ranges of the application's response -if requested by the client, and the application doesn't natively -support byte ranges. Again, however, the application **should** -perform this function on its own if desired. +suitable content encoding on its own, and **must not** apply a +transport encoding. A server **may** transmit byte ranges of the +application's response if requested by the client, and the +application doesn't natively support byte ranges. Again, however, +the application **should** perform this function on its own if desired. Note that these restrictions on applications do not necessarily mean that every application must reimplement every HTTP feature; many HTTP @@ -1444,9 +1456,12 @@ .. [2] The Common Gateway Interface Specification, v 1.1, 3rd Draft (http://cgi-spec.golux.com/draft-coar-cgi-v11-03.txt) -.. [3] Hypertext Transfer Protocol -- HTTP/1.1, section 3.6.1 +.. [3] "Chunked Transfer Coding" -- HTTP/1.1, section 3.6.1 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1) +.. [4] "End-to-end and Hop-by-hop Headers" -- HTTP/1.1, Section 13.5.1 + (http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1) + Copyright ========= From jafo at users.sourceforge.net Fri Sep 17 10:23:29 2004 From: jafo at users.sourceforge.net (jafo@users.sourceforge.net) Date: Fri Sep 17 10:23:32 2004 Subject: [Python-checkins] python/dist/src/Lib/distutils/command bdist_rpm.py, 1.43, 1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31481/dist/src/Lib/distutils/command Modified Files: bdist_rpm.py Log Message: SF Patch 1022003: Change bdist_rpm _topdir to use os.path.abspath(self.rpm_base) instead of os.getcwd() + '/' + self.rpm_base Index: bdist_rpm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/bdist_rpm.py,v retrieving revision 1.43 retrieving revision 1.44 diff -u -d -r1.43 -r1.44 --- bdist_rpm.py 12 Sep 2004 03:49:30 -0000 1.43 +++ bdist_rpm.py 17 Sep 2004 08:23:22 -0000 1.44 @@ -326,7 +326,7 @@ rpm_cmd.append('-ba') if self.rpm3_mode: rpm_cmd.extend(['--define', - '_topdir %s/%s' % (os.getcwd(), self.rpm_base),]) + '_topdir %s' % os.path.abspath(self.rpm_base)]) if not self.keep_temp: rpm_cmd.append('--clean') rpm_cmd.append(spec_path) From jafo at users.sourceforge.net Fri Sep 17 10:34:15 2004 From: jafo at users.sourceforge.net (jafo@users.sourceforge.net) Date: Fri Sep 17 10:34:19 2004 Subject: [Python-checkins] python/dist/src/Lib/distutils/command bdist_rpm.py, 1.44, 1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1423/dist/src/Lib/distutils/command Modified Files: bdist_rpm.py Log Message: SF Patch 1022011: Add a command-line argument --no-autoreq, which sets the "AutoReq: 0" to disable automatic dependency searching. Index: bdist_rpm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/bdist_rpm.py,v retrieving revision 1.44 retrieving revision 1.45 diff -u -d -r1.44 -r1.45 --- bdist_rpm.py 17 Sep 2004 08:23:22 -0000 1.44 +++ bdist_rpm.py 17 Sep 2004 08:34:12 -0000 1.45 @@ -81,6 +81,8 @@ "capabilities required to build this package"), ('obsoletes=', None, "capabilities made obsolete by this package"), + ('no-autoreq', None, + "do not automatically calculate dependencies"), # Actions to take when building RPM ('keep-temp', 'k', @@ -125,7 +127,8 @@ "Force an architecture onto the RPM build process"), ] - boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode'] + boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode', + 'no-autoreq'] negative_opt = {'no-keep-temp': 'keep-temp', 'no-rpm-opt-flags': 'use-rpm-opt-flags', @@ -172,6 +175,7 @@ self.keep_temp = 0 self.use_rpm_opt_flags = 1 self.rpm3_mode = 1 + self.no_autoreq = 0 self.force_arch = None @@ -429,6 +433,9 @@ if self.icon: spec_file.append('Icon: ' + os.path.basename(self.icon)) + if self.no_autoreq: + spec_file.append('AutoReq: 0') + spec_file.extend([ '', '%description', From pje at users.sourceforge.net Fri Sep 17 17:32:01 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Fri Sep 17 17:32:05 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20641 Modified Files: pep-0333.txt Log Message: Moved middleware introduction to "Specification Overview" section, adding a code example for a trivial middleware component. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- pep-0333.txt 16 Sep 2004 22:04:35 -0000 1.15 +++ pep-0333.txt 17 Sep 2004 15:31:58 -0000 1.16 @@ -125,6 +125,17 @@ mechanisms to specify where an application object should be imported from, or otherwise obtained. +In addition to "pure" servers/gateways and applications/frameworks, +it is also possible to create "middleware" components that implement +both sides of this specification. Such components act as an +application to their containing server, and as a server to a +contained application, and can be used to provide extended APIs, +content transformation, navigation, and other useful functions. + + +The Application/Framework Side +------------------------------ + The application object is simply a callable object that accepts two arguments. The term "object" should not be misconstrued as requiring an actual object instance: a function, method, class, @@ -184,6 +195,10 @@ callable was provided to it. Callables are only to be called, not introspected upon. + +The Server/Gateway Side +----------------------- + The server or gateway invokes the application callable once for each request it receives from an HTTP client, that is directed at the application. To illustrate, here is a simple CGI gateway, implemented @@ -254,8 +269,89 @@ if hasattr(result,'close'): result.close() -In the next section, we will specify the precise semantics that -these illustrations are examples of. + +Middleware: Components that Play Both Sides +------------------------------------------- + +Note that a single object may play the role of a server with respect +to some application(s), while also acting as an application with +respect to some server(s). Such "middleware" components can perform +such functions as: + +* Routing a request to different application objects based on the + target URL, after rewriting the ``environ`` accordingly. + +* Allowing multiple applications or frameworks to run side-by-side + in the same process + +* Load balancing and remote processing, by forwarding requests and + responses over a network + +* Perform content postprocessing, such as applying XSL stylesheets + +The presence of middleware in general is transparent to both the +"server/gateway" and the "application/framework" sides of the +interface, and should require no special support. A user who +desires to incorporate middleware into an application simply +provides the middleware component to the server, as if it were +an application, and configures the middleware component to +invoke the application, as if the middleware component were a +server. Of course, the "application" that the middleware wraps +may in fact be another middleware component wrapping another +application, and so on, creating what is referred to as a +"middleware stack". + +For the most part, middleware must conform to the restrictions +and requirements of both the server and application sides of +WSGI. In some cases, however, requirements for middleware +are more stringent than for a "pure" server or application, +and these points will be noted in the specification. + +Here is a (tongue-in-cheek) example of a middleware component that +converts ``text/plain`` responses to pig latin, using Joe Strout's +``piglatin.py``. (Note: a "real" middleware component would +probably use a more robust way of checking the content type, and +should also check for a content encoding.) + +:: + + from piglatin import piglatin + + class Latinator: + + # by default, don't transform output + transform = str + + def __init__(self, application): + self.application = application + + def __call__(environ, start_response): + + def write_latin(data): + self.write(self.transform(data)) + + def start_latin(status,headers,exc_info=None): + + for name,value in headers: + if name.lower()=='content-type' and value=='text/plain': + self.transform = piglatin + # Strip content-length if present, else it'll be wrong + headers = [(name,value) + for name,value in headers + if name.lower()<>'content-length' + ] + break + + self.write = start_response(status,headers,exc_info) + return write_latin + + for data in self.application(environ,start_latin): + yield self.transform(data) + + # Run foo_app under a Latinator's control, using the example CGI gateway + from foo_app import foo_app + run_with_cgi(Latinator(foo_app)) + Specification Details @@ -851,6 +947,8 @@ start_response(status, headers) return ["normal body goes here"] except: + # XXX should trap runtime issues like MemoryError, KeyboardInterrupt + # in a separate handler before this bare 'except:'... status = "500 Oops" headers = [("content-type","text/plain")] start_response(status, headers, sys.exc_info()) @@ -976,30 +1074,6 @@ to re-read it upon each invocation.) -Middleware ----------- - -Note that a single object may play the role of a server with respect -to some application(s), while also acting as an application with -respect to some server(s). Such "middleware" components can perform -such functions as: - -* Routing a request to different application objects based on the - target URL, after rewriting the ``environ`` accordingly. - -* Allowing multiple applications or frameworks to run side-by-side - in the same process - -* Load balancing and remote processing, by forwarding requests and - responses over a network - -* Perform content postprocessing, such as applying XSL stylesheets - -Given the existence of applications and servers conforming to this -specification, the appearance of such reusable middleware becomes -a possibility. - - Supporting Older (<2.2) Versions of Python ------------------------------------------ From pje at users.sourceforge.net Fri Sep 17 18:32:24 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Fri Sep 17 18:32:27 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1269 Modified Files: pep-0333.txt Log Message: Fixed middleware example not handling 'close' correctly. Fixed an erroneous statement re: calling 'write()' with empty strings. Moved "Multiple Invocations" note into overview, and moved "callable" definition to overview's preface. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- pep-0333.txt 17 Sep 2004 15:31:58 -0000 1.16 +++ pep-0333.txt 17 Sep 2004 16:32:17 -0000 1.17 @@ -132,6 +132,15 @@ contained application, and can be used to provide extended APIs, content transformation, navigation, and other useful functions. +Throughout this specification, we will use the term "a callable" to +mean "a function, method, class, or an instance with a ``__call__`` +method". It is up to the server, gateway, or application implementing +the callable to choose the appropriate implementation technique for +their needs. Conversely, a server, gateway, or application that is +invoking a callable **must not** have any dependency on what kind of +callable was provided to it. Callables are only to be called, not +introspected upon. + The Application/Framework Side ------------------------------ @@ -140,7 +149,9 @@ two arguments. The term "object" should not be misconstrued as requiring an actual object instance: a function, method, class, or instance with a ``__call__`` method are all acceptable for -use as an application object. +use as an application object. Application objects must be able +to be invoked more than once, as virtually all servers/gateways +(other than CGI) will make such repeated requests. (Note: although we refer to it as an "application" object, this should not be construed to mean that application developers will use @@ -186,15 +197,6 @@ self.start(status, headers) yield "Hello world!\n" -Throughout this specification, we will use the term "a callable" to -mean "a function, method, class, or an instance with a ``__call__`` -method". It is up to the server, gateway, or application implementing -the callable to choose the appropriate implementation technique for -their needs. Conversely, a server, gateway, or application that is -invoking a callable must *not* have any dependency on what kind of -callable was provided to it. Callables are only to be called, not -introspected upon. - The Server/Gateway Side ----------------------- @@ -311,30 +313,54 @@ converts ``text/plain`` responses to pig latin, using Joe Strout's ``piglatin.py``. (Note: a "real" middleware component would probably use a more robust way of checking the content type, and -should also check for a content encoding.) +should also check for a content encoding. Also, this simple +example ignores the possibility that a word might be split across +a block boundary.) :: from piglatin import piglatin + class LatinIter: + + """Transform iterated output to piglatin, if it's okay to do so + + Note that the "okayness" can change until the application yields + its first non-empty string, so 'transform_ok' has to be a mutable + truth value.""" + + def __init__(self,result,transform_ok): + if hasattr(result,'close'): + self.close = result.close + self._next = iter(result).next + self.transform_ok = transform_ok + + def __iter__(self): + return self + + def next(self): + if self.transform_ok: + return piglatin(self._next()) + else: + return self._next() + class Latinator: # by default, don't transform output - transform = str + transform = False def __init__(self, application): self.application = application def __call__(environ, start_response): - - def write_latin(data): - self.write(self.transform(data)) - + + transform_ok = [] + def start_latin(status,headers,exc_info=None): for name,value in headers: if name.lower()=='content-type' and value=='text/plain': - self.transform = piglatin + transform_ok.append(True) # Strip content-length if present, else it'll be wrong headers = [(name,value) for name,value in headers @@ -342,11 +368,17 @@ ] break - self.write = start_response(status,headers,exc_info) - return write_latin + write = start_response(status,headers,exc_info) + + if transform_ok: + def write_latin(data): + write(piglatin(data)) + return write_latin + else: + return write + + return LatinIter(self.application(environ,start_latin),transform_ok) - for data in self.application(environ,start_latin): - yield self.transform(data) # Run foo_app under a Latinator's control, using the example CGI gateway from foo_app import foo_app @@ -672,12 +704,11 @@ headers, please see the `Other HTTP Features`_ section below.) The ``start_response`` callable **must not** actually transmit the -HTTP headers. It must store them until the first ``write`` call that -is passed a non-empty string, or until after the first iteration of -the application return value that yields a non-empty string. This is -to ensure that buffered and asynchronous applications can replace -their originally intended output with error output, up until the last -possible moment. +HTTP headers. It must store them until the first ``write`` call, or +until after the first iteration of the application return value that +yields a non-empty string. This is to ensure that buffered and +asynchronous applications can replace their originally intended output +with error output, up until the last possible moment. The ``exc_info`` argument, if supplied, must be a Python ``sys.exc_info()`` tuple. This argument should be supplied by the @@ -919,13 +950,6 @@ this specification as a "string". -Multiple Invocations --------------------- - -Application objects must be able to be invoked more than once, since -virtually all servers/gateways will make such requests. - - Error Handling -------------- From fdrake at users.sourceforge.net Fri Sep 17 22:23:50 2004 From: fdrake at users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri Sep 17 22:23:53 2004 Subject: [Python-checkins] python/dist/src/Doc Makefile,1.277,1.278 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14991 Modified Files: Makefile Log Message: remove gzipped archives from the list of expected distributions Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.277 retrieving revision 1.278 diff -u -d -r1.277 -r1.278 --- Makefile 18 Aug 2004 22:27:04 -0000 1.277 +++ Makefile 17 Sep 2004 20:23:47 -0000 1.278 @@ -675,11 +675,11 @@ bzips: bzippdf bzipps bziphtml -disthtml: tarhtml bziphtml ziphtml -distinfo: tarinfo bzipinfo -distps: tarps bzipps zipps -distpdf: tarpdf bzippdf zippdf -distlatex: tarlatex bziplatex ziplatex +disthtml: bziphtml ziphtml +distinfo: bzipinfo +distps: bzipps zipps +distpdf: bzippdf zippdf +distlatex: bziplatex ziplatex # We use the "pkglist" target at the end of these to ensure the # package list is updated after building either of these; this seems a From bwarsaw at users.sourceforge.net Sat Sep 18 02:06:37 2004 From: bwarsaw at users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sat Sep 18 02:06:40 2004 Subject: [Python-checkins] python/dist/src/Lib string.py,1.83,1.84 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22539 Modified Files: string.py Log Message: At the cost of a modest (but useful in its own right) change in the semantics of the Template.delimiter attribute, we make use of the delimiter in the escaped group, and in the safe_substitute() method more robust. Now, .delimiter should be the unescaped delimiter literal, e.g. '$' or '&', or whatever. The _TemplateMetaclass will re.escape() this value when it builds the pattern. Index: string.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/string.py,v retrieving revision 1.83 retrieving revision 1.84 diff -u -d -r1.83 -r1.84 --- string.py 16 Sep 2004 00:09:11 -0000 1.83 +++ string.py 18 Sep 2004 00:06:34 -0000 1.84 @@ -113,7 +113,7 @@ pattern = cls.pattern else: pattern = _TemplateMetaclass.pattern % { - 'delim' : cls.delimiter, + 'delim' : _re.escape(cls.delimiter), 'id' : cls.idpattern, } cls.pattern = _re.compile(pattern, _re.IGNORECASE | _re.VERBOSE) @@ -123,7 +123,7 @@ """A string class for supporting $-substitutions.""" __metaclass__ = _TemplateMetaclass - delimiter = r'\$' + delimiter = '$' idpattern = r'[_a-z][_a-z0-9]*' def __init__(self, template): @@ -152,7 +152,6 @@ mapping = _multimap(kws, args[0]) else: mapping = args[0] - delimiter = self.delimiter[-1] # Helper function for .sub() def convert(mo): # Check the most common path first. @@ -163,7 +162,7 @@ # fail if val is a Unicode containing non-ASCII characters. return '%s' % val if mo.group('escaped') is not None: - return delimiter + return self.delimiter if mo.group('invalid') is not None: self._invalid(mo) raise ValueError('Unrecognized named group in pattern', pattern) @@ -178,7 +177,6 @@ mapping = _multimap(kws, args[0]) else: mapping = args[0] - delimiter = self.delimiter[-1] # Helper function for .sub() def convert(mo): named = mo.group('named') @@ -188,15 +186,15 @@ # will fail if val is a Unicode containing non-ASCII return '%s' % mapping[named] except KeyError: - return delimiter + named + return self.delimiter + named braced = mo.group('braced') if braced is not None: try: return '%s' % mapping[braced] except KeyError: - return delimiter + '{' + braced + '}' + return self.delimiter + '{' + braced + '}' if mo.group('escaped') is not None: - return delimiter + return self.delimiter if mo.group('invalid') is not None: self._invalid(mo) raise ValueError('Unrecognized named group in pattern', pattern) From loewis at users.sourceforge.net Sat Sep 18 11:03:51 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 11:03:54 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libhttplib.tex,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10831/Doc/lib Modified Files: libhttplib.tex Log Message: Patch #1025790: Add status code constants to httplib. Index: libhttplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libhttplib.tex,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- libhttplib.tex 18 Aug 2004 12:46:25 -0000 1.37 +++ libhttplib.tex 18 Sep 2004 09:03:48 -0000 1.38 @@ -24,16 +24,6 @@ to the online docstrings for usage. \end{notice} -The constants defined in this module are: - -\begin{datadesc}{HTTP_PORT} - The default port for the HTTP protocol (always \code{80}). -\end{datadesc} - -\begin{datadesc}{HTTPS_PORT} - The default port for the HTTPS protocol (always \code{443}). -\end{datadesc} - The module provides the following classes: \begin{classdesc}{HTTPConnection}{host\optional{, port}} @@ -135,6 +125,168 @@ \versionadded{2.0} \end{excdesc} +The constants defined in this module are: + +\begin{datadesc}{HTTP_PORT} + The default port for the HTTP protocol (always \code{80}). +\end{datadesc} + +\begin{datadesc}{HTTPS_PORT} + The default port for the HTTPS protocol (always \code{443}). +\end{datadesc} + +and also the following constants for integer status codes: + +\begin{tableiii}{l|c|l}{constant}{Constant}{Value}{Definition} + \lineiii{CONTINUE}{\code{100}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.1.1} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1}} + \lineiii{SWITCHING_PROTOCOLS}{\code{101}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.1.2} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.2}} + \lineiii{PROCESSING}{\code{102}} + {WEBDAV, \ulink{RFC 2518, Section 10.1} + {http://www.webdav.org/specs/rfc2518.htm#STATUS_102}} + + \lineiii{OK}{\code{200}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.2.1} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1}} + \lineiii{CREATED}{\code{201}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.2.2} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2}} + \lineiii{ACCEPTED}{\code{202}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.2.3} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3}} + \lineiii{NON_AUTHORITATIVE_INFORMATION}{\code{203}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.2.4} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.4}} + \lineiii{NO_CONTENT}{\code{204}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.2.5} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5}} + \lineiii{RESET_CONTENT}{\code{205}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.2.6} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.6}} + \lineiii{PARTIAL_CONTENT}{\code{206}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.2.7} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7}} + \lineiii{MULTI_STATUS}{\code{207}} + {WEBDAV \ulink{RFC 2518, Section 10.2} + {http://www.webdav.org/specs/rfc2518.htm#STATUS_207}} + \lineiii{IM_USED}{\code{226}} + {Delta encoding in HTTP, \rfc{3229}, Section 10.4.1} + + \lineiii{MULTIPLE_CHOICES}{\code{300}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.3.1} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1}} + \lineiii{MOVED_PERMANENTLY}{\code{301}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.3.2} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2}} + \lineiii{FOUND}{\code{302}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.3.3} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3}} + \lineiii{SEE_OTHER}{\code{303}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.3.4} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4}} + \lineiii{NOT_MODIFIED}{\code{304}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.3.5} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5}} + \lineiii{USE_PROXY}{\code{305}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.3.6} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.6}} + \lineiii{TEMPORARY_REDIRECT}{\code{307}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.3.8} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8}} + + \lineiii{BAD_REQUEST}{\code{400}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.1} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1}} + \lineiii{UNAUTHORIZED}{\code{401}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.2} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2}} + \lineiii{PAYMENT_REQUIRED}{\code{402}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.3} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}} + \lineiii{FORBIDDEN}{\code{403}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.4} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4}} + \lineiii{NOT_FOUND}{\code{404}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.5} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5}} + \lineiii{METHOD_NOT_ALLOWED}{\code{405}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.6} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6}} + \lineiii{NOT_ACCEPTABLE}{\code{406}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.7} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7}} + \lineiii{PROXY_AUTHENTICATION_REQUIRED} + {\code{407}}{HTTP/1.1, \ulink{RFC 2616, Section 10.4.8} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8}} + \lineiii{REQUEST_TIMEOUT}{\code{408}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.9} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9}} + \lineiii{CONFLICT}{\code{409}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.10} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10}} + \lineiii{GONE}{\code{410}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.11} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11}} + \lineiii{LENGTH_REQUIRED}{\code{411}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.12} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.12}} + \lineiii{PRECONDITION_FAILED}{\code{412}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.13} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13}} + \lineiii{REQUEST_ENTITY_TOO_LARGE} + {\code{413}}{HTTP/1.1, \ulink{RFC 2616, Section 10.4.14} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14}} + \lineiii{REQUEST_URI_TOO_LONG}{\code{414}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.15} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15}} + \lineiii{UNSUPPORTED_MEDIA_TYPE}{\code{415}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.16} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16}} + \lineiii{REQUESTED_RANGE_NOT_SATISFIABLE}{\code{416}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.17} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.17}} + \lineiii{EXPECTATION_FAILED}{\code{417}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.4.18} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18}} + \lineiii{UNPROCESSABLE_ENTITY}{\code{422}} + {WEBDAV, \ulink{RFC 2518, Section 10.3} + {http://www.webdav.org/specs/rfc2518.htm#STATUS_422}} + \lineiii{LOCKED}{\code{423}} + {WEBDAV \ulink{RFC 2518, Section 10.4} + {http://www.webdav.org/specs/rfc2518.htm#STATUS_423}} + \lineiii{FAILED_DEPENDENCY}{\code{424}} + {WEBDAV, \ulink{RFC 2518, Section 10.5} + {http://www.webdav.org/specs/rfc2518.htm#STATUS_424}} + \lineiii{UPGRADE_REQUIRED}{\code{426}} + {HTTP Upgrade to TLS, \rfc{2817}, Section 6} + + \lineiii{INTERNAL_SERVER_ERROR}{\code{500}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.5.1} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1}} + \lineiii{NOT_IMPLEMENTED}{\code{501}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.5.2} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2}} + \lineiii{BAD_GATEWAY}{\code{502}} + {HTTP/1.1 \ulink{RFC 2616, Section 10.5.3} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3}} + \lineiii{SERVICE_UNAVAILABLE}{\code{503}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.5.4} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4}} + \lineiii{GATEWAY_TIMEOUT}{\code{504}} + {HTTP/1.1 \ulink{RFC 2616, Section 10.5.5} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.5}} + \lineiii{HTTP_VERSION_NOT_SUPPORTED}{\code{505}} + {HTTP/1.1, \ulink{RFC 2616, Section 10.5.6} + {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.6}} + \lineiii{INSUFFICIENT_STORAGE}{\code{507}} + {WEBDAV, \ulink{RFC 2518, Section 10.6} + {http://www.webdav.org/specs/rfc2518.htm#STATUS_507}} + \lineiii{NOT_EXTENDED}{\code{510}} + {An HTTP Extension Framework, \rfc{2774}, Section 7} +\end{tableiii} \subsection{HTTPConnection Objects \label{httpconnection-objects}} From loewis at users.sourceforge.net Sat Sep 18 11:03:51 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 11:03:55 2004 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.91,1.92 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10831/Lib Modified Files: httplib.py Log Message: Patch #1025790: Add status code constants to httplib. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.91 retrieving revision 1.92 diff -u -d -r1.91 -r1.92 --- httplib.py 15 Sep 2004 23:26:22 -0000 1.91 +++ httplib.py 18 Sep 2004 09:03:49 -0000 1.92 @@ -93,6 +93,66 @@ _CS_REQ_STARTED = 'Request-started' _CS_REQ_SENT = 'Request-sent' +# status codes +# informational +CONTINUE = 100 +SWITCHING_PROTOCOLS = 101 +PROCESSING = 102 + +# successful +OK = 200 +CREATED = 201 +ACCEPTED = 202 +NON_AUTHORITATIVE_INFORMATION = 203 +NO_CONTENT = 204 +RESET_CONTENT = 205 +PARTIAL_CONTENT = 206 +MULTI_STATUS = 207 +IM_USED = 226 + +# redirection +MULTIPLE_CHOICES = 300 +MOVED_PERMANENTLY = 301 +FOUND = 302 +SEE_OTHER = 303 +NOT_MODIFIED = 304 +USE_PROXY = 305 +TEMPORARY_REDIRECT = 307 + +# client error +BAD_REQUEST = 400 +UNAUTHORIZED = 401 +PAYMENT_REQUIRED = 402 +FORBIDDEN = 403 +NOT_FOUND = 404 +METHOD_NOT_ALLOWED = 405 +NOT_ACCEPTABLE = 406 +PROXY_AUTHENTICATION_REQUIRED = 407 +REQUEST_TIMEOUT = 408 +CONFLICT = 409 +GONE = 410 +LENGTH_REQUIRED = 411 +PRECONDITION_FAILED = 412 +REQUEST_ENTITY_TOO_LARGE = 413 +REQUEST_URI_TOO_LONG = 414 +UNSUPPORTED_MEDIA_TYPE = 415 +REQUESTED_RANGE_NOT_SATISFIABLE = 416 +EXPECTATION_FAILED = 417 +UNPROCESSABLE_ENTITY = 422 +LOCKED = 423 +FAILED_DEPENDENCY = 424 +UPGRADE_REQUIRED = 426 + +# server error +INTERNAL_SERVER_ERROR = 500 +NOT_IMPLEMENTED = 501 +BAD_GATEWAY = 502 +SERVICE_UNAVAILABLE = 503 +GATEWAY_TIMEOUT = 504 +HTTP_VERSION_NOT_SUPPORTED = 505 +INSUFFICIENT_STORAGE = 507 +NOT_EXTENDED = 510 + class HTTPMessage(mimetools.Message): def addheader(self, key, value): @@ -271,7 +331,7 @@ # read until we get a non-100 response while True: version, status, reason = self._read_status() - if status != 100: + if status != CONTINUE: break # skip the header from the 100 response while True: @@ -329,8 +389,7 @@ self.length = None # does the body have a fixed length? (of zero) - if (status == 204 or # No Content - status == 304 or # Not Modified + if (status == NO_CONTENT or status == NOT_MODIFIED or 100 <= status < 200 or # 1xx codes self._method == 'HEAD'): self.length = 0 From loewis at users.sourceforge.net Sat Sep 18 11:03:53 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 11:03:58 2004 Subject: [Python-checkins] python/dist/src/Misc ACKS, 1.282, 1.283 NEWS, 1.1135, 1.1136 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10831/Misc Modified Files: ACKS NEWS Log Message: Patch #1025790: Add status code constants to httplib. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.282 retrieving revision 1.283 diff -u -d -r1.282 -r1.283 --- ACKS 10 Sep 2004 06:32:54 -0000 1.282 +++ ACKS 18 Sep 2004 09:03:49 -0000 1.283 @@ -161,6 +161,7 @@ Maxim Dzumanenko Hans Eckardt Grant Edwards +Andrew Eland Lance Ellinghaus David Ely Jeff Epler Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1135 retrieving revision 1.1136 diff -u -d -r1.1135 -r1.1136 --- NEWS 16 Sep 2004 01:30:48 -0000 1.1135 +++ NEWS 18 Sep 2004 09:03:49 -0000 1.1136 @@ -22,6 +22,8 @@ Library ------- +- httplib now offers symbolic constants for the HTTP status codes. + - SF bug #1028306: Trying to compare a ``datetime.date`` to a ``datetime.datetime`` mistakenly compared only the year, month and day. Now it acts like a mixed-type comparison: ``False`` for ``==``, From loewis at users.sourceforge.net Sat Sep 18 11:08:55 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 11:08:58 2004 Subject: [Python-checkins] python/dist/src/Lib tarfile.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11703/Lib Modified Files: tarfile.py Log Message: Patch #1029061: Always extract member names from the tarinfo. Index: tarfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tarfile.py,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- tarfile.py 25 Aug 2004 10:52:58 -0000 1.19 +++ tarfile.py 18 Sep 2004 09:08:50 -0000 1.20 @@ -814,7 +814,6 @@ # Init datastructures self.closed = False self.members = [] # list of members as TarInfo objects - self.membernames = [] # names of members self._loaded = False # flag if all members have been read self.offset = 0L # current position in the archive file self.inodes = {} # dictionary caching the inodes of @@ -1034,12 +1033,10 @@ than once in the archive, its last occurence is assumed to be the most up-to-date version. """ - self._check() - if name not in self.membernames and not self._loaded: - self._load() - if name not in self.membernames: + tarinfo = self._getmember(name) + if tarinfo is None: raise KeyError, "filename %r not found" % name - return self._getmember(name) + return tarinfo def getmembers(self): """Return the members of the archive as a list of TarInfo objects. The @@ -1055,10 +1052,7 @@ """Return the members of the archive as a list of their names. It has the same order as the list returned by getmembers(). """ - self._check() - if not self._loaded: - self._load() - return self.membernames + return [tarinfo.name for tarinfo in self.getmembers()] def gettarinfo(self, name=None, arcname=None, fileobj=None): """Create a TarInfo object for either the file `name' or the file @@ -1307,7 +1301,7 @@ blocks += 1 self.offset += blocks * BLOCKSIZE - self._record_member(tarinfo) + self.members.append(tarinfo) def extract(self, member, path=""): """Extract a member from the archive to the current working directory, @@ -1632,7 +1626,7 @@ # some old tar programs don't know DIRTYPE tarinfo.type = DIRTYPE - self._record_member(tarinfo) + self.members.append(tarinfo) return tarinfo #-------------------------------------------------------------------------- @@ -1647,8 +1641,8 @@ # if there is data to follow. # 2. set self.offset to the position where the next member's header will # begin. - # 3. call self._record_member() if the tarinfo object is supposed to - # appear as a member of the TarFile object. + # 3. append the tarinfo object to self.members, if it is supposed to appear + # as a member of the TarFile object. # 4. return tarinfo or another valid TarInfo object. def proc_gnulong(self, tarinfo): @@ -1729,7 +1723,7 @@ self.offset += self._block(tarinfo.size) tarinfo.size = origsize - self._record_member(tarinfo) + self.members.append(tarinfo) return tarinfo # The type mapping for the next() method. The keys are single character @@ -1757,20 +1751,17 @@ """Find an archive member by name from bottom to top. If tarinfo is given, it is used as the starting point. """ + # Ensure that all members have been loaded. + members = self.getmembers() + if tarinfo is None: - end = len(self.members) + end = len(members) else: - end = self.members.index(tarinfo) + end = members.index(tarinfo) for i in xrange(end - 1, -1, -1): - if name == self.membernames[i]: - return self.members[i] - - def _record_member(self, tarinfo): - """Record a tarinfo object in the internal datastructures. - """ - self.members.append(tarinfo) - self.membernames.append(tarinfo.name) + if name == members[i].name: + return members[i] def _load(self): """Read through the entire archive file and look for readable From loewis at users.sourceforge.net Sat Sep 18 11:08:56 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 11:08:59 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1136,1.1137 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11703/Misc Modified Files: NEWS Log Message: Patch #1029061: Always extract member names from the tarinfo. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1136 retrieving revision 1.1137 diff -u -d -r1.1136 -r1.1137 --- NEWS 18 Sep 2004 09:03:49 -0000 1.1136 +++ NEWS 18 Sep 2004 09:08:52 -0000 1.1137 @@ -22,6 +22,9 @@ Library ------- +- The (undocumented) tarfile.Tarfile.membernames has been removed; + applications should use the getmember function. + - httplib now offers symbolic constants for the HTTP status codes. - SF bug #1028306: Trying to compare a ``datetime.date`` to a From loewis at users.sourceforge.net Sat Sep 18 11:54:55 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 11:54:58 2004 Subject: [Python-checkins] python/dist/src configure, 1.456, 1.457 configure.in, 1.469, 1.470 pyconfig.h.in, 1.103, 1.104 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18352 Modified Files: configure configure.in pyconfig.h.in Log Message: Patch #1012280: Include curses.h for term.h check. Fixes #933795. Will backport to 2.3. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.456 retrieving revision 1.457 diff -u -d -r1.456 -r1.457 --- configure 15 Sep 2004 06:02:47 -0000 1.456 +++ configure 18 Sep 2004 09:54:48 -0000 1.457 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.468 . +# From configure.in Revision: 1.469 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for python 2.4. # @@ -4532,13 +4532,13 @@ -for ac_header in dlfcn.h fcntl.h grp.h langinfo.h \ +for ac_header in curses.h dlfcn.h fcntl.h grp.h langinfo.h \ libintl.h ncurses.h poll.h pthread.h \ stropts.h termios.h thread.h \ unistd.h utime.h \ sys/audioio.h sys/bsdtty.h sys/file.h sys/lock.h sys/mkdev.h sys/modem.h \ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ -sys/un.h sys/utsname.h sys/wait.h pty.h term.h libutil.h \ +sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ bluetooth/bluetooth.h do @@ -5374,6 +5374,69 @@ fi +# On Solaris, term.h requires curses.h + +for ac_header in term.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + # checks for typedefs was_it_defined=no echo "$as_me:$LINENO: checking for clock_t in time.h" >&5 Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.469 retrieving revision 1.470 diff -u -d -r1.469 -r1.470 --- configure.in 15 Sep 2004 06:02:53 -0000 1.469 +++ configure.in 18 Sep 2004 09:54:52 -0000 1.470 @@ -955,18 +955,21 @@ # checks for header files AC_HEADER_STDC -AC_CHECK_HEADERS(dlfcn.h fcntl.h grp.h langinfo.h \ +AC_CHECK_HEADERS(curses.h dlfcn.h fcntl.h grp.h langinfo.h \ libintl.h ncurses.h poll.h pthread.h \ stropts.h termios.h thread.h \ unistd.h utime.h \ sys/audioio.h sys/bsdtty.h sys/file.h sys/lock.h sys/mkdev.h sys/modem.h \ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ -sys/un.h sys/utsname.h sys/wait.h pty.h term.h libutil.h \ +sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ bluetooth/bluetooth.h) AC_HEADER_DIRENT AC_HEADER_MAJOR +# On Solaris, term.h requires curses.h +AC_CHECK_HEADERS(term.h,,,[#include ]) + # checks for typedefs was_it_defined=no AC_MSG_CHECKING(for clock_t in time.h) Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.103 retrieving revision 1.104 diff -u -d -r1.103 -r1.104 --- pyconfig.h.in 12 Aug 2004 13:45:08 -0000 1.103 +++ pyconfig.h.in 18 Sep 2004 09:54:52 -0000 1.104 @@ -76,6 +76,9 @@ /* Define if you have the 'ctermid_r' function. */ #undef HAVE_CTERMID_R +/* Define to 1 if you have the header file. */ +#undef HAVE_CURSES_H + /* Define to 1 if you have the device macros. */ #undef HAVE_DEVICE_MACROS From loewis at users.sourceforge.net Sat Sep 18 11:58:46 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 11:58:49 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS, 1.831.4.149, 1.831.4.150 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18977/Misc Modified Files: Tag: release23-maint NEWS Log Message: Patch #1012280: Include curses.h for term.h check. Fixes #933795. Update to autoconf 2.59. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.831.4.149 retrieving revision 1.831.4.150 diff -u -d -r1.831.4.149 -r1.831.4.150 --- NEWS 29 Aug 2004 16:45:13 -0000 1.831.4.149 +++ NEWS 18 Sep 2004 09:58:41 -0000 1.831.4.150 @@ -28,6 +28,8 @@ Extension modules ----------------- +- Patch #1012280: Fix term.h compilation problems on Solaris. + - Patch #914291: Set locale while getting a line from readline. - Bug #1005308: Define _BSD_TYPES. From loewis at users.sourceforge.net Sat Sep 18 11:58:48 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 11:58:53 2004 Subject: [Python-checkins] python/dist/src configure, 1.416.4.15, 1.416.4.16 configure.in, 1.427.4.14, 1.427.4.15 pyconfig.h.in, 1.83.4.5, 1.83.4.6 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18977 Modified Files: Tag: release23-maint configure configure.in pyconfig.h.in Log Message: Patch #1012280: Include curses.h for term.h check. Fixes #933795. Update to autoconf 2.59. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.416.4.15 retrieving revision 1.416.4.16 diff -u -d -r1.416.4.15 -r1.416.4.16 --- configure 12 Aug 2004 13:44:25 -0000 1.416.4.15 +++ configure 18 Sep 2004 09:58:37 -0000 1.416.4.16 @@ -1,10 +1,9 @@ #! /bin/sh -# From configure.in Revision: 1.427.4.13 . +# From configure.in Revision: 1.427.4.14 . # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.57 for python 2.3. +# Generated by GNU Autoconf 2.59 for python 2.3. # -# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. +# Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation [...10537 lines suppressed...] + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } @@ -19972,10 +21895,10 @@ as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.427.4.14 retrieving revision 1.427.4.15 diff -u -d -r1.427.4.14 -r1.427.4.15 --- configure.in 12 Aug 2004 13:44:44 -0000 1.427.4.14 +++ configure.in 18 Sep 2004 09:58:40 -0000 1.427.4.15 @@ -925,17 +925,20 @@ # checks for header files AC_HEADER_STDC -AC_CHECK_HEADERS(dlfcn.h fcntl.h grp.h limits.h langinfo.h \ +AC_CHECK_HEADERS(curses.h dlfcn.h fcntl.h grp.h limits.h langinfo.h \ libintl.h locale.h ncurses.h poll.h pthread.h \ signal.h stdarg.h stddef.h stdlib.h stropts.h termios.h thread.h \ unistd.h utime.h \ sys/audioio.h sys/bsdtty.h sys/file.h sys/lock.h sys/mkdev.h sys/modem.h \ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ -sys/un.h sys/utsname.h sys/wait.h pty.h term.h libutil.h \ +sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ sys/resource.h netpacket/packet.h sysexits.h) AC_HEADER_DIRENT AC_HEADER_MAJOR +# On Solaris, term.h requires curses.h +AC_CHECK_HEADERS(term.h,,,[#include ]) + # checks for typedefs was_it_defined=no AC_MSG_CHECKING(for clock_t in time.h) Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.83.4.5 retrieving revision 1.83.4.6 diff -u -d -r1.83.4.5 -r1.83.4.6 --- pyconfig.h.in 12 Aug 2004 13:44:44 -0000 1.83.4.5 +++ pyconfig.h.in 18 Sep 2004 09:58:40 -0000 1.83.4.6 @@ -71,6 +71,9 @@ /* Define if you have the 'ctermid_r' function. */ #undef HAVE_CTERMID_R +/* Define to 1 if you have the header file. */ +#undef HAVE_CURSES_H + /* Define to 1 if you have the device macros. */ #undef HAVE_DEVICE_MACROS From loewis at users.sourceforge.net Sat Sep 18 12:06:42 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 12:06:47 2004 Subject: [Python-checkins] python/dist/src configure, 1.416.4.16, 1.416.4.17 configure.in, 1.427.4.15, 1.427.4.16 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20069 Modified Files: Tag: release23-maint configure configure.in Log Message: Make curses.h inclusion conditional as in the original patch #1012280. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.416.4.16 retrieving revision 1.416.4.17 diff -u -d -r1.416.4.16 -r1.416.4.17 --- configure 18 Sep 2004 09:58:37 -0000 1.416.4.16 +++ configure 18 Sep 2004 10:06:26 -0000 1.416.4.17 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.427.4.14 . +# From configure.in Revision: 1.427.4.15 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for python 2.3. # @@ -5641,13 +5641,9 @@ # On Solaris, term.h requires curses.h - -for ac_header in term.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +echo "$as_me:$LINENO: checking for term.h" >&5 +echo $ECHO_N "checking for term.h... $ECHO_C" >&6 +if test "${ac_cv_header_term_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -5656,9 +5652,13 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +#ifdef HAVE_CURSES_H #include +#endif -#include <$ac_header> + +#include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 @@ -5682,25 +5682,18 @@ ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" + ac_cv_header_term_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_Header=no" +ac_cv_header_term_h=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi +echo "$as_me:$LINENO: result: $ac_cv_header_term_h" >&5 +echo "${ECHO_T}$ac_cv_header_term_h" >&6 -done # checks for typedefs Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.427.4.15 retrieving revision 1.427.4.16 diff -u -d -r1.427.4.15 -r1.427.4.16 --- configure.in 18 Sep 2004 09:58:40 -0000 1.427.4.15 +++ configure.in 18 Sep 2004 10:06:32 -0000 1.427.4.16 @@ -937,7 +937,11 @@ AC_HEADER_MAJOR # On Solaris, term.h requires curses.h -AC_CHECK_HEADERS(term.h,,,[#include ]) +AC_CHECK_HEADER(term.h,,,[ +#ifdef HAVE_CURSES_H +#include +#endif +]) # checks for typedefs was_it_defined=no From loewis at users.sourceforge.net Sat Sep 18 12:07:06 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 12:07:08 2004 Subject: [Python-checkins] python/dist/src configure, 1.457, 1.458 configure.in, 1.470, 1.471 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20187 Modified Files: configure configure.in Log Message: Make curses.h inclusion conditional as in the original patch #1012280. Backported to 2.3. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.457 retrieving revision 1.458 diff -u -d -r1.457 -r1.458 --- configure 18 Sep 2004 09:54:48 -0000 1.457 +++ configure 18 Sep 2004 10:07:02 -0000 1.458 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.469 . +# From configure.in Revision: 1.470 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for python 2.4. # @@ -5375,13 +5375,9 @@ # On Solaris, term.h requires curses.h - -for ac_header in term.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then +echo "$as_me:$LINENO: checking for term.h" >&5 +echo $ECHO_N "checking for term.h... $ECHO_C" >&6 +if test "${ac_cv_header_term_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -5390,9 +5386,13 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +#ifdef HAVE_CURSES_H #include +#endif -#include <$ac_header> + +#include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 @@ -5416,25 +5416,18 @@ ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" + ac_cv_header_term_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -eval "$as_ac_Header=no" +ac_cv_header_term_h=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi +echo "$as_me:$LINENO: result: $ac_cv_header_term_h" >&5 +echo "${ECHO_T}$ac_cv_header_term_h" >&6 -done # checks for typedefs Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.470 retrieving revision 1.471 diff -u -d -r1.470 -r1.471 --- configure.in 18 Sep 2004 09:54:52 -0000 1.470 +++ configure.in 18 Sep 2004 10:07:03 -0000 1.471 @@ -968,7 +968,11 @@ AC_HEADER_MAJOR # On Solaris, term.h requires curses.h -AC_CHECK_HEADERS(term.h,,,[#include ]) +AC_CHECK_HEADER(term.h,,,[ +#ifdef HAVE_CURSES_H +#include +#endif +]) # checks for typedefs was_it_defined=no From loewis at users.sourceforge.net Sat Sep 18 17:30:59 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 17:31:08 2004 Subject: [Python-checkins] python/nondist/sandbox/rational Rational.py, 1.2, 1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/rational In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14545 Modified Files: Rational.py Log Message: untabify. Index: Rational.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/rational/Rational.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- Rational.py 25 Nov 2003 21:20:42 -0000 1.2 +++ Rational.py 18 Sep 2004 15:30:57 -0000 1.3 @@ -131,311 +131,311 @@ ''' def _gcd(a, b): - if a>b: - b, a = a, b - if a == 0: - return b - while 1: - c = b % a - if c == 0: - return a - b = a - a = c + if a>b: + b, a = a, b + if a == 0: + return b + while 1: + c = b % a + if c == 0: + return a + b = a + a = c def _trim(n, d, max_d): - if max_d == 1: - return n/d, 1 - last_n, last_d = 0, 1 - current_n, current_d = 1, 0 - while 1: - div, mod = divmod(n, d) - n, d = d, mod - before_last_n, before_last_d = last_n, last_d - next_n = last_n + current_n*div - next_d = last_d + current_d*div - last_n, last_d = current_n, current_d - current_n, current_d = next_n, next_d - if mod == 0 or current_d>=max_d: - break - if current_d == max_d: - return current_n, current_d - i = (max_d-before_last_d)/last_d - alternative_n = before_last_n + i*last_n - alternative_d = before_last_d + i*last_d + if max_d == 1: + return n/d, 1 + last_n, last_d = 0, 1 + current_n, current_d = 1, 0 + while 1: + div, mod = divmod(n, d) + n, d = d, mod + before_last_n, before_last_d = last_n, last_d + next_n = last_n + current_n*div + next_d = last_d + current_d*div + last_n, last_d = current_n, current_d + current_n, current_d = next_n, next_d + if mod == 0 or current_d>=max_d: + break + if current_d == max_d: + return current_n, current_d + i = (max_d-before_last_d)/last_d + alternative_n = before_last_n + i*last_n + alternative_d = before_last_d + i*last_d alternative = _Rational(alternative_n, alternative_d) last = _Rational(last_n, last_d) - num = _Rational(n, d) - if abs(alternative-num) (top, bot), a pair of co-prime longs s.t. x = top/bot. + """\ + x -> (top, bot), a pair of co-prime longs s.t. x = top/bot. - The conversion is done exactly, without rounding. - bot > 0 guaranteed. - Some form of binary fp is assumed. - Pass NaNs or infinities at your own risk. + The conversion is done exactly, without rounding. + bot > 0 guaranteed. + Some form of binary fp is assumed. + Pass NaNs or infinities at your own risk. - >>> rational(10.0) - rational(10L, 1L) - >>> rational(0.0) - rational(0L) - >>> rational(-.25) - rational(-1L, 4L) - """ + >>> rational(10.0) + rational(10L, 1L) + >>> rational(0.0) + rational(0L) + >>> rational(-.25) + rational(-1L, 4L) + """ - if x == 0: - return 0L, 1L - signbit = 0 - if x < 0: - x = -x - signbit = 1 - f, e = _math.frexp(x) - assert 0.5 <= f < 1.0 - # x = f * 2**e exactly + if x == 0: + return 0L, 1L + signbit = 0 + if x < 0: + x = -x + signbit = 1 + f, e = _math.frexp(x) + assert 0.5 <= f < 1.0 + # x = f * 2**e exactly - # Suck up CHUNK bits at a time; 28 is enough so that we suck - # up all bits in 2 iterations for all known binary double- - # precision formats, and small enough to fit in an int. - CHUNK = 28 - top = 0L - # invariant: x = (top + f) * 2**e exactly - while f: - f = _math.ldexp(f, CHUNK) - digit = int(f) - assert digit >> CHUNK == 0 - top = (top << CHUNK) | digit - f = f - digit - assert 0.0 <= f < 1.0 - e = e - CHUNK - assert top + # Suck up CHUNK bits at a time; 28 is enough so that we suck + # up all bits in 2 iterations for all known binary double- + # precision formats, and small enough to fit in an int. + CHUNK = 28 + top = 0L + # invariant: x = (top + f) * 2**e exactly + while f: + f = _math.ldexp(f, CHUNK) + digit = int(f) + assert digit >> CHUNK == 0 + top = (top << CHUNK) | digit + f = f - digit + assert 0.0 <= f < 1.0 + e = e - CHUNK + assert top - # now x = top * 2**e exactly; fold in 2**e - r = _Rational(top, 1) - if e>0: - r = r << e - else: - r = r >> -e - if signbit: - return -r - else: - return r + # now x = top * 2**e exactly; fold in 2**e + r = _Rational(top, 1) + if e>0: + r = r << e + else: + r = r >> -e + if signbit: + return -r + else: + return r class _Rational: - def __init__(self, n, d): - if d == 0: - return n/d - n, d = map(long, (n, d)) - if d < 0: - n *= -1 - d *= -1 - f = _gcd(abs(n), d) - self.n = n/f - self.d = d/f + def __init__(self, n, d): + if d == 0: + return n/d + n, d = map(long, (n, d)) + if d < 0: + n *= -1 + d *= -1 + f = _gcd(abs(n), d) + self.n = n/f + self.d = d/f - def __repr__(self): - if self.d == 1: - return 'rational(%r)' % self.n - return 'rational(%(n)r, %(d)r)' % self.__dict__ + def __repr__(self): + if self.d == 1: + return 'rational(%r)' % self.n + return 'rational(%(n)r, %(d)r)' % self.__dict__ - def __str__(self): - if self.d == 1: - return str(self.n) - return '%(n)s/%(d)s' % self.__dict__ + def __str__(self): + if self.d == 1: + return str(self.n) + return '%(n)s/%(d)s' % self.__dict__ - def __coerce__(self, other): - for int in (type(1), type(1L)): - if isinstance(other, int): - return self, rational(other) - if type(other) == type(1.0): - return float(self), other - return NotImplemented + def __coerce__(self, other): + for int in (type(1), type(1L)): + if isinstance(other, int): + return self, rational(other) + if type(other) == type(1.0): + return float(self), other + return NotImplemented - def __rcoerce__(self, other): - return coerce(self, other) + def __rcoerce__(self, other): + return coerce(self, other) - def __add__(self, other): - return _Rational(self.n*other.d + other.n*self.d, - self.d*other.d) + def __add__(self, other): + return _Rational(self.n*other.d + other.n*self.d, + self.d*other.d) - def __radd__(self, other): - return self+other + def __radd__(self, other): + return self+other - def __mul__(self, other): - return _Rational(self.n*other.n, self.d*other.d) + def __mul__(self, other): + return _Rational(self.n*other.n, self.d*other.d) - def __rmul__(self, other): - return self*other + def __rmul__(self, other): + return self*other - def inv(self): - return _Rational(self.d, self.n) + def inv(self): + return _Rational(self.d, self.n) - def __div__(self, other): - return self*other.inv() + def __div__(self, other): + return self*other.inv() - def __rdiv__(self, other): - return self.inv()*other + def __rdiv__(self, other): + return self.inv()*other - def __neg__(self): - return _Rational(-self.n, self.d) + def __neg__(self): + return _Rational(-self.n, self.d) - def __sub__(self, other): - return self+(-other) + def __sub__(self, other): + return self+(-other) - def __rsub__(self, other): - return (-self)+other + def __rsub__(self, other): + return (-self)+other - def __long__(self): - if self.d != 1: - raise ValueError('cannot convert non-integer') - return self.n + def __long__(self): + if self.d != 1: + raise ValueError('cannot convert non-integer') + return self.n - def __int__(self): - return int(long(self)) + def __int__(self): + return int(long(self)) - def __float__(self): - # Avoid NaNs like the plague - if self.d > 1L<<1023: - self = self.trim(1L<<1023) - return float(self.n)/float(self.d) + def __float__(self): + # Avoid NaNs like the plague + if self.d > 1L<<1023: + self = self.trim(1L<<1023) + return float(self.n)/float(self.d) - def __pow__(self, exp, z=None): - if z is not None: - raise TypeError('pow with 3 args unsupported') - if isinstance(exp, _Rational): - if exp.d == 1: - exp = exp.n - if isinstance(exp, type(1)) or isinstance(exp, type(1L)): - if exp < 0: - return _Rational(self.d**-exp, self.n**-exp) - return _Rational(self.n**exp, self.d**exp) - return float(self)**exp + def __pow__(self, exp, z=None): + if z is not None: + raise TypeError('pow with 3 args unsupported') + if isinstance(exp, _Rational): + if exp.d == 1: + exp = exp.n + if isinstance(exp, type(1)) or isinstance(exp, type(1L)): + if exp < 0: + return _Rational(self.d**-exp, self.n**-exp) + return _Rational(self.n**exp, self.d**exp) + return float(self)**exp - def __cmp__(self, other): - return cmp(self.n*other.d, self.d*other.n) + def __cmp__(self, other): + return cmp(self.n*other.d, self.d*other.n) - def __hash__(self): - return hash(self.n)^hash(self.d) + def __hash__(self): + return hash(self.n)^hash(self.d) - def __abs__(self): - return _Rational(abs(self.n), self.d) + def __abs__(self): + return _Rational(abs(self.n), self.d) - def __complex__(self): - return complex(float(self)) + def __complex__(self): + return complex(float(self)) - def __nonzero__(self): - return self.n != 0 + def __nonzero__(self): + return self.n != 0 - def __pos__(self): - return self + def __pos__(self): + return self - def __oct__(self): - return '%s/%s' % (oct(self.n), oct(self.d)) + def __oct__(self): + return '%s/%s' % (oct(self.n), oct(self.d)) - def __hex__(self): - return '%s/%s' % (hex(self.n), hex(self.d)) + def __hex__(self): + return '%s/%s' % (hex(self.n), hex(self.d)) - def __lshift__(self, other): - if other.d != 1: - raise TypeError('cannot shift by non-integer') - return _Rational(self.n< Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21221/Lib/lib-tk Modified Files: tkMessageBox.py Log Message: Convert boolean results back to strings. Fixes #807871. Will backport to 2.3. Index: tkMessageBox.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/tkMessageBox.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- tkMessageBox.py 6 Apr 2003 09:00:54 -0000 1.2 +++ tkMessageBox.py 18 Sep 2004 16:01:23 -0000 1.3 @@ -72,7 +72,12 @@ if type: options["type"] = type if title: options["title"] = title if message: options["message"] = message - return Message(**options).show() + res = Message(**options).show() + # In some Tcl installations, Tcl converts yes/no into a boolean + if isinstance(res, bool): + if res: return YES + return NO + return res def showinfo(title=None, message=None, **options): "Show an info message" From loewis at users.sourceforge.net Sat Sep 18 18:04:23 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 18:04:26 2004 Subject: [Python-checkins] python/dist/src/Lib/lib-tk tkMessageBox.py, 1.2, 1.2.10.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22028/Lib/lib-tk Modified Files: Tag: release23-maint tkMessageBox.py Log Message: Convert bool results back to strings. Fixes #807871. Index: tkMessageBox.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/tkMessageBox.py,v retrieving revision 1.2 retrieving revision 1.2.10.1 diff -u -d -r1.2 -r1.2.10.1 --- tkMessageBox.py 6 Apr 2003 09:00:54 -0000 1.2 +++ tkMessageBox.py 18 Sep 2004 16:04:21 -0000 1.2.10.1 @@ -72,7 +72,12 @@ if type: options["type"] = type if title: options["title"] = title if message: options["message"] = message - return Message(**options).show() + res = Message(**options).show() + # In some Tcl installations, Tcl converts yes/no into a boolean + if isinstance(res, bool): + if res: return YES + return NO + return res def showinfo(title=None, message=None, **options): "Show an info message" From loewis at users.sourceforge.net Sat Sep 18 18:04:25 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 18:04:28 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS, 1.831.4.150, 1.831.4.151 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22028/Misc Modified Files: Tag: release23-maint NEWS Log Message: Convert bool results back to strings. Fixes #807871. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.831.4.150 retrieving revision 1.831.4.151 diff -u -d -r1.831.4.150 -r1.831.4.151 --- NEWS 18 Sep 2004 09:58:41 -0000 1.831.4.150 +++ NEWS 18 Sep 2004 16:04:21 -0000 1.831.4.151 @@ -53,6 +53,8 @@ Library ------- +- Bug #807871: Fix tkMessageBox.askyesno result. + - Patch #1014992: In tarfile.readline, never return more than a line. - Bug #1013882: Flush bz2 data even if nothing had been written so far. From loewis at users.sourceforge.net Sat Sep 18 18:08:01 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 18:08:04 2004 Subject: [Python-checkins] python/dist/src/Lib os.py,1.81,1.82 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22776/Lib Modified Files: os.py Log Message: Patch #1021596: Check for None to determine whether _urandomfd is uninitialized. Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.81 retrieving revision 1.82 diff -u -d -r1.81 -r1.82 --- os.py 1 Sep 2004 13:10:31 -0000 1.81 +++ os.py 18 Sep 2004 16:07:58 -0000 1.82 @@ -666,7 +666,7 @@ """ global _urandomfd - if not _urandomfd: + if _urandomfd is None: try: _urandomfd = open("/dev/urandom", O_RDONLY) except: From loewis at users.sourceforge.net Sat Sep 18 18:16:36 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat Sep 18 18:16:39 2004 Subject: [Python-checkins] python/dist/src/PCbuild _socket.vcproj,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24445 Modified Files: _socket.vcproj Log Message: Link with ws2_32 instead of wsock32. Index: _socket.vcproj =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/_socket.vcproj,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- _socket.vcproj 12 Aug 2004 14:07:49 -0000 1.4 +++ _socket.vcproj 18 Sep 2004 16:16:34 -0000 1.5 @@ -36,7 +36,7 @@ Name="VCCustomBuildTool"/> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9940/dist/src/Lib Modified Files: doctest.py Log Message: In DocFileTest: - Fixed bug in handling of absolute paths. - If run from an interactive session, make paths relative to the directory containing sys.argv[0] (since __main__ doesn't have a __file__ attribute). Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.105 retrieving revision 1.106 diff -u -d -r1.105 -r1.106 --- doctest.py 13 Sep 2004 14:53:27 -0000 1.105 +++ doctest.py 18 Sep 2004 20:27:04 -0000 1.106 @@ -2312,10 +2312,27 @@ ) def DocFileTest(path, package=None, globs=None, **options): - package = _normalize_module(package) name = path.split('/')[-1] - dir = os.path.split(package.__file__)[0] - path = os.path.join(dir, *(path.split('/'))) + + # Interpret relative paths as relative to the given package's + # directory (or the current module, if no package is specified). + if not os.path.isabs(path): + package = _normalize_module(package) + if hasattr(package, '__file__'): + # A normal package/module. + dir = os.path.split(package.__file__)[0] + path = os.path.join(dir, *(path.split('/'))) + elif package.__name__ == '__main__': + # An interactive session. + if sys.argv[0] != '': + dir = os.path.split(sys.argv[0])[0] + path = os.path.join(dir, *(path.split('/'))) + else: + # A module w/o __file__ (this includes builtins) + raise ValueError("Can't resolve paths relative to " + + "the module %s (it has" % package + + "no __file__)") + doc = open(path).read() if globs is None: From edloper at users.sourceforge.net Sat Sep 18 22:27:07 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Sat Sep 18 22:27:11 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_doctest.py, 1.46, 1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9940/dist/src/Lib/test Modified Files: test_doctest.py Log Message: In DocFileTest: - Fixed bug in handling of absolute paths. - If run from an interactive session, make paths relative to the directory containing sys.argv[0] (since __main__ doesn't have a __file__ attribute). Index: test_doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v retrieving revision 1.46 retrieving revision 1.47 diff -u -d -r1.46 -r1.47 --- test_doctest.py 13 Sep 2004 14:53:28 -0000 1.46 +++ test_doctest.py 18 Sep 2004 20:27:04 -0000 1.47 @@ -1812,14 +1812,37 @@ >>> suite.run(unittest.TestResult()) - Note that '/' should be used as a path separator. It will be - converted to a native separator at run time: - + '/' should be used as a path separator. It will be converted + to a native separator at run time: >>> suite = doctest.DocFileSuite('../test/test_doctest.txt') >>> suite.run(unittest.TestResult()) + If DocFileSuite is used from an interactive session, then files + are resolved relative to the directory of sys.argv[0]: + + >>> import new, os.path, test.test_doctest + >>> save_argv = sys.argv + >>> sys.argv = [test.test_doctest.__file__] + >>> suite = doctest.DocFileSuite('test_doctest.txt', + ... package=new.module('__main__')) + >>> sys.argv = save_argv + + Absolute paths may also be used; they should use the native + path separator (*not* '/'). + + >>> # Get the absolute path of the test package. + >>> test_doctest_path = os.path.abspath(test.test_doctest.__file__) + >>> test_pkg_path = os.path.split(test_doctest_path)[0] + + >>> # Use it to find the absolute path of test_doctest.txt. + >>> test_file = os.path.join(test_pkg_path, 'test_doctest.txt') + + >>> suite = doctest.DocFileSuite(test_file) + >>> suite.run(unittest.TestResult()) + + You can specify initial global variables: >>> suite = doctest.DocFileSuite('test_doctest.txt', From bwarsaw at users.sourceforge.net Sat Sep 18 22:53:38 2004 From: bwarsaw at users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sat Sep 18 22:53:42 2004 Subject: [Python-checkins] python/nondist/peps pep-0292.txt,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14421 Modified Files: pep-0292.txt Log Message: Another, and hopefully final round of edits. Index: pep-0292.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0292.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- pep-0292.txt 10 Sep 2004 03:02:32 -0000 1.14 +++ pep-0292.txt 18 Sep 2004 20:53:35 -0000 1.15 @@ -43,11 +43,11 @@ A Simpler Proposal - We propose the addition of a new class -- called 'Template', which - will live in the string module -- derived from the built-in - unicode type. The Template class supports new rules for string - substitution; its value contains placeholders, introduced with the - $ character. The following rules for $-placeholders apply: + We propose the addition of a new class, called 'Template', which + will live in the string module. The Template class supports new + rules for string substitution; its value contains placeholders, + introduced with the $ character. The following rules for + $-placeholders apply: 1. $$ is an escape; it is replaced with a single $ @@ -63,43 +63,48 @@ If the $ character appears at the end of the line, or is followed by any other character than those described above, a ValueError - will be raised at interpolation time. Values in the mapping will - be converted to Unicode strings by calling the built-in unicode() - function, using its default arguments. + will be raised at interpolation time. Values in mapping are + converted automatically to strings. No other characters have special meaning, however it is possible - to derive from the Template class to define different rules for - the placeholder. For example, a derived class could allow for - periods in the placeholder (e.g. to support a kind of dynamic - namespace and attribute path lookup). + to derive from the Template class to define different substitution + rules. For example, a derived class could allow for periods in + the placeholder (e.g. to support a kind of dynamic namespace and + attribute path lookup), or could define a delimiter character + other than '$'. Once the Template has been created, substitutions can be performed - using traditional Python syntax. For example: + by calling one of two methods: + + - substitute(). This method returns a new string which results + when the values of a mapping are substituted for the + placeholders in the Template. If there are placeholders which + are not present in the mapping, a KeyError will be raised. + + - safe_substitute(). This is similar to the substitute() method, + except that KeyErrors are never raised (due to placeholders + missing from the mapping). When a placeholder is missing, the + original placeholder will appear in the resulting string. + + Here are some examples: >>> from string import Template - >>> mapping = dict(name='Guido', country='the Netherlands') >>> s = Template('${name} was born in ${country}') - >>> print s % mapping + >>> print s.substitute(name='Guido', country='the Netherlands') Guido was born in the Netherlands - - Another class is provided which derives from Template. This class - is called 'SafeTemplate' and supports rules identical to those - above. The difference between Template instances and SafeTemplate - instances is that in SafeTemplate if a placeholder is missing from - the interpolation mapping, no KeyError is raised. Instead, the - original placeholder is included in the result string unchanged. - For example: - - >>> from string import Template, SafeTemplate - >>> mapping = dict(name='Guido', country='the Netherlands') - >>> s = Template('$who was born in $country') - >>> print s % mapping + >>> print s.substitute(name='Guido') Traceback (most recent call last): - [...traceback omitted...] - KeyError: u'who' - >>> s = SafeTemplate('$who was born in $country') - >>> print s % mapping - $who was born in the Netherlands + [...] + KeyError: 'country' + >>> print s.safe_substitute(name='Guido') + Guido was born in ${country} + + The signature of substitute() and safe_substitute() allows for + passing the mapping of placeholders to values, either as a single + dictionary-like object in the first positional argument, or as + keyword arguments as shown above. The exact details and + signatures of these two methods is reserved for the standard + library documentation. Why `$' and Braces? @@ -141,9 +146,9 @@ placeholder in the original $-string. The interesting thing is that the Template class defined in this - PEP has nothing to say about the values that are substituted for - the placeholders. Thus, with a little extra work, it's possible - to support PEP 215's functionality using existing Python syntax. + PEP is designed for inheritance and, with a little extra work, + it's possible to support PEP 215's functionality using existing + Python syntax. For example, one could define subclasses of Template and dict that allowed for a more complex placeholder syntax and a mapping that @@ -152,24 +157,26 @@ Internationalization - The implementation supports internationalization magic by keeping - the original string value intact. In fact, all the work of the - special substitution rules are implemented by overriding the - __mod__() operator. However the string value of a Template (or - SafeTemplate) is the string that was passed to its constructor. + The implementation supports internationalization by recording the + original template string in the Template instance's 'template' + attribute. This attribute would serve as the lookup key in an + gettext-based catalog. It is up to the application to turn the + resulting string back into a Template for substitution. - This approach allows a gettext-based internationalized program to - use the Template instance as a lookup into the catalog; in fact - gettext doesn't care that the catalog key is a Template. Because - the value of the Template is the original $-string, translators - also never need to use %-strings. The right thing will happen at - run-time. + However, the Template class was designed to work more intuitively + in an internationalized application, by supporting the mixing-in + of Template and unicode subclasses. Thus an internationalized + application could create an application-specific subclass, + multiply inheriting from Template and unicode, and using instances + of that subclass as the gettext catalog key. Further, the + subclass could alias the special __mod__() method to either + .substitute() or .safe_substitute() to provide a more traditional + string/unicode like %-operator substitution syntax. Reference Implementation - A SourceForge patch[5] is available which implements this - proposal, include unit tests and documentation changes. + The implementation has been committed to the Python 2.4 source tree. References From bwarsaw at users.sourceforge.net Sat Sep 18 23:13:46 2004 From: bwarsaw at users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sat Sep 18 23:13:49 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libstring.tex,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18436 Modified Files: libstring.tex Log Message: Update Template/PEP 292 documentation to current implementation. Index: libstring.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstring.tex,v retrieving revision 1.61 retrieving revision 1.62 diff -u -d -r1.61 -r1.62 --- libstring.tex 6 Sep 2004 01:01:08 -0000 1.61 +++ libstring.tex 18 Sep 2004 21:13:43 -0000 1.62 @@ -89,10 +89,8 @@ \subsection{Template strings} -Templates are Unicode strings that can be used to provide string substitutions -as described in \pep{292}. There is a \class{Template} class that is a -subclass of \class{unicode}, overriding the default \method{__mod__()} method. -Instead of the normal \samp{\%}-based substitutions, Template strings support +Templates provide simpler string substitutions as described in \pep{292}. +Instead of the normal \samp{\%}-based substitutions, Templates support \samp{\$}-based substitutions, using the following rules: \begin{itemize} @@ -113,55 +111,90 @@ \versionadded{2.4} -Template strings are used just like normal strings, in that the modulus -operator is used to interpolate a dictionary of values into a Template string, -for example: +The \module{string} module provides a \class{Template} class that implements +these rules. The methods of \class{Template} are: + +\begin{classdesc}{Template}{template} +The constructor takes a single argument which is the template string. +\end{classdesc} + +\begin{methoddesc}[Template]{substitute}{mapping\optional{, **kws}} +Performs the template substitution, returning a new string. \var{mapping} is +any dictionary-like object with keys that match the placeholders in the +template. Alternatively, you can provide keyword arguments, where the +keywords are the placeholders. When both \var{mapping} and \var{kws} are +given and there are duplicates, the placeholders from \var{kws} take +precedence. +\end{methoddesc} + +\begin{methoddesc}[Template]{safe_substitute}{mapping\optional{, **kws}} +Like \method{substitute()}, except that if placeholders are missing from +\var{mapping} and \var{kws}, instead of raising a \exception{KeyError} +exception, the original placeholder will appear in the resulting string +intact. Note that other exceptions may still be raised, including +\exception{ValueError} as described above. +\end{methoddesc} + +\class{Template} instances also provide one public data attribute: + +\begin{memberdesc}[string]{template} +This is the object passed to the constructor's \var{template} argument. In +general, you shouldn't change it, but read-only access is not enforced. +\end{memberdesc} + +Here is an example of how to use a Template: \begin{verbatim} >>> from string import Template >>> s = Template('$who likes $what') ->>> print s % dict(who='tim', what='kung pao') -tim likes kung pao ->>> Template('Give $who $100') % dict(who='tim') +>>> s.substitute(who='tim', what='kung pao') +'tim likes kung pao' +>>> d = dict(who='tim') +>>> Template('Give $who $100').substitute(d) Traceback (most recent call last): [...] -ValueError: Invalid placeholder at index 10 +ValueError: Invalid placeholder in string: line 1, col 10 +>>> Template('$who likes $what').substitute(d) +Traceback (most recent call last): +[...] +KeyError: 'what' +>>> Template('$who likes $what').safe_substitute(d) +'tim likes $what' \end{verbatim} -There is also a \class{SafeTemplate} class, derived from \class{Template} -which acts the same as \class{Template}, except that if placeholders are -missing in the interpolation dictionary, no \exception{KeyError} will be -raised. Instead the original placeholder (with or without the braces, as -appropriate) will be used: - -\begin{verbatim} ->>> from string import SafeTemplate ->>> s = SafeTemplate('$who likes $what for ${meal}') ->>> print s % dict(who='tim') -tim likes $what for ${meal} -\end{verbatim} +Advanced usage: you can derive subclasses of \class{Template} to customize the +placeholder syntax, delimiter character, or the entire regular expression used +to parse template strings. To do this, you can override these class +attributes: -The values in the mapping will automatically be converted to Unicode strings, -using the built-in \function{unicode()} function, which will be called without -optional arguments \var{encoding} or \var{errors}. +\begin{itemize} +\item \var{delimiter} -- This is the literal string describing a placeholder + introducing delimiter. The default value \samp{\$}. Note that this + should \emph{not} be a regular expression, as the implementation will + call \method{re.escape()} on this string as needed. +\item \var{idpattern} -- This is the regular expression describing the pattern + for non-braced placeholders (the braces will be added automatically as + appropriate). The default value is the regular expression + \samp{[_a-z][_a-z0-9]*}. +\end{itemize} -Advanced usage: you can derive subclasses of \class{Template} or -\class{SafeTemplate} to use application-specific placeholder rules. To do -this, you override the class attribute \member{pattern}; the value must be a -compiled regular expression object with four named capturing groups. The +Alternatively, you can provide the entire regular expression pattern by +overriding the class attribute \var{pattern}. If you do this, the value must +be a regular expression object with four named capturing groups. The capturing groups correspond to the rules given above, along with the invalid placeholder rule: \begin{itemize} -\item \var{escaped} -- This group matches the escape sequence, \samp{\$\$}, - in the default pattern. +\item \var{escaped} -- This group matches the escape sequence, + e.g. \samp{\$\$}, in the default pattern. \item \var{named} -- This group matches the unbraced placeholder name; it - should not include the \samp{\$} in capturing group. -\item \var{braced} -- This group matches the brace delimited placeholder name; - it should not include either the \samp{\$} or braces in the capturing + should not include the delimiter in capturing group. +\item \var{braced} -- This group matches the brace enclosed placeholder name; + it should not include either the delimiter or braces in the capturing group. -\item \var{bogus} -- This group matches any other \samp{\$}. It usually just - matches a single \samp{\$} and should appear last. +\item \var{invalid} -- This group matches any other delimiter pattern (usually + a single delimiter), and it should appear last in the regular + expression. \end{itemize} \subsection{String functions} From pje at users.sourceforge.net Sun Sep 19 01:46:53 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Sun Sep 19 01:46:57 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15913 Modified Files: pep-0333.txt Log Message: Get rid of tabs that sneaked into sample code. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- pep-0333.txt 17 Sep 2004 16:32:17 -0000 1.17 +++ pep-0333.txt 18 Sep 2004 23:46:50 -0000 1.18 @@ -253,7 +253,7 @@ # Re-raise original exception if headers sent raise exc_info[0], exc_info[1], exc_info[2] finally: - exc_info = None # avoid dangling circular ref + exc_info = None # avoid dangling circular ref elif headers_sent: raise AssertionError("Headers already sent!") @@ -263,8 +263,8 @@ result = application(environ, start_response) try: for data in result: - if data: # don't send headers until body appears - write(data) + if data: # don't send headers until body appears + write(data) if not headers_sent: write('') # send headers now if body was empty finally: @@ -329,20 +329,20 @@ its first non-empty string, so 'transform_ok' has to be a mutable truth value.""" - def __init__(self,result,transform_ok): - if hasattr(result,'close'): + def __init__(self,result,transform_ok): + if hasattr(result,'close'): self.close = result.close self._next = iter(result).next self.transform_ok = transform_ok - def __iter__(self): - return self - - def next(self): - if self.transform_ok: - return piglatin(self._next()) - else: - return self._next() + def __iter__(self): + return self + + def next(self): + if self.transform_ok: + return piglatin(self._next()) + else: + return self._next() class Latinator: @@ -361,28 +361,28 @@ for name,value in headers: if name.lower()=='content-type' and value=='text/plain': transform_ok.append(True) - # Strip content-length if present, else it'll be wrong - headers = [(name,value) - for name,value in headers - if name.lower()<>'content-length' - ] - break + # Strip content-length if present, else it'll be wrong + headers = [(name,value) + for name,value in headers + if name.lower()<>'content-length' + ] + break - write = start_response(status,headers,exc_info) + write = start_response(status,headers,exc_info) if transform_ok: - def write_latin(data): - write(piglatin(data)) - return write_latin + def write_latin(data): + write(piglatin(data)) + return write_latin else: return write return LatinIter(self.application(environ,start_latin),transform_ok) - # Run foo_app under a Latinator's control, using the example CGI gateway - from foo_app import foo_app - run_with_cgi(Latinator(foo_app)) + # Run foo_app under a Latinator's control, using the example CGI gateway + from foo_app import foo_app + run_with_cgi(Latinator(foo_app)) @@ -752,7 +752,7 @@ try: # do stuff w/exc_info here finally: - exc_info = None # Avoid circular ref. + exc_info = None # Avoid circular ref. The example CGI gateway provides another illustration of this technique. From edloper at users.sourceforge.net Sun Sep 19 03:16:47 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Sun Sep 19 03:16:50 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31077/dist/src/Doc/lib Modified Files: libdoctest.tex Log Message: - Updated example output to match actual output - Minor wording changes - Changed the docs to reflect the fact that multiple option directives can be specified on a single line (and updated the directive production list, as well). Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- libdoctest.tex 13 Sep 2004 15:03:17 -0000 1.42 +++ libdoctest.tex 19 Sep 2004 01:16:44 -0000 1.43 @@ -100,21 +100,28 @@ \begin{verbatim} $ python example.py -v -Trying: factorial(5) -Expecting: 120 +Trying: + factorial(5) +Expecting: + 120 ok -Trying: [factorial(n) for n in range(6)] -Expecting: [1, 1, 2, 6, 24, 120] +Trying: + [factorial(n) for n in range(6)] +Expecting: + [1, 1, 2, 6, 24, 120] ok -Trying: [factorial(long(n)) for n in range(6)] -Expecting: [1, 1, 2, 6, 24, 120] +Trying: + [factorial(long(n)) for n in range(6)] +Expecting: + [1, 1, 2, 6, 24, 120] ok \end{verbatim} And so on, eventually ending with: \begin{verbatim} -Trying: factorial(1e100) +Trying: + factorial(1e100) Expecting: Traceback (most recent call last): ... @@ -181,7 +188,7 @@ In any case, \function{testmod()} returns a 2-tuple of ints \code{(\var{f}, \var{t})}, where \var{f} is the number of docstring examples that failed and \var{t} is the total number of docstring examples -attempted. +tried. \subsection{Which Docstrings Are Examined?} @@ -266,7 +273,7 @@ detail \end{verbatim} -The last three (starting with \exception{ValueError}) lines are +The last three lines (starting with \exception{ValueError}) are compared against the exception's type and detail, and the rest are ignored. @@ -442,16 +449,20 @@ \begin{productionlist}[doctest] \production{directive} - {"\#" "doctest:" \token{on_or_off} \token{directive_name}} + {"\#" "doctest:" \token{directive_options}} + \production{directive_options} + {\token{directive_option} ("," \token{directive_option})*} + \production{directive_option} + {\token{on_or_off} \token{directive_option_name}} \production{on_or_off} {"+" | "-"} - \production{directive_name} + \production{directive_option_name} {"DONT_ACCEPT_BLANKLINE" | "NORMALIZE_WHITESPACE" | ...} \end{productionlist} Whitespace is not allowed between the \code{+} or \code{-} and the -directive name. The directive name can be any of the option names -explained above. +directive option name. The directive option name can be any of the +option names explained above. The doctest directives appearing in a single example modify doctest's behavior for that single example. Use \code{+} to enable the named @@ -475,16 +486,34 @@ [0, 1, ..., 18, 19] \end{verbatim} -Only one directive per physical line is accepted. If you want to -use multiple directives for a single example, you can add -\samp{...} lines to your example containing only directives: +Multiple directives can be used on a single physical line, separated +by commas: \begin{verbatim} ->>> print range(20) #doctest: +ELLIPSIS -... #doctest: +NORMALIZE_WHITESPACE +>>> print range(20) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE +[0, 1, ..., 18, 19] +\end{verbatim} + +If multiple directives are used for a single example, then they are +combined: + +\begin{verbatim} +>>> print range(20) # doctest: +ELLIPSIS +... # doctest: +NORMALIZE_WHITESPACE [0, 1, ..., 18, 19] \end{verbatim} +As the previous example shows, you can add \samp{...} lines to your +example containing only directives. This can also be useful when an +example is too long for a directive to comfortably fit on the same +line: + +\begin{verbatim} +>>> print range(5) + range(10,20) + range(30,40) + range(50,60) +... # doctest: +ELLIPSIS +[0, ..., 4, 10, ..., 19, 30, ..., 39, 50, ..., 59] +\end{verbatim} + Note that since all options are disabled by default, and directives apply only to the example they appear in, enabling options (via \code{+} in a directive) is usually the only meaningful choice. However, option flags From rhettinger at users.sourceforge.net Sun Sep 19 03:54:12 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 19 03:54:15 2004 Subject: [Python-checkins] python/dist/src/Lib decimal.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5264 Modified Files: decimal.py Log Message: SF patch #1020845: Decimal performance enhancements (Contributed by Nick Coghlan.) Various code cleanups and optimizations (saves about 40% on testsuite execution time and on the telco benchmark). * caches results of various operations on self (esp. checks for being a special value). * _WorkRep now uses ints and longs for intermediate computations. Index: decimal.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/decimal.py,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- decimal.py 19 Aug 2004 22:39:55 -0000 1.23 +++ decimal.py 19 Sep 2004 01:54:09 -0000 1.24 @@ -454,9 +454,13 @@ class Decimal(object): """Floating point class for decimal arithmetic.""" - __slots__ = ('_exp','_int','_sign') + __slots__ = ('_exp','_int','_sign', '_is_special') + # Generally, the value of the Decimal instance is given by + # (-1)**_sign * _int * 10**_exp + # Special values are signified by _is_special == True - def __init__(self, value="0", context=None): + # We're immutable, so use _new__ not __init__ [...1428 lines suppressed...] + return op1, op2, adjust ##### Helper Functions ######################################## +def _convert_other(other): + """Convert other to Decimal. + + Verifies that it's ok to use in an implicit construction. + """ + if isinstance(other, Decimal): + return other + if isinstance(other, (int, long)): + return Decimal(other) + + raise TypeError, "You can interact Decimal only with int, long or Decimal data types." + _infinity_map = { 'inf' : 1, 'infinity' : 1, From bcannon at users.sourceforge.net Sun Sep 19 07:43:16 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Sun Sep 19 07:43:19 2004 Subject: [Python-checkins] python/dist/src/Misc vimrc,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11804/Misc Added Files: vimrc Log Message: When this file is sourced in, or used as, one's vimrc file it will set the proper settings to follow the style guidelines laid out in PEPs 7 & 8 as best it can without forcing extraneous settings. Suggested settings are commented out and included at the end of the file. The goal is to have this file prevent as much as possible from deviating from the style guidelines. It is not meant to collect every cool macro possible for Python. Any useful settings for features included with Vim can be included and commented out, but anything overly extraneous should be left out. --- NEW FILE: vimrc --- " vimrc file for following the coding style specified in PEP 7 & 8. " " To use this file, source it in your own personal .vimrc file (``source " ``) or, if you don't have a .vimrc file, you can just symlink to it " (``ln -s ~/.vimrc``). All options are protected by 'autocmd's " (read below for an explanation) so blind sourcing of this file is safe and " will not affect your settings for non-Python or non-C files. " " All setting are protected by 'au' ('autocmd') statements. Only files ending " in .py or .pyw will trigger the Python settings while files ending in *.c or " *.h will trigger the C settings. This make the file "safe" in terms of only " adjusting settings for Python and C files. " " Only basic settings needed to enforce the style guidelines are set. " Some suggested options are listed but commented out at the end of this file. " " Number of spaces to use for an indent. " This will affect Ctrl-T and 'autoindent'. " Python: 4 spaces " C: tab (8 spaces) au BufRead,BufNewFile *.py,*pyw set shiftwidth=4 au BufRead,BufNewFile *.c,*.h set shiftwidth=8 " Number of spaces that a pre-existing tab is equal to. " For the amount of space used for a new tab, use shiftwidth. " Python: 8 " C: 8 au BufRead,BufNewFile *py,*pyw,*.c,*.h set tabstop=8 " Replace tabs with the equivalent number of spaces. " Also have an autocmd for Makefiles since they require hard tabs. " Python: yes " C: no au BufRead,BufNewFile *.py,*.pyw set expandtab au BufRead,BufNewFile *.c,*.h set noexpandtab au BufRead,BufNewFile Makefile* set noexpandtab " Wrap text after a certain number of characters " Python: 79 " C: 79 au BufRead,BufNewFile *.py,*.pyw,*.c,*.h set textwidth=79 " Turn off settings in 'formatoptions' relating to comment formatting. " - c : do not automatically insert the comment leader when wrapping based on " 'textwidth' " - o : do not insert the comment leader when using 'o' or 'O' from command mode " - r : do not insert the comment leader when hitting in insert mode " Python: not needed " C: prevents insertion of '*' at the beginning of every line in a comment au BufRead,BufNewFile *.c,*.h set formatoptions-=c formatoptions-=o formatoptions-=r " Use UNIX (\n) line endings. " Only used for new files so as to not force existing files to change their " line endings. " Python: yes " C: yes au BufNewFile *.py,*.pyw,*.c,*.h set fileformat=unix " The following section contains suggested settings. While in no way required " to meet coding standards, they are helpful. " Set the default file encoding to UTF-8: ``set encoding=utf-8`` " Put a marker at the beginning of the file to differentiate between UTF and " UCS encoding: ``set bomb`` " For full syntax highlighting: "``let python_highlight_all=1`` "``syntax on`` " Automatically indent: ``filetype indent on`` " Fold based on indentation: ``set foldmethod=indent`` From rhettinger at users.sourceforge.net Sun Sep 19 08:00:18 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 19 08:00:29 2004 Subject: [Python-checkins] python/dist/src/Objects abstract.c,2.131,2.132 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14326 Modified Files: abstract.c Log Message: SF bug #1030557: PyMapping_Check crashes when argument is NULL Make PySequence_Check() and PyMapping_Check() handle NULL inputs. This goes beyond what most of the other checks do, but it is nice defensive programming and solves the OP's problem. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.131 retrieving revision 2.132 diff -u -d -r2.131 -r2.132 --- abstract.c 19 Jul 2004 16:29:16 -0000 2.131 +++ abstract.c 19 Sep 2004 06:00:15 -0000 2.132 @@ -1085,7 +1085,7 @@ int PySequence_Check(PyObject *s) { - if (PyInstance_Check(s)) + if (s && PyInstance_Check(s)) return PyObject_HasAttrString(s, "__getitem__"); return s != NULL && s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL; @@ -1629,7 +1629,7 @@ int PyMapping_Check(PyObject *o) { - if (PyInstance_Check(o)) + if (o && PyInstance_Check(o)) return PyObject_HasAttrString(o, "__getitem__"); return o && o->ob_type->tp_as_mapping && From edloper at users.sourceforge.net Sun Sep 19 19:19:35 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Sun Sep 19 19:19:38 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_doctest.py, 1.47, 1.48 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22247/dist/src/Lib/test Modified Files: test_doctest.py Log Message: - Added "testfile" function, a simple function for running & verifying all examples in a given text file. (analagous to "testmod") - Minor docstring fixes. - Added module_relative parameter to DocTestFile/DocTestSuite, which controls whether paths are module-relative & os-independent, or os-specific. Index: test_doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v retrieving revision 1.47 retrieving revision 1.48 diff -u -d -r1.47 -r1.48 --- test_doctest.py 18 Sep 2004 20:27:04 -0000 1.47 +++ test_doctest.py 19 Sep 2004 17:19:33 -0000 1.48 @@ -1829,8 +1829,9 @@ ... package=new.module('__main__')) >>> sys.argv = save_argv - Absolute paths may also be used; they should use the native - path separator (*not* '/'). + By setting `module_relative=False`, os-specific paths may be + used (including absolute paths and paths relative to the + working directory): >>> # Get the absolute path of the test package. >>> test_doctest_path = os.path.abspath(test.test_doctest.__file__) @@ -1839,10 +1840,17 @@ >>> # Use it to find the absolute path of test_doctest.txt. >>> test_file = os.path.join(test_pkg_path, 'test_doctest.txt') - >>> suite = doctest.DocFileSuite(test_file) + >>> suite = doctest.DocFileSuite(test_file, module_relative=False) >>> suite.run(unittest.TestResult()) + It is an error to specify `package` when `module_relative=False`: + + >>> suite = doctest.DocFileSuite(test_file, module_relative=False, + ... package='test') + Traceback (most recent call last): + ValueError: Package may only be specified for module-relative paths. + You can specify initial global variables: >>> suite = doctest.DocFileSuite('test_doctest.txt', @@ -1991,6 +1999,127 @@ """ +def test_testfile(): r""" +Tests for the `testfile()` function. This function runs all the +doctest examples in a given file. In its simple invokation, it is +called with the name of a file, which is taken to be relative to the +calling module. The return value is (#failures, #tests). + + >>> doctest.testfile('test_doctest.txt') # doctest: +ELLIPSIS + ********************************************************************** + File "...", line 6, in test_doctest.txt + Failed example: + favorite_color + Exception raised: + ... + NameError: name 'favorite_color' is not defined + ********************************************************************** + 1 items had failures: + 1 of 2 in test_doctest.txt + ***Test Failed*** 1 failures. + (1, 2) + >>> doctest.master = None # Reset master. + +(Note: we'll be clearing doctest.master after each call to +`doctest.testfile`, to supress warnings about multiple tests with the +same name.) + +Globals may be specified with the `globs` and `extraglobs` parameters: + + >>> globs = {'favorite_color': 'blue'} + >>> doctest.testfile('test_doctest.txt', globs=globs) + (0, 2) + >>> doctest.master = None # Reset master. + + >>> extraglobs = {'favorite_color': 'red'} + >>> doctest.testfile('test_doctest.txt', globs=globs, + ... extraglobs=extraglobs) # doctest: +ELLIPSIS + ********************************************************************** + File "...", line 6, in test_doctest.txt + Failed example: + favorite_color + Expected: + 'blue' + Got: + 'red' + ********************************************************************** + 1 items had failures: + 1 of 2 in test_doctest.txt + ***Test Failed*** 1 failures. + (1, 2) + >>> doctest.master = None # Reset master. + +The file may be made relative to a given module or package, using the +optional `module_relative` parameter: + + >>> doctest.testfile('test_doctest.txt', globs=globs, + ... module_relative='test') + (0, 2) + >>> doctest.master = None # Reset master. + +Verbosity can be increased with the optional `verbose` paremter: + + >>> doctest.testfile('test_doctest.txt', globs=globs, verbose=True) + Trying: + favorite_color + Expecting: + 'blue' + ok + Trying: + if 1: + print 'a' + print + print 'b' + Expecting: + a + + b + ok + 1 items passed all tests: + 2 tests in test_doctest.txt + 2 tests in 1 items. + 2 passed and 0 failed. + Test passed. + (0, 2) + >>> doctest.master = None # Reset master. + +The name of the test may be specified with the optional `name` +parameter: + + >>> doctest.testfile('test_doctest.txt', name='newname') + ... # doctest: +ELLIPSIS + ********************************************************************** + File "...", line 6, in newname + ... + (1, 2) + >>> doctest.master = None # Reset master. + +The summary report may be supressed with the optional `report` +parameter: + + >>> doctest.testfile('test_doctest.txt', report=False) + ... # doctest: +ELLIPSIS + ********************************************************************** + File "...", line 6, in test_doctest.txt + Failed example: + favorite_color + Exception raised: + ... + NameError: name 'favorite_color' is not defined + (1, 2) + >>> doctest.master = None # Reset master. + +The optional keyword argument `raise_on_error` can be used to raise an +exception on the first error (which may be useful for postmortem +debugging): + + >>> doctest.testfile('test_doctest.txt', raise_on_error=True) + ... # doctest: +ELLIPSIS + Traceback (most recent call last): + UnexpectedException: ... + >>> doctest.master = None # Reset master. +""" + # old_test1, ... used to live in doctest.py, but cluttered it. Note # that these use the deprecated doctest.Tester, so should go away (or # be rewritten) someday. From edloper at users.sourceforge.net Sun Sep 19 19:19:35 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Sun Sep 19 19:19:39 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.106,1.107 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22247/dist/src/Lib Modified Files: doctest.py Log Message: - Added "testfile" function, a simple function for running & verifying all examples in a given text file. (analagous to "testmod") - Minor docstring fixes. - Added module_relative parameter to DocTestFile/DocTestSuite, which controls whether paths are module-relative & os-independent, or os-specific. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.106 retrieving revision 1.107 diff -u -d -r1.106 -r1.107 --- doctest.py 18 Sep 2004 20:27:04 -0000 1.106 +++ doctest.py 19 Sep 2004 17:19:33 -0000 1.107 @@ -200,6 +200,7 @@ 'DebugRunner', # 6. Test Functions 'testmod', + 'testfile', 'run_docstring_examples', # 7. Tester 'Tester', @@ -478,6 +479,30 @@ # Restore stdout. sys.stdout = save_stdout +def _module_relative_path(module, path): + if not inspect.ismodule(module): + raise TypeError, 'Expected a module: %r' % module + if path.startswith('/'): + raise ValueError, 'Module-relative files may not have absolute paths' + + # Find the base directory for the path. + if hasattr(module, '__file__'): + # A normal module/package + basedir = os.path.split(module.__file__)[0] + elif module.__name__ == '__main__': + # An interactive session. + if len(sys.argv)>0 and sys.argv[0] != '': + basedir = os.path.split(sys.argv[0])[0] + else: + basedir = os.curdir + else: + # A module w/o __file__ (this includes builtins) + raise ValueError("Can't resolve paths relative to the module " + + module + " (it has no __file__)") + + # Combine the base directory and the path. + return os.path.join(basedir, *(path.split('/'))) + ###################################################################### ## 2. Example & DocTest ###################################################################### @@ -1881,6 +1906,7 @@ DONT_ACCEPT_BLANKLINE NORMALIZE_WHITESPACE ELLIPSIS + IGNORE_EXCEPTION_DETAIL REPORT_UDIFF REPORT_CDIFF REPORT_NDIFF @@ -1896,9 +1922,7 @@ treat all functions as public. Optionally, "isprivate" can be set to doctest.is_private to skip over functions marked as private using the underscore naming convention; see its docs for details. - """ - """ [XX] This is no longer true: Advanced tomfoolery: testmod runs methods of a local instance of class doctest.Tester, then merges the results into (or creates) global Tester instance doctest.master. Methods of doctest.master @@ -1950,6 +1974,121 @@ return runner.failures, runner.tries +def testfile(filename, module_relative=True, name=None, package=None, + globs=None, verbose=None, report=True, optionflags=0, + extraglobs=None, raise_on_error=False): + """ + Test examples in the given file. Return (#failures, #tests). + + Optional keyword arg "module_relative" specifies how filenames + should be interpreted: + + - If "module_relative" is True (the default), then "filename" + specifies a module-relative path. By default, this path is + relative to the calling module's directory; but if the + "package" argument is specified, then it is relative to that + package. To ensure os-independence, "filename" should use + "/" characters to separate path segments, and should not + be an absolute path (i.e., it may not begin with "/"). + + - If "module_relative" is False, then "filename" specifies an + os-specific path. The path may be absolute or relative (to + the current working directory). + + Optional keyword arg "name" gives the name of the file; by default + use the file's name. + + Optional keyword argument "package" is a Python package or the + name of a Python package whose directory should be used as the + base directory for a module relative filename. If no package is + specified, then the calling module's directory is used as the base + directory for module relative filenames. It is an error to + specify "package" if "module_relative" is False. + + Optional keyword arg "globs" gives a dict to be used as the globals + when executing examples; by default, use {}. A copy of this dict + is actually used for each docstring, so that each docstring's + examples start with a clean slate. + + Optional keyword arg "extraglobs" gives a dictionary that should be + merged into the globals that are used to execute examples. By + default, no extra globals are used. + + Optional keyword arg "verbose" prints lots of stuff if true, prints + only failures if false; by default, it's true iff "-v" is in sys.argv. + + Optional keyword arg "report" prints a summary at the end when true, + else prints nothing at the end. In verbose mode, the summary is + detailed, else very brief (in fact, empty if all tests passed). + + Optional keyword arg "optionflags" or's together module constants, + and defaults to 0. Possible values (see the docs for details): + + DONT_ACCEPT_TRUE_FOR_1 + DONT_ACCEPT_BLANKLINE + NORMALIZE_WHITESPACE + ELLIPSIS + IGNORE_EXCEPTION_DETAIL + REPORT_UDIFF + REPORT_CDIFF + REPORT_NDIFF + REPORT_ONLY_FIRST_FAILURE + + Optional keyword arg "raise_on_error" raises an exception on the + first unexpected exception or failure. This allows failures to be + post-mortem debugged. + + Advanced tomfoolery: testmod runs methods of a local instance of + class doctest.Tester, then merges the results into (or creates) + global Tester instance doctest.master. Methods of doctest.master + can be called directly too, if you want to do something unusual. + Passing report=0 to testmod is especially useful then, to delay + displaying a summary. Invoke doctest.master.summarize(verbose) + when you're done fiddling. + """ + global master + + if package and not module_relative: + raise ValueError("Package may only be specified for module-" + "relative paths.") + + # Relativize the path + if module_relative: + package = _normalize_module(package) + filename = _module_relative_path(package, filename) + + # If no name was given, then use the file's name. + if name is None: + name = os.path.split(filename)[-1] + + # Assemble the globals. + if globs is None: + globs = {} + else: + globs = globs.copy() + if extraglobs is not None: + globs.update(extraglobs) + + if raise_on_error: + runner = DebugRunner(verbose=verbose, optionflags=optionflags) + else: + runner = DocTestRunner(verbose=verbose, optionflags=optionflags) + + # Read the file, convert it to a test, and run it. + s = open(filename).read() + test = DocTestParser().get_doctest(s, globs, name, filename, 0) + runner.run(test) + + if report: + runner.summarize() + + if master is None: + master = runner + else: + master.merge(runner) + + return runner.failures, runner.tries + def run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0): """ @@ -2311,52 +2450,59 @@ % (self._dt_test.name, self._dt_test.filename, err) ) -def DocFileTest(path, package=None, globs=None, **options): - name = path.split('/')[-1] +def DocFileTest(path, module_relative=True, package=None, + globs=None, **options): + if globs is None: + globs = {} - # Interpret relative paths as relative to the given package's - # directory (or the current module, if no package is specified). - if not os.path.isabs(path): + if package and not module_relative: + raise ValueError("Package may only be specified for module-" + "relative paths.") + + # Relativize the path. + if module_relative: package = _normalize_module(package) - if hasattr(package, '__file__'): - # A normal package/module. - dir = os.path.split(package.__file__)[0] - path = os.path.join(dir, *(path.split('/'))) - elif package.__name__ == '__main__': - # An interactive session. - if sys.argv[0] != '': - dir = os.path.split(sys.argv[0])[0] - path = os.path.join(dir, *(path.split('/'))) - else: - # A module w/o __file__ (this includes builtins) - raise ValueError("Can't resolve paths relative to " + - "the module %s (it has" % package + - "no __file__)") + path = _module_relative_path(package, path) - doc = open(path).read() + # Find the file and read it. + name = os.path.split(path)[-1] - if globs is None: - globs = {} + doc = open(path).read() + # Convert it to a test, and wrap it in a DocFileCase. test = DocTestParser().get_doctest(doc, globs, name, path, 0) - return DocFileCase(test, **options) def DocFileSuite(*paths, **kw): - """Creates a suite of doctest files. - - One or more text file paths are given as strings. These should - use "/" characters to separate path segments. Paths are relative - to the directory of the calling module, or relative to the package - passed as a keyword argument. + """A unittest suite for one or more doctest files. + + The path to each doctest file is given as a string; the + interpretation of that string depends on the keyword argument + "module_relative". A number of options may be provided as keyword arguments: + module_relative + If "module_relative" is True, then the given file paths are + interpreted as os-independent module-relative paths. By + default, these paths are relative to the calling module's + directory; but if the "package" argument is specified, then + they are relative to that package. To ensure os-independence, + "filename" should use "/" characters to separate path + segments, and may not be an absolute path (i.e., it may not + begin with "/"). + + If "module_relative" is False, then the given file paths are + interpreted as os-specific paths. These paths may be absolute + or relative (to the current working directory). + package - The name of a Python package. Text-file paths will be - interpreted relative to the directory containing this package. - The package may be supplied as a package object or as a dotted - package name. + A Python package or the name of a Python package whose directory + should be used as the base directory for module relative paths. + If "package" is not specified, then the calling module's + directory is used as the base directory for module relative + filenames. It is an error to specify "package" if + "module_relative" is False. setUp The name of a set-up function. This is called before running the @@ -2375,14 +2521,14 @@ optionflags A set of doctest option flags expressed as an integer. - """ suite = unittest.TestSuite() # We do this here so that _normalize_module is called at the right # level. If it were called in DocFileTest, then this function # would be the caller and we might guess the package incorrectly. - kw['package'] = _normalize_module(kw.get('package')) + if kw.get('module_relative', True): + kw['package'] = _normalize_module(kw.get('package')) for path in paths: suite.addTest(DocFileTest(path, **kw)) From loewis at users.sourceforge.net Sun Sep 19 20:36:50 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun Sep 19 20:36:53 2004 Subject: [Python-checkins] python/dist/src/Tools/msi msi.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/msi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4541 Modified Files: msi.py Log Message: Fix lib-tk PythonPath. Index: msi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/msi/msi.py,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- msi.py 12 Sep 2004 03:49:31 -0000 1.11 +++ msi.py 19 Sep 2004 18:36:45 -0000 1.12 @@ -1085,7 +1085,7 @@ ("InstallGroup", -1, prefix+r"\InstallPath\InstallGroup", "", "Python %s" % short_version, "REGISTRY"), ("PythonPath", -1, prefix+r"\PythonPath", "", - "[TARGETDIR]Lib;[TARGETDIR]DLLs;[TARGETDIR]lib-tk", "REGISTRY"), + r"[TARGETDIR]Lib;[TARGETDIR]DLLs;[TARGETDIR]Lib\lib-tk", "REGISTRY"), ("Documentation", -1, prefix+r"\Help\Main Python Documentation", "", r"[TARGETDIR]Doc\Python%s%s.chm" % (major, minor), "REGISTRY"), ("Modules", -1, prefix+r"\Modules", "+", None, "REGISTRY"), From pje at users.sourceforge.net Sun Sep 19 21:49:40 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Sun Sep 19 21:49:46 2004 Subject: [Python-checkins] python/nondist/peps pep-0333.txt,1.18,1.19 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020 Modified Files: pep-0333.txt Log Message: Move subsections on HTTP features, error handling, unicode, and threading to the main "Specification Details" section. Juggle order of implementation notes to better match their importance and pedagogic sequence. Add current open issues re: async app frameworks. Index: pep-0333.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- pep-0333.txt 18 Sep 2004 23:46:50 -0000 1.18 +++ pep-0333.txt 19 Sep 2004 19:49:37 -0000 1.19 @@ -916,11 +916,8 @@ from within their return iterable. -Implementation/Application Notes -================================ - -Unicode -------- +Unicode Issues +-------------- HTTP does not directly support Unicode, and neither does this interface. All encoding/decoding must be handled by the application; @@ -1009,6 +1006,77 @@ being provided +HTTP 1.1 Expect/Continue +------------------------ + +Servers and gateways that implement HTTP 1.1 **must** provide +transparent support for HTTP 1.1's "expect/continue" mechanism. This +may be done in any of several ways: + +1. Respond to requests containing an ``Expect: 100-continue`` request + with an immediate "100 Continue" response, and proceed normally. + +2. Proceed with the request normally, but provide the application + with a ``wsgi.input`` stream that will send the "100 Continue" + response if/when the application first attempts to read from the + input stream. The read request must then remain blocked until the + client responds. + +3. Wait until the client decides that the server does not support + expect/continue, and sends the request body on its own. (This + is suboptimal, and is not recommended.) + +Note that these behavior restrictions do not apply for HTTP 1.0 +requests, or for requests that are not directed to an application +object. For more information on HTTP 1.1 Expect/Continue, see RFC +2616, sections 8.2.3 and 10.1.1. + + +Other HTTP Features +------------------- + +In general, servers and gateways should "play dumb" and allow the +application complete control over its output. They should only make +changes that do not alter the effective semantics of the application's +response. It is always possible for the application developer to add +middleware components to supply additional features, so server/gateway +developers should be conservative in their implementation. In a sense, +a server should consider itself to be like an HTTP "proxy server", with +the application being an HTTP "origin server". + +However, because WSGI servers and applications do not communicate via +HTTP, what RFC 2616 calls "hop-by-hop" headers do not apply to WSGI +internal communications. WSGI applications **must not** generate any +"hop-by-hop" headers [4]_, attempt to use HTTP features that would +require them to generate such headers, or rely on the content of +any incoming "hop-by-hop" headers in the ``environ`` dictionary. +WSGI servers **must** handle any supported inbound "hop-by-hop" headers +on their own, such as by decoding any inbound ``Transfer-Encoding``, +including chunked encoding if applicable. + +Applying these principles to a variety of HTTP features, it should be +clear that a server **may** handle cache validation via the +``If-None-Match`` and ``If-Modified-Since`` request headers and the +``Last-Modified`` and ``ETag`` response headers. However, it is +not required to do this, and the application **should** perform its +own cache validation if it wants to support that feature, since +the server/gateway is not required to do such validation. + +Similarly, a server **may** re-encode or transport-encode an +application's response, but the application **should** use a +suitable content encoding on its own, and **must not** apply a +transport encoding. A server **may** transmit byte ranges of the +application's response if requested by the client, and the +application doesn't natively support byte ranges. Again, however, +the application **should** perform this function on its own if desired. + +Note that these restrictions on applications do not necessarily mean +that every application must reimplement every HTTP feature; many HTTP +features can be partially or fully implemented by middleware +components, thus freeing both server and application authors from +implementing the same features over and over again. + + Thread Support -------------- @@ -1019,35 +1087,66 @@ may still be used with that server. -URL Reconstruction ------------------- -If an application wishes to reconstruct a request's complete URL, it -may do so using the following algorithm, contributed by Ian Bicking:: +Implementation/Application Notes +================================ - url = environ['wsgi.url_scheme']+'://' - if environ.get('HTTP_HOST'): - url += environ['HTTP_HOST'] - else: - url += environ['SERVER_NAME'] +Server Extension APIs +--------------------- - if environ['wsgi.url_scheme'] == 'https': - if environ['SERVER_PORT'] != '443' - url += ':' + environ['SERVER_PORT'] - else: - if environ['SERVER_PORT'] != '80': - url += ':' + environ['SERVER_PORT'] +Some server authors may wish to expose more advanced APIs, that +application or framework authors can use for specialized purposes. +For example, a gateway based on ``mod_python`` might wish to expose +part of the Apache API as a WSGI extension. - url += environ.get('SCRIPT_NAME','') - url += environ.get('PATH_INFO','') - if environ.get('QUERY_STRING'): - url += '?' + environ['QUERY_STRING'] +In the simplest case, this requires nothing more than defining an +``environ`` variable, such as ``mod_python.some_api``. But, in many +cases, the possible presence of middleware can make this difficult. +For example, an API that offers access to the same HTTP headers that +are found in ``environ`` variables, might return different data if +``environ`` has been modified by middleware. -Note that such a reconstructed URL may not be precisely the same URI -as requested by the client. Server rewrite rules, for example, may -have modified the client's originally requested URL to place it in a -canonical form. +In general, any extension API that duplicates, supplants, or bypasses +some portion of WSGI functionality runs the risk of being incompatible +with middleware components. Server/gateway developers should *not* +assume that nobody will use middleware, because some framework +developers specifically intend to organize or reorganize their +frameworks to function almost entirely as middleware of various kinds. + +So, to provide maximum compatibility, servers and gateways that +provide extension APIs that replace some WSGI functionality, **must** +design those APIs so that they are invoked using the portion of the +API that they replace. For example, an extension API to access HTTP +request headers must require the application to pass in its current +``environ``, so that the server/gateway may verify that HTTP headers +accessible via the API have not been altered by middleware. If the +extension API cannot guarantee that it will always agree with +``environ`` about the contents of HTTP headers, it must refuse service +to the application, e.g. by raising an error, returning ``None`` +instead of a header collection, or whatever is appropriate to the API. + +Similarly, if an extension API provides an alternate means of writing +response data or headers, it should require the ``start_response`` +callable to be passed in, before the application can obtain the +extended service. If the object passed in is not the same one that +the server/gateway originally supplied to the application, it cannot +guarantee correct operation and must refuse to provide the extended +service to the application. + +These guidelines also apply to middleware that adds information such +as parsed cookies, form variables, sessions, and the like to +``environ``. Specifically, such middleware should provide these +features as functions which operate on ``environ``, rather than simply +stuffing values into ``environ``. This helps ensure that information +is calculated from ``environ`` *after* any middleware has done any URL +rewrites or other ``environ`` modifications. + +It is very important that these "safe extension" rules be followed by +both server/gateway and middleware developers, in order to avoid a +future in which middleware developers are forced to delete any and all +extension APIs from ``environ`` to ensure that their mediation isn't +being bypassed by applications using those extensions! Application Configuration @@ -1098,6 +1197,37 @@ to re-read it upon each invocation.) +URL Reconstruction +------------------ + +If an application wishes to reconstruct a request's complete URL, it +may do so using the following algorithm, contributed by Ian Bicking:: + + url = environ['wsgi.url_scheme']+'://' + + if environ.get('HTTP_HOST'): + url += environ['HTTP_HOST'] + else: + url += environ['SERVER_NAME'] + + if environ['wsgi.url_scheme'] == 'https': + if environ['SERVER_PORT'] != '443' + url += ':' + environ['SERVER_PORT'] + else: + if environ['SERVER_PORT'] != '80': + url += ':' + environ['SERVER_PORT'] + + url += environ.get('SCRIPT_NAME','') + url += environ.get('PATH_INFO','') + if environ.get('QUERY_STRING'): + url += '?' + environ['QUERY_STRING'] + +Note that such a reconstructed URL may not be precisely the same URI +as requested by the client. Server rewrite rules, for example, may +have modified the client's originally requested URL to place it in a +canonical form. + + Supporting Older (<2.2) Versions of Python ------------------------------------------ @@ -1146,64 +1276,6 @@ 1 and 0 instead of ``True`` and ``False``, etc.) - -Server Extension APIs ---------------------- - -Some server authors may wish to expose more advanced APIs, that -application or framework authors can use for specialized purposes. -For example, a gateway based on ``mod_python`` might wish to expose -part of the Apache API as a WSGI extension. - -In the simplest case, this requires nothing more than defining an -``environ`` variable, such as ``mod_python.some_api``. But, in many -cases, the possible presence of middleware can make this difficult. -For example, an API that offers access to the same HTTP headers that -are found in ``environ`` variables, might return different data if -``environ`` has been modified by middleware. - -In general, any extension API that duplicates, supplants, or bypasses -some portion of WSGI functionality runs the risk of being incompatible -with middleware components. Server/gateway developers should *not* -assume that nobody will use middleware, because some framework -developers specifically intend to organize or reorganize their -frameworks to function almost entirely as middleware of various kinds. - -So, to provide maximum compatibility, servers and gateways that -provide extension APIs that replace some WSGI functionality, **must** -design those APIs so that they are invoked using the portion of the -API that they replace. For example, an extension API to access HTTP -request headers must require the application to pass in its current -``environ``, so that the server/gateway may verify that HTTP headers -accessible via the API have not been altered by middleware. If the -extension API cannot guarantee that it will always agree with -``environ`` about the contents of HTTP headers, it must refuse service -to the application, e.g. by raising an error, returning ``None`` -instead of a header collection, or whatever is appropriate to the API. - -Similarly, if an extension API provides an alternate means of writing -response data or headers, it should require the ``start_response`` -callable to be passed in, before the application can obtain the -extended service. If the object passed in is not the same one that -the server/gateway originally supplied to the application, it cannot -guarantee correct operation and must refuse to provide the extended -service to the application. - -These guidelines also apply to middleware that adds information such -as parsed cookies, form variables, sessions, and the like to -``environ``. Specifically, such middleware should provide these -features as functions which operate on ``environ``, rather than simply -stuffing values into ``environ``. This helps ensure that information -is calculated from ``environ`` *after* any middleware has done any URL -rewrites or other ``environ`` modifications. - -It is very important that these "safe extension" rules be followed by -both server/gateway and middleware developers, in order to avoid a -future in which middleware developers are forced to delete any and all -extension APIs from ``environ`` to ensure that their mediation isn't -being bypassed by applications using those extensions! - - Optional Platform-Specific File Handling ---------------------------------------- @@ -1302,77 +1374,6 @@ result.close() -HTTP 1.1 Expect/Continue ------------------------- - -Servers and gateways that implement HTTP 1.1 **must** provide -transparent support for HTTP 1.1's "expect/continue" mechanism. This -may be done in any of several ways: - -1. Respond to requests containing an ``Expect: 100-continue`` request - with an immediate "100 Continue" response, and proceed normally. - -2. Proceed with the request normally, but provide the application - with a ``wsgi.input`` stream that will send the "100 Continue" - response if/when the application first attempts to read from the - input stream. The read request must then remain blocked until the - client responds. - -3. Wait until the client decides that the server does not support - expect/continue, and sends the request body on its own. (This - is suboptimal, and is not recommended.) - -Note that these behavior restrictions do not apply for HTTP 1.0 -requests, or for requests that are not directed to an application -object. For more information on HTTP 1.1 Expect/Continue, see RFC -2616, sections 8.2.3 and 10.1.1. - - -Other HTTP Features -------------------- - -In general, servers and gateways should "play dumb" and allow the -application complete control over its output. They should only make -changes that do not alter the effective semantics of the application's -response. It is always possible for the application developer to add -middleware components to supply additional features, so server/gateway -developers should be conservative in their implementation. In a sense, -a server should consider itself to be like an HTTP "proxy server", with -the application being an HTTP "origin server". - -However, because WSGI servers and applications do not communicate via -HTTP, what RFC 2616 calls "hop-by-hop" headers do not apply to WSGI -internal communications. WSGI applications **must not** generate any -"hop-by-hop" headers [4]_, attempt to use HTTP features that would -require them to generate such headers, or rely on the content of -any incoming "hop-by-hop" headers in the ``environ`` dictionary. -WSGI servers **must** handle any supported inbound "hop-by-hop" headers -on their own, such as by decoding any inbound ``Transfer-Encoding``, -including chunked encoding if applicable. - -Applying these principles to a variety of HTTP features, it should be -clear that a server **may** handle cache validation via the -``If-None-Match`` and ``If-Modified-Since`` request headers and the -``Last-Modified`` and ``ETag`` response headers. However, it is -not required to do this, and the application **should** perform its -own cache validation if it wants to support that feature, since -the server/gateway is not required to do such validation. - -Similarly, a server **may** re-encode or transport-encode an -application's response, but the application **should** use a -suitable content encoding on its own, and **must not** apply a -transport encoding. A server **may** transmit byte ranges of the -application's response if requested by the client, and the -application doesn't natively support byte ranges. Again, however, -the application **should** perform this function on its own if desired. - -Note that these restrictions on applications do not necessarily mean -that every application must reimplement every HTTP feature; many HTTP -features can be partially or fully implemented by middleware -components, thus freeing both server and application authors from -implementing the same features over and over again. - - Questions and Answers ===================== @@ -1518,6 +1519,25 @@ developers. +Proposed/Under Discussion +========================= + +These items are currently being discussed on the Web-SIG and elsewhere, +or are on the PEP author's "to-do" list: + +* Should ``wsgi.input`` be an iterator instead of a file? This would + help for asynchronous applications and chunked-encoding input + streams. + +* Optional extensions are being discussed for pausing iteration of an + application's ouptut until input is available or until a callback + occurs. + +* Add a section about synchronous vs. asynchronous apps and servers, + the relevant threading models, and issues/design goals in these + areas. + + Acknowledgements ================ From loewis at users.sourceforge.net Mon Sep 20 08:14:58 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon Sep 20 08:15:01 2004 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.164,1.165 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11191/Objects Modified Files: longobject.c Log Message: Patch #1024670: Support int objects in PyLong_AsUnsignedLong[Mask]. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.164 retrieving revision 1.165 diff -u -d -r1.164 -r1.165 --- longobject.c 30 Aug 2004 02:58:59 -0000 1.164 +++ longobject.c 20 Sep 2004 06:14:54 -0000 1.165 @@ -245,6 +245,15 @@ int i; if (vv == NULL || !PyLong_Check(vv)) { + if (vv != NULL && PyInt_Check(vv)) { + long val = PyInt_AsLong(vv); + if (val < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to unsigned long"); + return (unsigned long) -1; + } + return val; + } PyErr_BadInternalCall(); return (unsigned long) -1; } @@ -279,6 +288,8 @@ int i, sign; if (vv == NULL || !PyLong_Check(vv)) { + if (vv != NULL && PyInt_Check(vv)) + return PyInt_AsUnsignedLongMask(vv); PyErr_BadInternalCall(); return (unsigned long) -1; } From loewis at users.sourceforge.net Mon Sep 20 08:17:55 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon Sep 20 08:17:58 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1137,1.1138 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11689/Misc Modified Files: NEWS Log Message: Patch #1024670: Support int objects in PyLong_AsUnsignedLong[Mask]. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1137 retrieving revision 1.1138 diff -u -d -r1.1137 -r1.1138 --- NEWS 18 Sep 2004 09:08:52 -0000 1.1137 +++ NEWS 20 Sep 2004 06:17:46 -0000 1.1138 @@ -12,7 +12,7 @@ Core and builtins ----------------- -... +- PyLong_AsUnsignedLong[Mask] now support int objects as well. Extension modules ----------------- From montanaro at users.sourceforge.net Mon Sep 20 17:40:41 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon Sep 20 17:40:44 2004 Subject: [Python-checkins] python/dist/src/Lib inspect.py,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29971 Modified Files: inspect.py Log Message: Sort classes by fully qualified name. In the common case where you are displaying a set of classes from one module it doesn't matter, but if you are displaying a large class tree from multiple modules it improves the display to sort by module.name. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.55 retrieving revision 1.56 diff -u -d -r1.55 -r1.56 --- inspect.py 11 Sep 2004 15:53:22 -0000 1.55 +++ inspect.py 20 Sep 2004 15:40:38 -0000 1.56 @@ -557,7 +557,8 @@ def walktree(classes, children, parent): """Recursive helper function for getclasstree().""" results = [] - classes.sort(key=attrgetter('__name__')) + classes.sort(lambda a, b: cmp("%s.%s" % (a.__module__, a.__name__), + "%s.%s" % (b.__module__, b.__name__))) for c in classes: results.append((c, c.__bases__)) if c in children: From montanaro at users.sourceforge.net Mon Sep 20 18:43:33 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon Sep 20 18:43:36 2004 Subject: [Python-checkins] python/dist/src/Lib inspect.py,1.56,1.57 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10759 Modified Files: inspect.py Log Message: Raymond reminded me to use DSU key Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.56 retrieving revision 1.57 diff -u -d -r1.56 -r1.57 --- inspect.py 20 Sep 2004 15:40:38 -0000 1.56 +++ inspect.py 20 Sep 2004 16:43:30 -0000 1.57 @@ -557,8 +557,7 @@ def walktree(classes, children, parent): """Recursive helper function for getclasstree().""" results = [] - classes.sort(lambda a, b: cmp("%s.%s" % (a.__module__, a.__name__), - "%s.%s" % (b.__module__, b.__name__))) + classes.sort(key=lambda c: (c.__module__, c.__name__)) for c in classes: results.append((c, c.__bases__)) if c in children: From rhettinger at users.sourceforge.net Mon Sep 20 19:47:49 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 20 19:47:57 2004 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew24.tex, 1.101, 1.102 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24989 Modified Files: whatsnew24.tex Log Message: Fix minor grammar typo. Index: whatsnew24.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew24.tex,v retrieving revision 1.101 retrieving revision 1.102 diff -u -d -r1.101 -r1.102 --- whatsnew24.tex 13 Sep 2004 15:06:50 -0000 1.101 +++ whatsnew24.tex 20 Sep 2004 17:47:46 -0000 1.102 @@ -1365,7 +1365,7 @@ switch enables profiling using the Pentium's Time-Stamp-Counter register. The switch is slightly misnamed, because the profiling feature also works on the PowerPC platform, though that processor - architecture doesn't called that register the TSC. + architecture doesn't call that register a TSC. \item The \ctype{tracebackobject} type has been renamed to \ctype{PyTracebackObject}. From rhettinger at users.sourceforge.net Mon Sep 20 20:08:34 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 20 20:08:38 2004 Subject: [Python-checkins] python/dist/src/Lib inspect.py,1.57,1.58 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29350 Modified Files: inspect.py Log Message: Import no longer needed. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.57 retrieving revision 1.58 diff -u -d -r1.57 -r1.58 --- inspect.py 20 Sep 2004 16:43:30 -0000 1.57 +++ inspect.py 20 Sep 2004 18:08:31 -0000 1.58 @@ -29,7 +29,6 @@ __date__ = '1 Jan 2001' import sys, os, types, string, re, dis, imp, tokenize, linecache -from operator import attrgetter # ----------------------------------------------------------- type-checking def ismodule(object): From tim_one at users.sourceforge.net Mon Sep 20 21:52:38 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon Sep 20 21:52:43 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.107,1.108 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20341/Lib Modified Files: doctest.py Log Message: Whitespace normalization. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.107 retrieving revision 1.108 diff -u -d -r1.107 -r1.108 --- doctest.py 19 Sep 2004 17:19:33 -0000 1.107 +++ doctest.py 20 Sep 2004 19:52:34 -0000 1.108 @@ -2051,7 +2051,7 @@ if package and not module_relative: raise ValueError("Package may only be specified for module-" "relative paths.") - + # Relativize the path if module_relative: package = _normalize_module(package) @@ -2458,7 +2458,7 @@ if package and not module_relative: raise ValueError("Package may only be specified for module-" "relative paths.") - + # Relativize the path. if module_relative: package = _normalize_module(package) @@ -2475,7 +2475,7 @@ def DocFileSuite(*paths, **kw): """A unittest suite for one or more doctest files. - + The path to each doctest file is given as a string; the interpretation of that string depends on the keyword argument "module_relative". @@ -2491,7 +2491,7 @@ "filename" should use "/" characters to separate path segments, and may not be an absolute path (i.e., it may not begin with "/"). - + If "module_relative" is False, then the given file paths are interpreted as os-specific paths. These paths may be absolute or relative (to the current working directory). From bcannon at users.sourceforge.net Tue Sep 21 00:33:24 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Tue Sep 21 00:33:27 2004 Subject: [Python-checkins] python/dist/src/Misc vimrc,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24766/Misc Modified Files: vimrc Log Message: Add a commented-out recipe on making trailing whitespace explicit. If people think this is not too intrusive it could be uncommented. Index: vimrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/vimrc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- vimrc 19 Sep 2004 05:43:13 -0000 1.1 +++ vimrc 20 Sep 2004 22:33:21 -0000 1.2 @@ -76,3 +76,10 @@ " Automatically indent: ``filetype indent on`` " Fold based on indentation: ``set foldmethod=indent`` + +" Make trailing whitespace explicit: +"highlight WhitespaceEOL ctermbg=red guibg=red +"match WhitespaceEOL /\s\+$/ +" or +"set list listchars=trail:- + From edloper at users.sourceforge.net Tue Sep 21 05:00:54 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 21 05:00:57 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13596/dist/src/Doc/lib Modified Files: libdoctest.tex Log Message: - Updated docs to reflect changes in 2.4. - Reorganized the documentation - Shifted focus a little more towards "literate testing" - Documented new functions and classes: - testfile() - Example, DocTest - DocTestParser, DocTestFinder, DocTestRunner, OutputChecker - DocFileSuite - DebugRunner, DocTestFailure, UnexpectedException - register_optionflag() Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.43 retrieving revision 1.44 diff -u -d -r1.43 -r1.44 --- libdoctest.tex 19 Sep 2004 01:16:44 -0000 1.43 +++ libdoctest.tex 21 Sep 2004 03:00:51 -0000 1.44 @@ -1,22 +1,33 @@ \section{\module{doctest} --- - Test docstrings represent reality} + Test interactive Python examples} \declaremodule{standard}{doctest} \moduleauthor{Tim Peters}{tim_one@users.sourceforge.net} \sectionauthor{Tim Peters}{tim_one@users.sourceforge.net} \sectionauthor{Moshe Zadka}{moshez@debian.org} +\sectionauthor{Edward Loper}{edloper@users.sourceforge.net} -\modulesynopsis{A framework for verifying examples in docstrings.} [...1361 lines suppressed...] +By interleaving prose and examples, it becomes much easier to keep +track of what's actually being tested, and why. When a test fails, +the prose descriptions makes it much easier to figure out what the +problem is, and how it should be fixed. Regression testing is best +confined to dedicated objects or files. There are several options for +organizing regressions: + +\begin{itemize} +\item Define functions named \code{_regrtest_\textit{topic}} that + consist of single docstrings, containing test cases for the + named topics. These functions can be included in the same file + as the module, or separated out into a separate test file. +\item Define a \code{__test__} dictionary mapping from regression test + topics to docstrings containing test cases. +\item Write a text file containing test cases as interactive examples, + and test that file using \function{testfunc()}. +\end{itemize} + + + From edloper at users.sourceforge.net Tue Sep 21 05:20:37 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 21 05:20:39 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_doctest.py, 1.48, 1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17277/Lib/test Modified Files: test_doctest.py Log Message: - Changed SampleClass docstrings to test docstring parsing a little more thouroughly. Index: test_doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v retrieving revision 1.48 retrieving revision 1.49 diff -u -d -r1.48 -r1.49 --- test_doctest.py 19 Sep 2004 17:19:33 -0000 1.48 +++ test_doctest.py 21 Sep 2004 03:20:34 -0000 1.49 @@ -25,6 +25,17 @@ """ >>> print 1 1 + + >>> # comments get ignored. so are empty PS1 and PS2 prompts: + >>> + ... + + Multiline example: + >>> sc = SampleClass(3) + >>> for i in range(10): + ... sc = sc.double() + ... print sc.get(), + 6 12 24 48 96 192 384 768 1536 3072 """ def __init__(self, val): """ @@ -411,7 +422,7 @@ >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) - 1 SampleClass + 3 SampleClass 3 SampleClass.NestedClass 1 SampleClass.NestedClass.__init__ 1 SampleClass.__init__ @@ -443,7 +454,7 @@ >>> m = new.module('some_module') >>> def triple(val): ... ''' - ... >>> print tripple(11) + ... >>> print triple(11) ... 33 ... ''' ... return val*3 @@ -468,7 +479,7 @@ >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) 1 some_module - 1 some_module.SampleClass + 3 some_module.SampleClass 3 some_module.SampleClass.NestedClass 1 some_module.SampleClass.NestedClass.__init__ 1 some_module.SampleClass.__init__ @@ -513,7 +524,7 @@ >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) - 1 SampleClass + 3 SampleClass 3 SampleClass.NestedClass 1 SampleClass.NestedClass.__init__ 1 SampleClass.__init__ @@ -530,7 +541,7 @@ >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) - 1 SampleClass + 3 SampleClass 3 SampleClass.NestedClass 1 SampleClass.NestedClass.__init__ 0 SampleClass.NestedClass.get @@ -548,7 +559,7 @@ >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) - 1 SampleClass + 3 SampleClass 1 SampleClass.__init__ 2 SampleClass.a_classmethod 1 SampleClass.a_property @@ -574,7 +585,7 @@ >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) - 1 SampleClass + 3 SampleClass Line numbers ~~~~~~~~~~~~ From edloper at users.sourceforge.net Tue Sep 21 05:24:41 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 21 05:24:44 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.108,1.109 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17990/Lib Modified Files: doctest.py Log Message: - Minor docstring fixes. - Simplified code to find names for file-based tests. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.108 retrieving revision 1.109 diff -u -d -r1.108 -r1.109 --- doctest.py 20 Sep 2004 19:52:34 -0000 1.108 +++ doctest.py 21 Sep 2004 03:24:24 -0000 1.109 @@ -479,6 +479,7 @@ # Restore stdout. sys.stdout = save_stdout +# [XX] Normalize with respect to os.path.pardir? def _module_relative_path(module, path): if not inspect.ismodule(module): raise TypeError, 'Expected a module: %r' % module @@ -1995,8 +1996,8 @@ os-specific path. The path may be absolute or relative (to the current working directory). - Optional keyword arg "name" gives the name of the file; by default - use the file's name. + Optional keyword arg "name" gives the name of the test; by default + use the file's basename. Optional keyword argument "package" is a Python package or the name of a Python package whose directory should be used as the @@ -2059,7 +2060,7 @@ # If no name was given, then use the file's name. if name is None: - name = os.path.split(filename)[-1] + name = os.path.basename(filename) # Assemble the globals. if globs is None: @@ -2385,20 +2386,14 @@ A number of options may be provided as keyword arguments: - package - The name of a Python package. Text-file paths will be - interpreted relative to the directory containing this package. - The package may be supplied as a package object or as a dotted - package name. - setUp - The name of a set-up function. This is called before running the + A set-up function. This is called before running the tests in each file. The setUp function will be passed a DocTest object. The setUp function can access the test globals as the globs attribute of the test passed. tearDown - The name of a tear-down function. This is called after running the + A tear-down function. This is called after running the tests in each file. The tearDown function will be passed a DocTest object. The tearDown function can access the test globals as the globs attribute of the test passed. @@ -2465,8 +2460,7 @@ path = _module_relative_path(package, path) # Find the file and read it. - name = os.path.split(path)[-1] - + name = os.path.basename(path) doc = open(path).read() # Convert it to a test, and wrap it in a DocFileCase. @@ -2505,13 +2499,13 @@ "module_relative" is False. setUp - The name of a set-up function. This is called before running the + A set-up function. This is called before running the tests in each file. The setUp function will be passed a DocTest object. The setUp function can access the test globals as the globs attribute of the test passed. tearDown - The name of a tear-down function. This is called after running the + A tear-down function. This is called after running the tests in each file. The tearDown function will be passed a DocTest object. The tearDown function can access the test globals as the globs attribute of the test passed. From kbk at users.sourceforge.net Wed Sep 22 06:52:35 2004 From: kbk at users.sourceforge.net (kbk@users.sourceforge.net) Date: Wed Sep 22 06:52:39 2004 Subject: [Python-checkins] python/dist/src/Lib/idlelib PyShell.py, 1.81.4.3, 1.81.4.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/idlelib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21018 Modified Files: Tag: release23-maint PyShell.py Log Message: There was an error in the Tk error dialog fix at Rev 1.81.4.3 which caused starting w/o the subprocess to fail. This is the same error in the 2.4 version which was corrected at Rev 1.85, but missed in the backport! Thanks to Hans Gubitz for noticing this. M PyShell.py Index: PyShell.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/idlelib/PyShell.py,v retrieving revision 1.81.4.3 retrieving revision 1.81.4.4 diff -u -d -r1.81.4.3 -r1.81.4.4 --- PyShell.py 6 Jun 2004 17:41:41 -0000 1.81.4.3 +++ PyShell.py 22 Sep 2004 04:52:33 -0000 1.81.4.4 @@ -926,7 +926,7 @@ client = self.interp.start_subprocess() if not client: self.close() - return None + return False else: nosub = "==== No Subprocess ====" self.write("Python %s on %s\n%s\n%s\nIDLE %s %s\n" % @@ -935,7 +935,7 @@ self.showprompt() import Tkinter Tkinter._default_root = None # 03Jan04 KBK What's this? - return client + return True def readline(self): save = self.reading From vsajip at users.sourceforge.net Wed Sep 22 14:39:35 2004 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Wed Sep 22 14:39:42 2004 Subject: [Python-checkins] python/dist/src/Lib/logging __init__.py, 1.19, 1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23470 Modified Files: __init__.py Log Message: Added getLoggerClass() Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/__init__.py,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- __init__.py 4 Aug 2004 08:38:08 -0000 1.19 +++ __init__.py 22 Sep 2004 12:39:26 -0000 1.20 @@ -36,8 +36,8 @@ __author__ = "Vinay Sajip " __status__ = "beta" -__version__ = "0.4.9.3" -__date__ = "08 July 2004" +__version__ = "0.4.9.4" +__date__ = "22 September 2004" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -689,13 +689,14 @@ """ try: msg = self.format(record) + fs = "%s\n" if not hasattr(types, "UnicodeType"): #if no unicode support... - self.stream.write("%s\n" % msg) + self.stream.write(fs % msg) else: try: - self.stream.write("%s\n" % msg) + self.stream.write(fs % msg) except UnicodeError: - self.stream.write("%s\n" % msg.encode("UTF-8")) + self.stream.write(fs % msg.encode("UTF-8")) self.flush() except: self.handleError(record) @@ -763,6 +764,13 @@ global _loggerClass _loggerClass = klass +def getLoggerClass(): + """ + Return the class to be used when instantiating a logger. + """ + + return _loggerClass + class Manager: """ There is [under normal circumstances] just one Manager instance, which @@ -780,7 +788,8 @@ def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it - if it doesn't yet exist. + if it doesn't yet exist. This name is a dot-separated hierarchical + name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created @@ -879,12 +888,6 @@ """ self.level = level -# def getRoot(self): -# """ -# Get the root of the logger hierarchy. -# """ -# return Logger.root - def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. From vsajip at users.sourceforge.net Wed Sep 22 14:55:18 2004 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Wed Sep 22 14:55:21 2004 Subject: [Python-checkins] python/dist/src/Doc/lib liblogging.tex,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26944 Modified Files: liblogging.tex Log Message: Added getLoggerClass() Index: liblogging.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liblogging.tex,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- liblogging.tex 31 Aug 2004 10:21:51 -0000 1.24 +++ liblogging.tex 22 Sep 2004 12:55:16 -0000 1.25 @@ -144,6 +144,19 @@ parts of an application. \end{funcdesc} +\begin{funcdesc}{getLoggerClass}{} +Return either the standard \class{Logger} class, or the last class passed to +\function{setLoggerClass()}. This function may be called from within a new +class definition, to ensure that installing a customised \class{Logger} class +will not undo customisations already applied by other code. For example: + +\begin{verbatim} + class MyLogger(logging.getLoggerClass()): + # ... override behaviour here +\end{verbatim} + +\end{funcdesc} + \begin{funcdesc}{debug}{msg\optional{, *args\optional{, **kwargs}}} Logs a message with level \constant{DEBUG} on the root logger. The \var{msg} is the message format string, and the \var{args} are the From rhettinger at users.sourceforge.net Wed Sep 22 19:17:34 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 22 19:17:37 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1138,1.1139 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18184/Misc Modified Files: NEWS Log Message: Bug #1030125: rfc822 __iter__ problem Add iteration support to the Message class. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1138 retrieving revision 1.1139 diff -u -d -r1.1138 -r1.1139 --- NEWS 20 Sep 2004 06:17:46 -0000 1.1138 +++ NEWS 22 Sep 2004 17:17:29 -0000 1.1139 @@ -21,6 +21,7 @@ Library ------- +- rfc822 Messages now support iteration. - The (undocumented) tarfile.Tarfile.membernames has been removed; applications should use the getmember function. From rhettinger at users.sourceforge.net Wed Sep 22 19:17:34 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 22 19:17:38 2004 Subject: [Python-checkins] python/dist/src/Lib rfc822.py,1.77,1.78 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18184/Lib Modified Files: rfc822.py Log Message: Bug #1030125: rfc822 __iter__ problem Add iteration support to the Message class. Index: rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rfc822.py,v retrieving revision 1.77 retrieving revision 1.78 diff -u -d -r1.77 -r1.78 --- rfc822.py 7 Aug 2004 16:38:38 -0000 1.77 +++ rfc822.py 22 Sep 2004 17:17:31 -0000 1.78 @@ -444,6 +444,9 @@ """Determine whether a message contains the named header.""" return name.lower() in self.dict + def __iter__(self): + return iter(self.dict) + def keys(self): """Get all of a message's header field names.""" return self.dict.keys() From rhettinger at users.sourceforge.net Wed Sep 22 19:17:35 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 22 19:17:40 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_rfc822.py, 1.21, 1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18184/Lib/test Modified Files: test_rfc822.py Log Message: Bug #1030125: rfc822 __iter__ problem Add iteration support to the Message class. Index: test_rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_rfc822.py,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- test_rfc822.py 7 Aug 2004 16:38:40 -0000 1.21 +++ test_rfc822.py 22 Sep 2004 17:17:32 -0000 1.22 @@ -176,6 +176,17 @@ 'foo', [('', 'guido@[132.151.1.21]')]) + def test_iter(self): + m = rfc822.Message(StringIO( + 'Date: Wed, 13 Jan 1999 23:57:35 -0500\n' + 'From: Guido van Rossum \n' + 'To: "Guido van\n' + '\t : Rossum" \n' + 'Subject: test2\n' + '\n' + 'test2\n' )) + self.assertEqual(sorted(m), ['date', 'from', 'subject', 'to']) + def test_rfc2822_phrases(self): # RFC 2822 (the update to RFC 822) specifies that dots in phrases are # obsolete syntax, which conforming programs MUST recognize but NEVER From rhettinger at users.sourceforge.net Wed Sep 22 20:03:57 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 22 20:04:00 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1139,1.1140 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28969 Modified Files: NEWS Log Message: Clarify that iteration is over headers, not Mime elements. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1139 retrieving revision 1.1140 diff -u -d -r1.1139 -r1.1140 --- NEWS 22 Sep 2004 17:17:29 -0000 1.1139 +++ NEWS 22 Sep 2004 18:03:47 -0000 1.1140 @@ -21,7 +21,8 @@ Library ------- -- rfc822 Messages now support iteration. + +- rfc822 Messages now support iterating over the headers. - The (undocumented) tarfile.Tarfile.membernames has been removed; applications should use the getmember function. From rhettinger at users.sourceforge.net Wed Sep 22 20:44:27 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 22 20:44:30 2004 Subject: [Python-checkins] python/dist/src/Python compile.c, 2.326, 2.327 import.c, 2.237, 2.238 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4038/Python Modified Files: compile.c import.c Log Message: SF patch #1031667: Fold tuples of constants into a single constant Example: >>> import dis >>> dis.dis(compile('1,2,3', '', 'eval')) 0 0 LOAD_CONST 3 ((1, 2, 3)) 3 RETURN_VALUE Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.326 retrieving revision 2.327 diff -u -d -r2.326 -r2.327 --- compile.c 31 Aug 2004 10:07:13 -0000 2.326 +++ compile.c 22 Sep 2004 18:44:20 -0000 2.327 @@ -380,6 +380,8 @@ } } +/* Begin: Peephole optimizations ----------------------------------------- */ + #define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1])) #define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD) #define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP) @@ -388,6 +390,56 @@ #define CODESIZE(op) (HAS_ARG(op) ? 3 : 1) #define ISBASICBLOCK(blocks, start, bytes) (blocks[start]==blocks[start+bytes-1]) +/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n + with LOAD_CONST (c1, c2, ... cn). + The consts table must still be in list form so that the + new constant (c1, c2, ... cn) can be appended. + Called with codestr pointing to the first LOAD_CONST. + Bails out with no change if one or more of the LOAD_CONSTs is missing. */ +static int +tuple_of_constants(unsigned char *codestr, int n, PyObject *consts) +{ + PyObject *newconst, *constant; + int i, arg, len_consts; + + /* Pre-conditions */ + assert(PyList_CheckExact(consts)); + assert(codestr[0] == LOAD_CONST); + assert(codestr[n*3] == BUILD_TUPLE); + assert(GETARG(codestr, (n*3)) == n); + + /* Verify chain of n load_constants */ + for (i=0 ; i= 255. + + Optimizations are restricted to simple transformations occuring within a + single basic block. All transformations keep the code size the same or + smaller. For those that reduce size, the gaps are initially filled with + NOPs. Later those NOPs are removed and the jump addresses retargeted in + a single pass. Line numbering is adjusted accordingly. */ + static PyObject * optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *lineno_obj) { @@ -447,7 +514,7 @@ /* Avoid situations where jump retargeting could overflow */ codelen = PyString_Size(code); - if (codelen > 32000) + if (codelen > 32700) goto exitUnchanged; /* Make a modifiable copy of the code string */ @@ -464,7 +531,7 @@ blocks = markblocks(codestr, codelen); if (blocks == NULL) goto exitUnchanged; - assert(PyTuple_Check(consts)); + assert(PyList_Check(consts)); for (i=0, nops=0 ; i= 0 && + codestr[h] == LOAD_CONST && + ISBASICBLOCK(blocks, h, 3*(j+1)) && + tuple_of_constants(&codestr[h], j, consts)) { + nops += 3 * j; + break; + } + /* Intentional fallthrough */ case BUILD_LIST: j = GETARG(codestr, i); if (codestr[i+3] != UNPACK_SEQUENCE || @@ -610,8 +688,8 @@ /* Replace RETURN LOAD_CONST None RETURN with just RETURN */ case RETURN_VALUE: - if (i+4 >= codelen || - codestr[i+4] != RETURN_VALUE || + if (i+4 >= codelen || + codestr[i+4] != RETURN_VALUE || !ISBASICBLOCK(blocks,i,5)) continue; memset(codestr+i+1, NOP, 4); @@ -677,6 +755,8 @@ return code; } +/* End: Peephole optimizations ----------------------------------------- */ + PyCodeObject * PyCode_New(int argcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, @@ -4899,7 +4979,6 @@ if (sc.c_errors == 0) { PyObject *consts, *names, *varnames, *filename, *name, *freevars, *cellvars, *code; - consts = PyList_AsTuple(sc.c_consts); names = PyList_AsTuple(sc.c_names); varnames = PyList_AsTuple(sc.c_varnames); cellvars = dict_keys_inorder(sc.c_cellvars, 0); @@ -4907,7 +4986,8 @@ PyTuple_GET_SIZE(cellvars)); filename = PyString_InternFromString(sc.c_filename); name = PyString_InternFromString(sc.c_name); - code = optimize_code(sc.c_code, consts, names, sc.c_lnotab); + code = optimize_code(sc.c_code, sc.c_consts, names, sc.c_lnotab); + consts = PyList_AsTuple(sc.c_consts); if (!PyErr_Occurred()) co = PyCode_New(sc.c_argcount, sc.c_nlocals, Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.237 retrieving revision 2.238 diff -u -d -r2.237 -r2.238 --- import.c 23 Aug 2004 23:37:48 -0000 2.237 +++ import.c 22 Sep 2004 18:44:21 -0000 2.238 @@ -49,8 +49,9 @@ Python 2.3a0: 62011 (!) Python 2.4a0: 62041 Python 2.4a3: 62051 + Python 2.4b1: 62061 */ -#define MAGIC (62051 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (62061 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the value of this global to accommodate for alterations of how the From rhettinger at users.sourceforge.net Wed Sep 22 20:44:42 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 22 20:44:44 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_peepholer.py, 1.2, 1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4038/Lib/test Modified Files: test_peepholer.py Log Message: SF patch #1031667: Fold tuples of constants into a single constant Example: >>> import dis >>> dis.dis(compile('1,2,3', '', 'eval')) 0 0 LOAD_CONST 3 ((1, 2, 3)) 3 RETURN_VALUE Index: test_peepholer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_peepholer.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- test_peepholer.py 26 Aug 2004 05:23:19 -0000 1.2 +++ test_peepholer.py 22 Sep 2004 18:44:08 -0000 1.3 @@ -64,15 +64,25 @@ def test_pack_unpack(self): for line, elem in ( - ('a, = 1,', 'LOAD_CONST',), - ('a, b = 1, 2', 'ROT_TWO',), - ('a, b, c = 1, 2, 3', 'ROT_THREE',), + ('a, = a,', 'LOAD_CONST',), + ('a, b = a, b', 'ROT_TWO',), + ('a, b, c = a, b, c', 'ROT_THREE',), ): asm = dis_single(line) self.assert_(elem in asm) self.assert_('BUILD_TUPLE' not in asm) self.assert_('UNPACK_TUPLE' not in asm) + def test_folding_of_tuples_of_constants(self): + for line, elem in ( + ('a = 1,2,3', '((1, 2, 3))',), + ('("a","b","c")', "(('a', 'b', 'c'))",), + ('a,b,c = 1,2,3', '((1, 2, 3))',), + ): + asm = dis_single(line) + self.assert_(elem in asm) + self.assert_('BUILD_TUPLE' not in asm) + def test_elim_extra_return(self): # RETURN LOAD_CONST None RETURN --> RETURN def f(x): From rhettinger at users.sourceforge.net Wed Sep 22 20:44:53 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 22 20:44:55 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1140,1.1141 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4038/Misc Modified Files: NEWS Log Message: SF patch #1031667: Fold tuples of constants into a single constant Example: >>> import dis >>> dis.dis(compile('1,2,3', '', 'eval')) 0 0 LOAD_CONST 3 ((1, 2, 3)) 3 RETURN_VALUE Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1140 retrieving revision 1.1141 diff -u -d -r1.1140 -r1.1141 --- NEWS 22 Sep 2004 18:03:47 -0000 1.1140 +++ NEWS 22 Sep 2004 18:44:09 -0000 1.1141 @@ -12,6 +12,9 @@ Core and builtins ----------------- +- The bytecode optimizer now folds tuples of constants into a single + constant. + - PyLong_AsUnsignedLong[Mask] now support int objects as well. Extension modules From tim_one at users.sourceforge.net Thu Sep 23 03:56:04 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 03:56:07 2004 Subject: [Python-checkins] python/dist/src/Include longobject.h,2.30,2.31 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29278/Include Modified Files: longobject.h Log Message: Removed redundant declaration of _PyLong_NumBits(). Index: longobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v retrieving revision 2.30 retrieving revision 2.31 diff -u -d -r2.30 -r2.31 --- longobject.h 17 Apr 2003 18:55:11 -0000 2.30 +++ longobject.h 23 Sep 2004 01:56:02 -0000 2.31 @@ -53,7 +53,6 @@ PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); -PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); /* _PyLong_NumBits. Return the number of bits needed to represent the absolute value of a long. For example, this returns 1 for 1 and -1, 2 for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. From tim_one at users.sourceforge.net Thu Sep 23 04:39:39 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 04:39:41 2004 Subject: [Python-checkins] python/dist/src/Include object.h,2.129,2.130 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3702/Include Modified Files: object.h Log Message: A static swapped_op[] array was defined in 3 different C files, & I think I need to define it again. Bite the bullet and define it once as an extern, _Py_SwappedOp[]. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.129 retrieving revision 2.130 diff -u -d -r2.129 -r2.130 --- object.h 1 Sep 2004 07:02:42 -0000 2.129 +++ object.h 23 Sep 2004 02:39:36 -0000 2.130 @@ -667,6 +667,11 @@ #define Py_GT 4 #define Py_GE 5 +/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. + * Defined in object.c. + */ +PyAPI_DATA(int) _Py_SwappedOp[]; + /* Define staticforward and statichere for source compatibility with old C extensions. From tim_one at users.sourceforge.net Thu Sep 23 04:39:39 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 04:39:43 2004 Subject: [Python-checkins] python/dist/src/Objects classobject.c, 2.175, 2.176 object.c, 2.222, 2.223 typeobject.c, 2.263, 2.264 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3702/Objects Modified Files: classobject.c object.c typeobject.c Log Message: A static swapped_op[] array was defined in 3 different C files, & I think I need to define it again. Bite the bullet and define it once as an extern, _Py_SwappedOp[]. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.175 retrieving revision 2.176 diff -u -d -r2.175 -r2.176 --- classobject.c 3 Aug 2004 10:21:03 -0000 2.175 +++ classobject.c 23 Sep 2004 02:39:36 -0000 2.176 @@ -1873,9 +1873,6 @@ return res; } -/* Map rich comparison operators to their swapped version, e.g. LT --> GT */ -static int swapped_op[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE}; - static PyObject * instance_richcompare(PyObject *v, PyObject *w, int op) { @@ -1889,7 +1886,7 @@ } if (PyInstance_Check(w)) { - res = half_richcompare(w, v, swapped_op[op]); + res = half_richcompare(w, v, _Py_SwappedOp[op]); if (res != Py_NotImplemented) return res; Py_DECREF(res); Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.222 retrieving revision 2.223 diff -u -d -r2.222 -r2.223 --- object.c 14 Sep 2004 17:09:47 -0000 2.222 +++ object.c 23 Sep 2004 02:39:37 -0000 2.223 @@ -476,7 +476,7 @@ ? (t)->tp_richcompare : NULL) /* Map rich comparison operators to their swapped version, e.g. LT --> GT */ -static int swapped_op[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE}; +extern int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE}; /* Try a genuine rich comparison, returning an object. Return: NULL for exception; @@ -494,7 +494,7 @@ if (v->ob_type != w->ob_type && PyType_IsSubtype(w->ob_type, v->ob_type) && (f = RICHCOMPARE(w->ob_type)) != NULL) { - res = (*f)(w, v, swapped_op[op]); + res = (*f)(w, v, _Py_SwappedOp[op]); if (res != Py_NotImplemented) return res; Py_DECREF(res); @@ -506,7 +506,7 @@ Py_DECREF(res); } if ((f = RICHCOMPARE(w->ob_type)) != NULL) { - return (*f)(w, v, swapped_op[op]); + return (*f)(w, v, _Py_SwappedOp[op]); } res = Py_NotImplemented; Py_INCREF(res); @@ -1703,7 +1703,7 @@ assert(result); if (!PyList_Check(result)) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_TypeError, "Expected keys() to be a list."); goto error; } Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.263 retrieving revision 2.264 diff -u -d -r2.263 -r2.264 --- typeobject.c 18 Aug 2004 13:16:54 -0000 2.263 +++ typeobject.c 23 Sep 2004 02:39:37 -0000 2.264 @@ -4638,9 +4638,6 @@ return res; } -/* Map rich comparison operators to their swapped version, e.g. LT --> GT */ -static int swapped_op[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE}; - static PyObject * slot_tp_richcompare(PyObject *self, PyObject *other, int op) { @@ -4653,7 +4650,7 @@ Py_DECREF(res); } if (other->ob_type->tp_richcompare == slot_tp_richcompare) { - res = half_richcompare(other, self, swapped_op[op]); + res = half_richcompare(other, self, _Py_SwappedOp[op]); if (res != Py_NotImplemented) { return res; } From pje at users.sourceforge.net Thu Sep 23 06:06:42 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Thu Sep 23 06:06:45 2004 Subject: [Python-checkins] python/nondist/peps pep-0302.txt,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18527 Modified Files: pep-0302.txt Log Message: Fix specification error that makes it impossible for 'reload()' to work correctly with PEP 302 module loaders. See also SF#1029475, and: http://mail.python.org/pipermail/python-dev/2004-September/048970.html Index: pep-0302.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0302.txt,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- pep-0302.txt 2 Jan 2003 18:47:04 -0000 1.13 +++ pep-0302.txt 23 Sep 2004 04:06:40 -0000 1.14 @@ -240,16 +240,22 @@ The load_module() method has a few responsibilities that it must fulfill *before* it runs any code: - - It must create the module object. From Python this can be done + - It must use the existing module object from sys.modules, if one + exists. (Otherwise, the reload() builtin will not work + correctly.) + + - If a module object is not already present in sys.modules, the + loader must create a module object. From Python this can be done via the new.module() function, the imp.new_module() function or via the module type object; from C with the PyModule_New() function or the PyImport_ModuleAdd() function. The latter also does the following step: - - It must add the module to sys.modules. This is crucial because - the module code may (directly or indirectly) import itself; adding - it to sys.modules beforehand prevents unbounded recursion in the - worst case and multiple loading in the best. + - It must add the module to sys.modules, if it was not already + present there. This is crucial because the module code may + (directly or indirectly) import itself; adding it to sys.modules + beforehand prevents unbounded recursion in the worst case and + multiple loading in the best. - The __file__ attribute must be set. This must be a string, but it may be a dummy value, for example "". The privilege of From pje at users.sourceforge.net Thu Sep 23 06:37:38 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Thu Sep 23 06:37:42 2004 Subject: [Python-checkins] python/dist/src/Python import.c,2.238,2.239 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24775/Python Modified Files: import.c Log Message: Fix for SF bug #1029475 : reload() doesn't work with PEP 302 loaders. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.238 retrieving revision 2.239 diff -u -d -r2.238 -r2.239 --- import.c 22 Sep 2004 18:44:21 -0000 2.238 +++ import.c 23 Sep 2004 04:37:36 -0000 2.239 @@ -2252,7 +2252,7 @@ PyImport_ReloadModule(PyObject *m) { PyObject *modules = PyImport_GetModuleDict(); - PyObject *path = NULL; + PyObject *path = NULL, *loader = NULL; char *name, *subname; char buf[MAXPATHLEN+1]; struct filedescr *fdp; @@ -2295,11 +2295,17 @@ PyErr_Clear(); } buf[0] = '\0'; - fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, NULL); + fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, &loader); Py_XDECREF(path); - if (fdp == NULL) + + if (fdp == NULL) { + Py_XDECREF(loader); return NULL; - newm = load_module(name, fp, buf, fdp->type, NULL); + } + + newm = load_module(name, fp, buf, fdp->type, loader); + Py_XDECREF(loader); + if (fp) fclose(fp); if (newm == NULL) { From pje at users.sourceforge.net Thu Sep 23 06:37:38 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Thu Sep 23 06:37:43 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_importhooks.py, 1.2, 1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24775/Lib/test Modified Files: test_importhooks.py Log Message: Fix for SF bug #1029475 : reload() doesn't work with PEP 302 loaders. Index: test_importhooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_importhooks.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- test_importhooks.py 17 Feb 2003 14:51:41 -0000 1.2 +++ test_importhooks.py 23 Sep 2004 04:37:35 -0000 1.3 @@ -12,7 +12,13 @@ return __file__ """ +reload_src = test_src+"""\ +reloaded = True +""" + test_co = compile(test_src, "", "exec") +reload_co = compile(reload_src, "", "exec") + test_path = "!!!_test_!!!" @@ -32,6 +38,7 @@ "hooktestpackage": (True, test_co), "hooktestpackage.sub": (True, test_co), "hooktestpackage.sub.subber": (False, test_co), + "reloadmodule": (False, test_co), } def __init__(self, path=test_path): @@ -52,8 +59,7 @@ def load_module(self, fullname): ispkg, code = self.modules[fullname] - mod = imp.new_module(fullname) - sys.modules[fullname] = mod + mod = sys.modules.setdefault(fullname,imp.new_module(fullname)) mod.__file__ = "<%s>" % self.__class__.__name__ mod.__loader__ = self if ispkg: @@ -163,6 +169,14 @@ self.assertEqual(hooktestpackage.sub.__loader__, importer) self.assertEqual(hooktestpackage.sub.subber.__loader__, importer) + TestImporter.modules['reloadmodule'] = (False, test_co) + import reloadmodule + self.failIf(hasattr(reloadmodule,'reloaded')) + + TestImporter.modules['reloadmodule'] = (False, reload_co) + reload(reloadmodule) + self.failUnless(hasattr(reloadmodule,'reloaded')) + def testMetaPath(self): i = MetaImporter() sys.meta_path.append(i) From pje at users.sourceforge.net Thu Sep 23 07:19:29 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Thu Sep 23 07:19:33 2004 Subject: [Python-checkins] python/dist/src/Python import.c, 2.222.6.3, 2.222.6.4 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31468/Python Modified Files: Tag: release23-maint import.c Log Message: Fix for SF bug #1029475 : reload() doesn't work with PEP 302 loaders. (Backport to 2.3 maintenance branch.) Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.222.6.3 retrieving revision 2.222.6.4 diff -u -d -r2.222.6.3 -r2.222.6.4 --- import.c 7 Jun 2004 14:59:59 -0000 2.222.6.3 +++ import.c 23 Sep 2004 05:19:27 -0000 2.222.6.4 @@ -2310,7 +2310,7 @@ PyImport_ReloadModule(PyObject *m) { PyObject *modules = PyImport_GetModuleDict(); - PyObject *path = NULL; + PyObject *path = NULL, *loader = NULL; char *name, *subname; char buf[MAXPATHLEN+1]; struct filedescr *fdp; @@ -2352,11 +2352,14 @@ PyErr_Clear(); } buf[0] = '\0'; - fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, NULL); + fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, &loader); Py_XDECREF(path); - if (fdp == NULL) + if (fdp == NULL) { + Py_XDECREF(loader); return NULL; - m = load_module(name, fp, buf, fdp->type, NULL); + } + m = load_module(name, fp, buf, fdp->type, loader); + Py_XDECREF(loader); if (fp) fclose(fp); return m; From pje at users.sourceforge.net Thu Sep 23 07:19:29 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Thu Sep 23 07:19:34 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_importhooks.py, 1.2, 1.2.16.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31468/Lib/test Modified Files: Tag: release23-maint test_importhooks.py Log Message: Fix for SF bug #1029475 : reload() doesn't work with PEP 302 loaders. (Backport to 2.3 maintenance branch.) Index: test_importhooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_importhooks.py,v retrieving revision 1.2 retrieving revision 1.2.16.1 diff -u -d -r1.2 -r1.2.16.1 --- test_importhooks.py 17 Feb 2003 14:51:41 -0000 1.2 +++ test_importhooks.py 23 Sep 2004 05:19:26 -0000 1.2.16.1 @@ -12,7 +12,13 @@ return __file__ """ +reload_src = test_src+"""\ +reloaded = True +""" + test_co = compile(test_src, "", "exec") +reload_co = compile(reload_src, "", "exec") + test_path = "!!!_test_!!!" @@ -32,6 +38,7 @@ "hooktestpackage": (True, test_co), "hooktestpackage.sub": (True, test_co), "hooktestpackage.sub.subber": (False, test_co), + "reloadmodule": (False, test_co), } def __init__(self, path=test_path): @@ -52,8 +59,7 @@ def load_module(self, fullname): ispkg, code = self.modules[fullname] - mod = imp.new_module(fullname) - sys.modules[fullname] = mod + mod = sys.modules.setdefault(fullname,imp.new_module(fullname)) mod.__file__ = "<%s>" % self.__class__.__name__ mod.__loader__ = self if ispkg: @@ -163,6 +169,14 @@ self.assertEqual(hooktestpackage.sub.__loader__, importer) self.assertEqual(hooktestpackage.sub.subber.__loader__, importer) + TestImporter.modules['reloadmodule'] = (False, test_co) + import reloadmodule + self.failIf(hasattr(reloadmodule,'reloaded')) + + TestImporter.modules['reloadmodule'] = (False, reload_co) + reload(reloadmodule) + self.failUnless(hasattr(reloadmodule,'reloaded')) + def testMetaPath(self): i = MetaImporter() sys.meta_path.append(i) From rhettinger at users.sourceforge.net Thu Sep 23 08:43:27 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 23 08:43:31 2004 Subject: [Python-checkins] python/dist/src/Lib StringIO.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13791 Modified Files: StringIO.py Log Message: Use local variables in StringIO.write(). Makes it easier on the eyes and a bit more snappy. Index: StringIO.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/StringIO.py,v retrieving revision 1.35 retrieving revision 1.36 diff -u -d -r1.35 -r1.36 --- StringIO.py 14 Mar 2004 07:54:37 -0000 1.35 +++ StringIO.py 23 Sep 2004 06:43:25 -0000 1.36 @@ -215,21 +215,22 @@ # Force s to be a string or unicode if not isinstance(s, basestring): s = str(s) - if self.pos == self.len: + spos = self.pos + slen = self.len + if spos == slen: self.buflist.append(s) - self.len = self.pos = self.pos + len(s) + self.len = self.pos = slen = spos = spos + len(s) return - if self.pos > self.len: - self.buflist.append('\0'*(self.pos - self.len)) - self.len = self.pos - newpos = self.pos + len(s) - if self.pos < self.len: + if spos > slen: + self.buflist.append('\0'*(spos - slen)) + slen = spos + newpos = spos + len(s) + if spos < slen: if self.buflist: self.buf += ''.join(self.buflist) - self.buflist = [] - self.buflist = [self.buf[:self.pos], s, self.buf[newpos:]] + self.buflist = [self.buf[:spos], s, self.buf[newpos:]] self.buf = '' - if newpos > self.len: + if newpos > slen: self.len = newpos else: self.buflist.append(s) From rhettinger at users.sourceforge.net Thu Sep 23 09:00:50 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 23 09:00:56 2004 Subject: [Python-checkins] python/dist/src/Lib StringIO.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17055 Modified Files: StringIO.py Log Message: Arghh, checked in wrong draft. Replacing with correct one. Index: StringIO.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/StringIO.py,v retrieving revision 1.36 retrieving revision 1.37 diff -u -d -r1.36 -r1.37 --- StringIO.py 23 Sep 2004 06:43:25 -0000 1.36 +++ StringIO.py 23 Sep 2004 07:00:47 -0000 1.37 @@ -219,7 +219,7 @@ slen = self.len if spos == slen: self.buflist.append(s) - self.len = self.pos = slen = spos = spos + len(s) + self.len = self.pos = spos + len(s) return if spos > slen: self.buflist.append('\0'*(spos - slen)) @@ -231,10 +231,11 @@ self.buflist = [self.buf[:spos], s, self.buf[newpos:]] self.buf = '' if newpos > slen: - self.len = newpos + slen = newpos else: self.buflist.append(s) - self.len = newpos + slen = newpos + self.len = slen self.pos = newpos def writelines(self, iterable): From rhettinger at users.sourceforge.net Thu Sep 23 09:27:42 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 23 09:27:44 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_itertools.py, 1.31, 1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22472/Lib/test Modified Files: test_itertools.py Log Message: Improve three recipes in the itertools docs. Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_itertools.py,v retrieving revision 1.31 retrieving revision 1.32 diff -u -d -r1.31 -r1.32 --- test_itertools.py 18 Jul 2004 17:34:03 -0000 1.31 +++ test_itertools.py 23 Sep 2004 07:27:39 -0000 1.32 @@ -746,15 +746,21 @@ >>> def all(seq, pred=bool): ... "Returns True if pred(x) is True for every element in the iterable" -... return False not in imap(pred, seq) +... for elem in ifilterfalse(pred, seq): +... return False +... return True >>> def any(seq, pred=bool): ... "Returns True if pred(x) is True for at least one element in the iterable" -... return True in imap(pred, seq) +... for elem in ifilter(pred, seq): +... return True +... return False >>> def no(seq, pred=bool): ... "Returns True if pred(x) is False for every element in the iterable" -... return True not in imap(pred, seq) +... for elem in ifilter(pred, seq): +... return False +... return True >>> def quantify(seq, pred=bool): ... "Count how many times the predicate is True in the sequence" From rhettinger at users.sourceforge.net Thu Sep 23 09:27:41 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 23 09:27:45 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libitertools.tex, 1.31, 1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22472/Doc/lib Modified Files: libitertools.tex Log Message: Improve three recipes in the itertools docs. Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libitertools.tex,v retrieving revision 1.31 retrieving revision 1.32 diff -u -d -r1.31 -r1.32 --- libitertools.tex 11 Jul 2004 13:20:11 -0000 1.31 +++ libitertools.tex 23 Sep 2004 07:27:39 -0000 1.32 @@ -458,15 +458,21 @@ def all(seq, pred=bool): "Returns True if pred(x) is True for every element in the iterable" - return False not in imap(pred, seq) + for elem in ifilterfalse(pred, seq): + return False + return True def any(seq, pred=bool): - "Returns True if pred(x) is True at least one element in the iterable" - return True in imap(pred, seq) + "Returns True if pred(x) is True for at least one element in the iterable" + for elem in ifilter(pred, seq): + return True + return False def no(seq, pred=bool): "Returns True if pred(x) is False for every element in the iterable" - return True not in imap(pred, seq) + for elem in ifilter(pred, seq): + return False + return True def quantify(seq, pred=bool): "Count how many times the predicate is True in the sequence" From tim_one at users.sourceforge.net Thu Sep 23 10:06:44 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 10:06:48 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1141,1.1142 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28365/Misc Modified Files: NEWS Log Message: SF bug #513866: Float/long comparison anomaly. When an integer is compared to a float now, the int isn't coerced to float. This avoids spurious overflow exceptions and insane results. This should compute correct results, without raising spurious exceptions, in all cases now -- although I expect that what happens when an int/long is compared to a NaN is still a platform accident. Note that we had potential problems here even with "short" ints, on boxes where sizeof(long)==8. There's #ifdef'ed code here to handle that, but I can't test it as intended. I tested it by changing the #ifdef to trigger on my 32-bit box instead. I suppose this is a bugfix candidate, but I won't backport it. It's long-winded (for speed) and messy (because the problem is messy). Note that this also depends on a previous 2.4 patch that introduced _Py_SwappedOp[] as an extern. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1141 retrieving revision 1.1142 diff -u -d -r1.1141 -r1.1142 --- NEWS 22 Sep 2004 18:44:09 -0000 1.1141 +++ NEWS 23 Sep 2004 08:06:37 -0000 1.1142 @@ -15,7 +15,14 @@ - The bytecode optimizer now folds tuples of constants into a single constant. -- PyLong_AsUnsignedLong[Mask] now support int objects as well. +- SF bug #513866: Float/long comparison anomaly. Prior to 2.4b1, when + an integer was compared to a float, the integer was coerced to a float. + That could yield spurious overflow errors (if the integer was very + large), and to anomalies such as + ``long(1e200)+1 == 1e200 == long(1e200)-1``. Coercion to float is no + longer performed, and cases like ``long(1e200)-1 < 1e200``, + ``long(1e200)+1 > 1e200`` and ``(1 << 20000) > 1e200`` are computed + correctly now. Extension modules ----------------- @@ -72,6 +79,8 @@ C API ----- +- PyLong_AsUnsignedLong[Mask] now support int objects as well. + - SF patch #998993: ``PyUnicode_DecodeUTF8Stateful`` and ``PyUnicode_DecodeUTF16Stateful`` have been added, which implement stateful decoding. From tim_one at users.sourceforge.net Thu Sep 23 10:06:44 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 10:06:49 2004 Subject: [Python-checkins] python/dist/src/Objects floatobject.c, 2.132, 2.133 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28365/Objects Modified Files: floatobject.c Log Message: SF bug #513866: Float/long comparison anomaly. When an integer is compared to a float now, the int isn't coerced to float. This avoids spurious overflow exceptions and insane results. This should compute correct results, without raising spurious exceptions, in all cases now -- although I expect that what happens when an int/long is compared to a NaN is still a platform accident. Note that we had potential problems here even with "short" ints, on boxes where sizeof(long)==8. There's #ifdef'ed code here to handle that, but I can't test it as intended. I tested it by changing the #ifdef to trigger on my 32-bit box instead. I suppose this is a bugfix candidate, but I won't backport it. It's long-winded (for speed) and messy (because the problem is messy). Note that this also depends on a previous 2.4 patch that introduced _Py_SwappedOp[] as an extern. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.132 retrieving revision 2.133 diff -u -d -r2.132 -r2.133 --- floatobject.c 8 Jul 2004 01:55:58 -0000 2.132 +++ floatobject.c 23 Sep 2004 08:06:40 -0000 2.133 @@ -354,38 +354,236 @@ return PyString_FromString(buf); } +/* Comparison is pretty much a nightmare. When comparing float to float, + * we do it as straightforwardly (and long-windedly) as conceivable, so + * that, e.g., Python x == y delivers the same result as the platform + * C x == y when x and/or y is a NaN. + * When mixing float with an integer type, there's no good *uniform* approach. + * Converting the double to an integer obviously doesn't work, since we + * may lose info from fractional bits. Converting the integer to a double + * also has two failure modes: (1) a long int may trigger overflow (too + * large to fit in the dynamic range of a C double); (2) even a C long may have + * more bits than fit in a C double (e.g., on a a 64-bit box long may have + * 63 bits of precision, but a C double probably has only 53), and then + * we can falsely claim equality when low-order integer bits are lost by + * coercion to double. So this part is painful too. + */ + static PyObject* float_richcompare(PyObject *v, PyObject *w, int op) { double i, j; int r = 0; - CONVERT_TO_DOUBLE(v, i); - CONVERT_TO_DOUBLE(w, j); + assert(PyFloat_Check(v)); + i = PyFloat_AS_DOUBLE(v); + + /* Switch on the type of w. Set i and j to doubles to be compared, + * and op to the richcomp to use. + */ + if (PyFloat_Check(w)) + j = PyFloat_AS_DOUBLE(w); + + else if (Py_IS_INFINITY(i)) { + /* XXX If we had a reliable way to check whether i is a + * XXX NaN, it would belong in this branch too. + */ + if (PyInt_Check(w) || PyLong_Check(w)) + /* The magnitude of i exceeds any finite integer, + * so it doesn't matter which int we compare i with. + */ + j = 0.0; + else + goto Unimplemented; + } + + else if (PyInt_Check(w)) { + long jj = PyInt_AS_LONG(w); + /* In the worst realistic case I can imagine, C double is a + * Cray single with 48 bits of precision, and long has 64 + * bits. + */ +#if SIZEOF_LONG > 4 + unsigned long abs = (unsigned long)(jj < 0 ? -jj : jj); + if (abs >> 48) { + /* Needs more than 48 bits. Make it take the + * PyLong path. + */ + PyObject *result; + PyObject *ww = PyLong_FromLong(jj); + + if (ww == NULL) + return NULL; + result = float_richcompare(v, ww, op); + Py_DECREF(ww); + return result; + } +#endif + j = (double)jj; + assert((long)j == jj); + } + + else if (PyLong_Check(w)) { + int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1; + int wsign = _PyLong_Sign(w); + size_t nbits; + double mant; + int exponent; + + if (vsign != wsign) { + /* Magnitudes are irrelevant -- the signs alone + * determine the outcome. + */ + i = (double)vsign; + j = (double)wsign; + goto Compare; + } + /* The signs are the same. */ + /* Convert w to a double if it fits. In particular, 0 fits. */ + nbits = _PyLong_NumBits(w); + if (nbits == (size_t)-1 && PyErr_Occurred()) { + /* This long is so large that size_t isn't big enough + * to hold the # of Python digits. Replace with + * little doubles that give the same outcome -- + * w is so large that its magnitude must exceed + * the magnitude of any finite float. + */ + PyErr_Clear(); + i = (double)vsign; + assert(wsign != 0); + j = wsign * 2.0; + goto Compare; + } + if (nbits <= 48) { + j = PyLong_AsDouble(w); + /* It's impossible that <= 48 bits overflowed. */ + assert(j != -1.0 || ! PyErr_Occurred()); + goto Compare; + } + assert(wsign != 0); /* else nbits was 0 */ + assert(vsign != 0); /* if vsign were 0, then since wsign is + * not 0, we would have taken the + * vsign != wsign branch at the start */ + /* We want to work with non-negative numbers. */ + if (vsign < 0) { + /* "Multiply both sides" by -1; this also swaps the + * comparator. + */ + i = -i; + op = _Py_SwappedOp[op]; + } + assert(i > 0.0); + mant = frexp(i, &exponent); + /* exponent is the # of bits in v before the radix point; + * we know that nbits (the # of bits in w) > 48 at this point + */ + if (exponent < 0 || (size_t)exponent < nbits) { + i = 1.0; + j = 2.0; + goto Compare; + } + if ((size_t)exponent > nbits) { + i = 2.0; + j = 1.0; + goto Compare; + } + /* v and w have the same number of bits before the radix + * point. Construct two longs that have the same comparison + * outcome. + */ + { + double fracpart; + double intpart; + PyObject *result = NULL; + PyObject *one = NULL; + PyObject *vv = NULL; + PyObject *ww = w; + + if (wsign < 0) { + ww = PyNumber_Negative(w); + if (ww == NULL) + goto Error; + } + else + Py_INCREF(ww); + fracpart = modf(i, &intpart); + vv = PyLong_FromDouble(intpart); + if (vv == NULL) + goto Error; + + if (fracpart != 0.0) { + /* Shift left, and or a 1 bit into vv + * to represent the lost fraction. + */ + PyObject *temp; + + one = PyInt_FromLong(1); + if (one == NULL) + goto Error; + + temp = PyNumber_Lshift(ww, one); + if (temp == NULL) + goto Error; + Py_DECREF(ww); + ww = temp; + + temp = PyNumber_Lshift(vv, one); + if (temp == NULL) + goto Error; + Py_DECREF(vv); + vv = temp; + + temp = PyNumber_Or(vv, one); + if (temp == NULL) + goto Error; + Py_DECREF(vv); + vv = temp; + } + + r = PyObject_RichCompareBool(vv, ww, op); + if (r < 0) + goto Error; + result = PyBool_FromLong(r); + Error: + Py_XDECREF(vv); + Py_XDECREF(ww); + Py_XDECREF(one); + return result; + } + } /* else if (PyLong_Check(w)) */ + + else /* w isn't float, int, or long */ + goto Unimplemented; + + Compare: PyFPE_START_PROTECT("richcompare", return NULL) switch (op) { case Py_EQ: - r = i==j; + r = i == j; break; case Py_NE: - r = i!=j; + r = i != j; break; case Py_LE: - r = i<=j; + r = i <= j; break; case Py_GE: - r = i>=j; + r = i >= j; break; case Py_LT: - r = ij; + r = i > j; break; } PyFPE_END_PROTECT(r) return PyBool_FromLong(r); + + Unimplemented: + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; } static long From tim_one at users.sourceforge.net Thu Sep 23 10:07:10 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 10:07:13 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_long.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28365/Lib/test Modified Files: test_long.py Log Message: SF bug #513866: Float/long comparison anomaly. When an integer is compared to a float now, the int isn't coerced to float. This avoids spurious overflow exceptions and insane results. This should compute correct results, without raising spurious exceptions, in all cases now -- although I expect that what happens when an int/long is compared to a NaN is still a platform accident. Note that we had potential problems here even with "short" ints, on boxes where sizeof(long)==8. There's #ifdef'ed code here to handle that, but I can't test it as intended. I tested it by changing the #ifdef to trigger on my 32-bit box instead. I suppose this is a bugfix candidate, but I won't backport it. It's long-winded (for speed) and messy (because the problem is messy). Note that this also depends on a previous 2.4 patch that introduced _Py_SwappedOp[] as an extern. Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- test_long.py 30 Aug 2004 23:18:23 -0000 1.24 +++ test_long.py 23 Sep 2004 08:06:37 -0000 1.25 @@ -387,8 +387,7 @@ "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.", "math.sin(huge)", "math.sin(mhuge)", "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better - "math.floor(huge)", "math.floor(mhuge)", - "float(shuge) == int(shuge)"]: + "math.floor(huge)", "math.floor(mhuge)"]: try: eval(test, namespace) @@ -397,6 +396,11 @@ else: raise TestFailed("expected OverflowError from %s" % test) + # XXX Perhaps float(shuge) can raise OverflowError on some box? + # The comparison should not. + if float(shuge) == int(shuge): + raise TestFailed("float(shuge) should not equal int(shuge)") + # ---------------------------------------------- test huge log and log10 def test_logs(): @@ -431,6 +435,101 @@ except ValueError: pass +# ----------------------------------------------- test mixed comparisons + +def test_mixed_compares(): + import math + import sys + + if verbose: + print "mixed comparisons" + + # We're mostly concerned with that mixing floats and longs does the + # right stuff, even when longs are too large to fit in a float. + # The safest way to check the results is to use an entirely different + # method, which we do here via a skeletal rational class (which + # represents all Python ints, longs and floats exactly). + class Rat: + def __init__(self, value): + if isinstance(value, (int, long)): + self.n = value + self.d = 1 + + elif isinstance(value, float): + # Convert to exact rational equivalent. + f, e = math.frexp(abs(value)) + assert f == 0 or 0.5 <= f < 1.0 + # |value| = f * 2**e exactly + + # Suck up CHUNK bits at a time; 28 is enough so that we suck + # up all bits in 2 iterations for all known binary double- + # precision formats, and small enough to fit in an int. + CHUNK = 28 + top = 0 + # invariant: |value| = (top + f) * 2**e exactly + while f: + f = math.ldexp(f, CHUNK) + digit = int(f) + assert digit >> CHUNK == 0 + top = (top << CHUNK) | digit + f -= digit + assert 0.0 <= f < 1.0 + e -= CHUNK + + # Now |value| = top * 2**e exactly. + if e >= 0: + n = top << e + d = 1 + else: + n = top + d = 1 << -e + if value < 0: + n = -n + self.n = n + self.d = d + assert float(n) / float(d) == value + + else: + raise TypeError("can't deal with %r" % val) + + def __cmp__(self, other): + if not isinstance(other, Rat): + other = Rat(other) + return cmp(self.n * other.d, self.d * other.n) + + cases = [0, 0.001, 0.99, 1.0, 1.5, 1e20, 1e200] + # 2**48 is an important boundary in the internals. 2**53 is an + # important boundary for IEEE double precision. + for t in 2.0**48, 2.0**50, 2.0**53: + cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0, + long(t-1), long(t), long(t+1)]) + cases.extend([0, 1, 2, sys.maxint, float(sys.maxint)]) + # 1L<<20000 should exceed all double formats. long(1e200) is to + # check that we get equality with 1e200 above. + t = long(1e200) + cases.extend([0L, 1L, 2L, 1L << 20000, t-1, t, t+1]) + cases.extend([-x for x in cases]) + for x in cases: + Rx = Rat(x) + for y in cases: + Ry = Rat(y) + Rcmp = cmp(Rx, Ry) + xycmp = cmp(x, y) + if Rcmp != xycmp: + raise TestFailed('%r %r %d %d' % (x, y, Rcmp, xycmp)) + if (x == y) != (Rcmp == 0): + raise TestFailed('%r == %r %d' % (x, y, Rcmp)) + if (x != y) != (Rcmp != 0): + raise TestFailed('%r != %r %d' % (x, y, Rcmp)) + if (x < y) != (Rcmp < 0): + raise TestFailed('%r < %r %d' % (x, y, Rcmp)) + if (x <= y) != (Rcmp <= 0): + raise TestFailed('%r <= %r %d' % (x, y, Rcmp)) + if (x > y) != (Rcmp > 0): + raise TestFailed('%r > %r %d' % (x, y, Rcmp)) + if (x >= y) != (Rcmp >= 0): + raise TestFailed('%r >= %r %d' % (x, y, Rcmp)) + # ---------------------------------------------------------------- do it test_division() @@ -441,3 +540,4 @@ test_auto_overflow() test_float_overflow() test_logs() +test_mixed_compares() From pje at users.sourceforge.net Thu Sep 23 15:54:56 2004 From: pje at users.sourceforge.net (pje@users.sourceforge.net) Date: Thu Sep 23 15:55:01 2004 Subject: [Python-checkins] python/nondist/peps pep-0302.txt,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9906 Modified Files: pep-0302.txt Log Message: It's PyImport_AddModule, not PyImport_ModuleAdd. Fix Python code sample to do the right thing for reload() to work. Revise explanation so it's clear what to do to fulfill reload()'s requirements in both C and Python. Index: pep-0302.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0302.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- pep-0302.txt 23 Sep 2004 04:06:40 -0000 1.14 +++ pep-0302.txt 23 Sep 2004 13:54:53 -0000 1.15 @@ -240,22 +240,27 @@ The load_module() method has a few responsibilities that it must fulfill *before* it runs any code: - - It must use the existing module object from sys.modules, if one - exists. (Otherwise, the reload() builtin will not work - correctly.) + - If there is an existing module object named 'fullname' in + sys.modules, the loader must use that existing module. + (Otherwise, the reload() builtin will not work correctly.) + If a module named 'fullname' does not exist in sys.modules, + the loader must create a new module object and add it to + sys.modules. - - If a module object is not already present in sys.modules, the - loader must create a module object. From Python this can be done - via the new.module() function, the imp.new_module() function or - via the module type object; from C with the PyModule_New() - function or the PyImport_ModuleAdd() function. The latter also - does the following step: + In C code, all of these requirements can be met simply by using + the PyImport_AddModule() function, which returns the existing + module or creates a new one and adds it to sys.modules for you. + In Python code, you can use something like: - - It must add the module to sys.modules, if it was not already - present there. This is crucial because the module code may - (directly or indirectly) import itself; adding it to sys.modules - beforehand prevents unbounded recursion in the worst case and - multiple loading in the best. + module = sys.modules.setdefault(fullname, new.module(fullname)) + + to accomplish the same results. + + Note that the module object *must* be in sys.modules before the + loader executes the module code. This is crucial because the + module code may (directly or indirectly) import itself; adding + it to sys.modules beforehand prevents unbounded recursion in the + worst case and multiple loading in the best. - The __file__ attribute must be set. This must be a string, but it may be a dummy value, for example "". The privilege of @@ -279,8 +284,7 @@ def load_module(self, fullname): ispkg, code = self._get_code(fullname) - mod = imp.new_module(fullname) - sys.modules[fullname] = mod + mod = sys.modules.setdefault(fullname, imp.new_module(fullname)) mod.__file__ = "<%s>" % self.__class__.__name__ mod.__loader__ = self if ispkg: From tim_one at users.sourceforge.net Thu Sep 23 21:11:34 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 21:11:37 2004 Subject: [Python-checkins] python/dist/src/PC pyconfig.h,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21226/PC Modified Files: pyconfig.h Log Message: Introduced a Py_IS_NAN macro, which probably works on the major platforms today. pyconfig.h can override it if not, and can also override Py_IS_INFINITY now. Py_IS_NAN and Py_IS_INFINITY are overridden now for Microsoft compilers, using efficient MS-specific spellings. Index: pyconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/pyconfig.h,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- pyconfig.h 3 Aug 2004 08:52:46 -0000 1.29 +++ pyconfig.h 23 Sep 2004 19:11:32 -0000 1.30 @@ -118,6 +118,10 @@ typedef int pid_t; #define hypot _hypot +#include +#define Py_IS_NAN _isnan +#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X)) + #endif /* _MSC_VER */ /* define some ANSI types that are not defined in earlier Win headers */ From tim_one at users.sourceforge.net Thu Sep 23 21:11:34 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 21:11:38 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1142,1.1143 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21226/Misc Modified Files: NEWS Log Message: Introduced a Py_IS_NAN macro, which probably works on the major platforms today. pyconfig.h can override it if not, and can also override Py_IS_INFINITY now. Py_IS_NAN and Py_IS_INFINITY are overridden now for Microsoft compilers, using efficient MS-specific spellings. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1142 retrieving revision 1.1143 diff -u -d -r1.1142 -r1.1143 --- NEWS 23 Sep 2004 08:06:37 -0000 1.1142 +++ NEWS 23 Sep 2004 19:11:22 -0000 1.1143 @@ -74,7 +74,11 @@ Build ----- -... +- pyport.h now defines a Py_IS_NAN macro. It works as-is when the + platform C computes true for ``x != x`` if and only if X is a NaN. + Other platforms can override the default definition with a platform- + specific spelling in that platform's pyconfig.h. You can also override + pyport.h's default Py_IS_INFINITY definition now. C API ----- From tim_one at users.sourceforge.net Thu Sep 23 21:11:54 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 21:12:00 2004 Subject: [Python-checkins] python/dist/src/Include pyport.h,2.69,2.70 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21226/Include Modified Files: pyport.h Log Message: Introduced a Py_IS_NAN macro, which probably works on the major platforms today. pyconfig.h can override it if not, and can also override Py_IS_INFINITY now. Py_IS_NAN and Py_IS_INFINITY are overridden now for Microsoft compilers, using efficient MS-specific spellings. Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.69 retrieving revision 2.70 diff -u -d -r2.69 -r2.70 --- pyport.h 4 Aug 2004 06:33:50 -0000 2.69 +++ pyport.h 23 Sep 2004 19:11:21 -0000 2.70 @@ -219,14 +219,29 @@ #define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE) #endif +/* Py_IS_NAN(X) + * Return 1 if float or double arg is a NaN, else 0. + * Caution: + * X is evaluated more than once. + * This may not work on all platforms. Each platform has *some* + * way to spell this, though -- override in pyconfig.h if you have + * a platform where it doesn't work. + */ +#ifndef Py_IS_NAN +#define Py_IS_NAN(X) ((X) != (X)) +#endif + /* Py_IS_INFINITY(X) * Return 1 if float or double arg is an infinity, else 0. * Caution: * X is evaluated more than once. * This implementation may set the underflow flag if |X| is very small; * it really can't be implemented correctly (& easily) before C99. + * Override in pyconfig.h if you have a better spelling on your platform. */ +#ifndef Py_IS_INFINITY #define Py_IS_INFINITY(X) ((X) && (X)*0.5 == (X)) +#endif /* HUGE_VAL is supposed to expand to a positive double infinity. Python * uses Py_HUGE_VAL instead because some platforms are broken in this @@ -257,12 +272,12 @@ * Some platforms have better way to spell this, so expect some #ifdef'ery. * * OpenBSD uses 'isinf()' because a compiler bug on that platform causes - * the longer macro version to be mis-compiled. This isn't optimal, and + * the longer macro version to be mis-compiled. This isn't optimal, and * should be removed once a newer compiler is available on that platform. * The system that had the failure was running OpenBSD 3.2 on Intel, with * gcc 2.95.3. * - * According to Tim's checkin, the FreeBSD systems use isinf() to work + * According to Tim's checkin, the FreeBSD systems use isinf() to work * around a FPE bug on that platform. */ #if defined(__FreeBSD__) || defined(__OpenBSD__) From tim_one at users.sourceforge.net Thu Sep 23 21:22:44 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu Sep 23 21:22:46 2004 Subject: [Python-checkins] python/dist/src/Objects floatobject.c, 2.133, 2.134 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24289/Objects Modified Files: floatobject.c Log Message: float_richcompare(): Use the new Py_IS_NAN macro to ensure that, on platforms where that macro works, NaN compared to an int or long works the same as NaN compared to a finite float. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.133 retrieving revision 2.134 diff -u -d -r2.133 -r2.134 --- floatobject.c 23 Sep 2004 08:06:40 -0000 2.133 +++ floatobject.c 23 Sep 2004 19:22:41 -0000 2.134 @@ -384,13 +384,11 @@ if (PyFloat_Check(w)) j = PyFloat_AS_DOUBLE(w); - else if (Py_IS_INFINITY(i)) { - /* XXX If we had a reliable way to check whether i is a - * XXX NaN, it would belong in this branch too. - */ + else if (Py_IS_INFINITY(i) || Py_IS_NAN(i)) { if (PyInt_Check(w) || PyLong_Check(w)) - /* The magnitude of i exceeds any finite integer, - * so it doesn't matter which int we compare i with. + /* If i is an infinity, its magnitude exceeds any + * finite integer, so it doesn't matter which int we + * compare i with. If i is a NaN, similarly. */ j = 0.0; else @@ -403,7 +401,7 @@ * Cray single with 48 bits of precision, and long has 64 * bits. */ -#if SIZEOF_LONG > 4 +#if SIZEOF_LONG > 6 unsigned long abs = (unsigned long)(jj < 0 ? -jj : jj); if (abs >> 48) { /* Needs more than 48 bits. Make it take the @@ -443,10 +441,10 @@ nbits = _PyLong_NumBits(w); if (nbits == (size_t)-1 && PyErr_Occurred()) { /* This long is so large that size_t isn't big enough - * to hold the # of Python digits. Replace with - * little doubles that give the same outcome -- - * w is so large that its magnitude must exceed - * the magnitude of any finite float. + * to hold the # of bits. Replace with little doubles + * that give the same outcome -- w is so large that + * its magnitude must exceed the magnitude of any + * finite float. */ PyErr_Clear(); i = (double)vsign; From akuchling at users.sourceforge.net Thu Sep 23 22:15:44 2004 From: akuchling at users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu Sep 23 22:15:47 2004 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew24.tex, 1.102, 1.103 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2793 Modified Files: whatsnew24.tex Log Message: Add various items Index: whatsnew24.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew24.tex,v retrieving revision 1.102 retrieving revision 1.103 diff -u -d -r1.102 -r1.103 --- whatsnew24.tex 20 Sep 2004 17:47:46 -0000 1.102 +++ whatsnew24.tex 23 Sep 2004 20:15:41 -0000 1.103 @@ -941,6 +941,10 @@ the generated bytecode for list comprehensions and speeds them up by about a third. (Contributed by Raymond Hettinger.) +\item The peephole bytecode optimizer has been improved to +produce shorter, faster bytecode; remarkably the resulting bytecode is +more readable. (Enhanced by Raymond Hettinger.) + \item String concatenations in statements of the form \code{s = s + "abc"} and \code{s += "abc"} are now performed more efficiently in certain circumstances. This optimization won't be present in other @@ -1056,6 +1060,12 @@ find the N largest or smallest values in a dataset without the expense of a full sort. (Contributed by Raymond Hettinger.) +\item The \module{httplib} module now contains constants for HTTP +status codes defined in various HTTP-related RFC documents. Constants +have names such as \constant{OK}, \constant{CREATED}, +\constant{CONTINUE}, and \constant{MOVED_PERMANENTLY}; use pydoc to +get a full list. (Contributed by Andrew Eland.) + \item The \module{imaplib} module now supports IMAP's THREAD command (contributed by Yves Dionne) and new \method{deleteacl()} and \method{myrights()} methods (contributed by Arnaud Mazin). @@ -1167,6 +1177,11 @@ classes derive from a new \class{BaseRotatingHandler} class that can be used to implement other rotating handlers. +\item The \module{marshal} module now shares interned strings on unpacking a +data structure. This may shrink the size of certain pickle strings, +but the primary effect is to make \file{.pyc} files significantly smaller. +(Contributed by Martin von Loewis.) + \item The \module{nntplib} module's \class{NNTP} class gained \method{description()} and \method{descriptions()} methods to retrieve newsgroup descriptions for a single group or for a range of groups. @@ -1347,6 +1362,10 @@ implements fast dictionary lookups without masking exceptions raised during the look-up process. (Contributed by Raymond Hettinger.) + \item The \csimplemacro{Py_IS_NAN(\var{X})} macro returns 1 if + its float or double argument \var{X} is a NaN. + (Contributed by Tim Peters.) + \item A new function, \cfunction{PyArg_VaParseTupleAndKeywords()}, is the same as \cfunction{PyArg_ParseTupleAndKeywords()} but takes a \ctype{va_list} instead of a number of arguments. From akuchling at users.sourceforge.net Thu Sep 23 22:17:29 2004 From: akuchling at users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu Sep 23 22:17:31 2004 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew24.tex, 1.103, 1.104 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3083 Modified Files: whatsnew24.tex Log Message: Update for beta1 Index: whatsnew24.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew24.tex,v retrieving revision 1.103 retrieving revision 1.104 diff -u -d -r1.103 -r1.104 --- whatsnew24.tex 23 Sep 2004 20:15:41 -0000 1.103 +++ whatsnew24.tex 23 Sep 2004 20:17:26 -0000 1.104 @@ -21,8 +21,8 @@ \maketitle \tableofcontents -This article explains the new features in Python 2.4 alpha3, scheduled -for release in early September. The final version of Python 2.4 is +This article explains the new features in Python 2.4 beta1, scheduled +for release in mid-October. The final version of Python 2.4 is expected to be released around December 2004. Python 2.4 is a medium-sized release. It doesn't introduce as many @@ -376,7 +376,7 @@ function that's constructed and returned. The new syntax was provisionally added in 2.4alpha2, and is subject to -change during the 2.4alpha release cycle depending on the Python +change during the 2.4beta release cycle depending on the Python community's reaction. Post-2.4 versions of Python will preserve compatibility with whatever syntax is used in 2.4final. From rhettinger at users.sourceforge.net Fri Sep 24 05:41:07 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri Sep 24 05:41:11 2004 Subject: [Python-checkins] python/dist/src/Lib sre.py,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24976/lib Modified Files: sre.py Log Message: Granted Noam Raphael's request for minor improvements to the re module and its documentation. * Documented that the compiled re methods are supposed to be more full featured than their simpilified function counterparts. * Documented the existing start and stop position arguments for the findall() and finditer() methods of compiled regular expression objects. * Added an optional flags argument to the re.findall() and re.finditer() functions. This aligns their API with that for re.search() and re.match(). Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- sre.py 25 Aug 2004 02:22:29 -0000 1.50 +++ sre.py 24 Sep 2004 03:41:05 -0000 1.51 @@ -156,7 +156,7 @@ returning a list containing the resulting substrings.""" return _compile(pattern, 0).split(string, maxsplit) -def findall(pattern, string): +def findall(pattern, string, flags=0): """Return a list of all non-overlapping matches in the string. If one or more groups are present in the pattern, return a @@ -164,16 +164,16 @@ has more than one group. Empty matches are included in the result.""" - return _compile(pattern, 0).findall(string) + return _compile(pattern, flags).findall(string) if sys.hexversion >= 0x02020000: __all__.append("finditer") - def finditer(pattern, string): + def finditer(pattern, string, flags=0): """Return an iterator over all non-overlapping matches in the string. For each match, the iterator returns a match object. Empty matches are included in the result.""" - return _compile(pattern, 0).finditer(string) + return _compile(pattern, flags).finditer(string) def compile(pattern, flags=0): "Compile a regular expression pattern, returning a pattern object." From rhettinger at users.sourceforge.net Fri Sep 24 05:41:07 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri Sep 24 05:41:12 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1143,1.1144 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24976/Misc Modified Files: NEWS Log Message: Granted Noam Raphael's request for minor improvements to the re module and its documentation. * Documented that the compiled re methods are supposed to be more full featured than their simpilified function counterparts. * Documented the existing start and stop position arguments for the findall() and finditer() methods of compiled regular expression objects. * Added an optional flags argument to the re.findall() and re.finditer() functions. This aligns their API with that for re.search() and re.match(). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1143 retrieving revision 1.1144 diff -u -d -r1.1143 -r1.1144 --- NEWS 23 Sep 2004 19:11:22 -0000 1.1143 +++ NEWS 24 Sep 2004 03:40:57 -0000 1.1144 @@ -32,6 +32,11 @@ Library ------- +- re's findall() and finditer() functions now take an optional flags argument + just like the compile(), search(), and match() functions. Also, documented + the previously existing start and stop parameters for the findall() and + finditer() methods of regular expression objects. + - rfc822 Messages now support iterating over the headers. - The (undocumented) tarfile.Tarfile.membernames has been removed; From rhettinger at users.sourceforge.net Fri Sep 24 05:41:08 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri Sep 24 05:41:13 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libre.tex,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24976/doc/lib Modified Files: libre.tex Log Message: Granted Noam Raphael's request for minor improvements to the re module and its documentation. * Documented that the compiled re methods are supposed to be more full featured than their simpilified function counterparts. * Documented the existing start and stop position arguments for the findall() and finditer() methods of compiled regular expression objects. * Added an optional flags argument to the re.findall() and re.finditer() functions. This aligns their API with that for re.search() and re.match(). Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.109 retrieving revision 1.110 diff -u -d -r1.109 -r1.110 --- libre.tex 3 Sep 2004 17:06:10 -0000 1.109 +++ libre.tex 24 Sep 2004 03:41:05 -0000 1.110 @@ -424,8 +424,10 @@ \subsection{Module Contents} \nodename{Contents of Module re} -The module defines the following functions and constants, and an exception: - +The module defines several functions, constants, and an exception. Some of the +functions are simplified versions of the full featured methods for compiled +regular expressions. Most non-trivial applications always use the compiled +form. \begin{funcdesc}{compile}{pattern\optional{, flags}} Compile a regular expression pattern into a regular expression @@ -552,21 +554,23 @@ the old \function{regsub.split()} and \function{regsub.splitx()}. \end{funcdesc} -\begin{funcdesc}{findall}{pattern, string} +\begin{funcdesc}{findall}{pattern, string\optional{, flags}} Return a list of all non-overlapping matches of \var{pattern} in \var{string}. If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result unless they touch the beginning of another match. \versionadded{1.5.2} + \versionchanged[Added the optional flags argument]{2.4} \end{funcdesc} -\begin{funcdesc}{finditer}{pattern, string} +\begin{funcdesc}{finditer}{pattern, string\optional{, flags}} Return an iterator over all non-overlapping matches for the RE \var{pattern} in \var{string}. For each match, the iterator returns a match object. Empty matches are included in the result unless they touch the beginning of another match. \versionadded{2.2} + \versionchanged[Added the optional flags argument]{2.4} \end{funcdesc} \begin{funcdesc}{sub}{pattern, repl, string\optional{, count}} @@ -695,11 +699,13 @@ Identical to the \function{split()} function, using the compiled pattern. \end{methoddesc} -\begin{methoddesc}[RegexObject]{findall}{string} +\begin{methoddesc}[RegexObject]{findall}{string\optional{, pos\optional{, + endpos}}} Identical to the \function{findall()} function, using the compiled pattern. \end{methoddesc} -\begin{methoddesc}[RegexObject]{finditer}{string} +\begin{methoddesc}[RegexObject]{finditer}{string\optional{, pos\optional{, + endpos}}} Identical to the \function{finditer()} function, using the compiled pattern. \end{methoddesc} From rhettinger at users.sourceforge.net Fri Sep 24 06:31:22 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri Sep 24 06:31:26 2004 Subject: [Python-checkins] python/dist/src/Modules _sre.c,2.108,2.109 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32524 Modified Files: _sre.c Log Message: Add docstrings for regular expression objects and methods. Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.108 retrieving revision 2.109 diff -u -d -r2.108 -r2.109 --- _sre.c 3 Sep 2004 18:11:59 -0000 2.108 +++ _sre.c 24 Sep 2004 04:31:19 -0000 2.109 @@ -2672,15 +2672,58 @@ #endif } +PyDoc_STRVAR(pattern_match_doc, +"match(string[, pos[, endpos]]) --> match object or None.\n\ + Matches zero or more characters at the beginning of the string"); + +PyDoc_STRVAR(pattern_search_doc, +"search(string[, pos[, endpos]]) --> match object or None.\n\ + Scan through string looking for a match, and return a corresponding\n\ + MatchObject instance. Return None if no position in the string matches."); + +PyDoc_STRVAR(pattern_split_doc, +"split(string[, maxsplit = 0]) --> list.\n\ + Split string by the occurrences of pattern."); + +PyDoc_STRVAR(pattern_findall_doc, +"findall(string[, pos[, endpos]]) --> list.\n\ + Return a list of all non-overlapping matches of pattern in string."); + +PyDoc_STRVAR(pattern_finditer_doc, +"finditer(string[, pos[, endpos]]) --> iterator.\n\ + Return an iterator over all non-overlapping matches for the \n\ + RE pattern in string. For each match, the iterator returns a\n\ + match object."); + +PyDoc_STRVAR(pattern_sub_doc, +"sub(repl, string[, count = 0]) --> newstring\n\ + Return the string obtained by replacing the leftmost non-overlapping\n\ + occurrences of pattern in string by the replacement repl."); + +PyDoc_STRVAR(pattern_subn_doc, +"subn(repl, string[, count = 0]) --> (newstring, number of subs)\n\ + Return the tuple (new_string, number_of_subs_made) found by replacing\n\ + the leftmost non-overlapping occurrences of pattern with the\n\ + replacement repl."); + +PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects"); + static PyMethodDef pattern_methods[] = { - {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, - {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS}, - {"sub", (PyCFunction) pattern_sub, METH_VARARGS|METH_KEYWORDS}, - {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS}, - {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS}, - {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS}, + {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS, + pattern_match_doc}, + {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS, + pattern_search_doc}, + {"sub", (PyCFunction) pattern_sub, METH_VARARGS|METH_KEYWORDS, + pattern_sub_doc}, + {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS, + pattern_subn_doc}, + {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS, + pattern_split_doc}, + {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS, + pattern_findall_doc}, #if PY_VERSION_HEX >= 0x02020000 - {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS}, + {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS, + pattern_finditer_doc}, #endif {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, @@ -2741,7 +2784,7 @@ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */ - 0, /* tp_doc */ + pattern_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ From tim_one at users.sourceforge.net Fri Sep 24 06:37:01 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri Sep 24 06:37:05 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_importhooks.py, 1.3, 1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv605/Lib/test Modified Files: test_importhooks.py Log Message: Whitespace normalization. Index: test_importhooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_importhooks.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- test_importhooks.py 23 Sep 2004 04:37:35 -0000 1.3 +++ test_importhooks.py 24 Sep 2004 04:36:47 -0000 1.4 @@ -176,7 +176,7 @@ TestImporter.modules['reloadmodule'] = (False, reload_co) reload(reloadmodule) self.failUnless(hasattr(reloadmodule,'reloaded')) - + def testMetaPath(self): i = MetaImporter() sys.meta_path.append(i) From vsajip at users.sourceforge.net Fri Sep 24 13:45:16 2004 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Fri Sep 24 13:45:54 2004 Subject: [Python-checkins] python/dist/src/Lib/logging config.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12481 Modified Files: config.py Log Message: Added exception handling during handler initialization in fileConfig() Index: config.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/config.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- config.py 28 Feb 2004 16:05:50 -0000 1.9 +++ config.py 24 Sep 2004 11:45:13 -0000 1.10 @@ -98,31 +98,34 @@ handlers = {} fixups = [] #for inter-handler references for hand in hlist: - sectname = "handler_%s" % hand - klass = cp.get(sectname, "class") - opts = cp.options(sectname) - if "formatter" in opts: - fmt = cp.get(sectname, "formatter") - else: - fmt = "" - klass = eval(klass, vars(logging)) - args = cp.get(sectname, "args") - args = eval(args, vars(logging)) - h = apply(klass, args) - if "level" in opts: - level = cp.get(sectname, "level") - h.setLevel(logging._levelNames[level]) - if len(fmt): - h.setFormatter(formatters[fmt]) - #temporary hack for FileHandler and MemoryHandler. - if klass == logging.handlers.MemoryHandler: - if "target" in opts: - target = cp.get(sectname,"target") + try: + sectname = "handler_%s" % hand + klass = cp.get(sectname, "class") + opts = cp.options(sectname) + if "formatter" in opts: + fmt = cp.get(sectname, "formatter") else: - target = "" - if len(target): #the target handler may not be loaded yet, so keep for later... - fixups.append((h, target)) - handlers[hand] = h + fmt = "" + klass = eval(klass, vars(logging)) + args = cp.get(sectname, "args") + args = eval(args, vars(logging)) + h = apply(klass, args) + if "level" in opts: + level = cp.get(sectname, "level") + h.setLevel(logging._levelNames[level]) + if len(fmt): + h.setFormatter(formatters[fmt]) + #temporary hack for FileHandler and MemoryHandler. + if klass == logging.handlers.MemoryHandler: + if "target" in opts: + target = cp.get(sectname,"target") + else: + target = "" + if len(target): #the target handler may not be loaded yet, so keep for later... + fixups.append((h, target)) + handlers[hand] = h + except: #if an error occurs when instantiating a handler, too bad + pass #this could happen e.g. because of lack of privileges #now all handlers are loaded, fixup inter-handler references... for fixup in fixups: h = fixup[0] From vsajip at users.sourceforge.net Fri Sep 24 13:45:55 2004 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Fri Sep 24 13:45:58 2004 Subject: [Python-checkins] python/dist/src/Lib/logging __init__.py, 1.20, 1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12619 Modified Files: __init__.py Log Message: Added log() function Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/__init__.py,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- __init__.py 22 Sep 2004 12:39:26 -0000 1.20 +++ __init__.py 24 Sep 2004 11:45:52 -0000 1.21 @@ -1245,6 +1245,14 @@ basicConfig() apply(root.debug, (msg,)+args, kwargs) +def log(level, msg, *args, **kwargs): + """ + Log 'msg % args' with the integer severity 'level' on the root logger. + """ + if len(root.handlers) == 0: + basicConfig() + apply(root.log, (level, msg)+args, kwargs) + def disable(level): """ Disable all logging calls less severe than 'level'. From vsajip at users.sourceforge.net Fri Sep 24 13:46:47 2004 From: vsajip at users.sourceforge.net (vsajip@users.sourceforge.net) Date: Fri Sep 24 13:46:49 2004 Subject: [Python-checkins] python/dist/src/Doc/lib liblogging.tex,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12831 Modified Files: liblogging.tex Log Message: Added log() function documentation Index: liblogging.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liblogging.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- liblogging.tex 22 Sep 2004 12:55:16 -0000 1.25 +++ liblogging.tex 24 Sep 2004 11:46:44 -0000 1.26 @@ -193,6 +193,11 @@ from an exception handler. \end{funcdesc} +\begin{funcdesc}{log}{level, msg\optional{, *args\optional{, **kwargs}}} +Logs a message with level \var{level} on the root logger. +The other arguments are interpreted as for \function{debug()}. +\end{funcdesc} + \begin{funcdesc}{disable}{lvl} Provides an overriding level \var{lvl} for all loggers which takes precedence over the logger's own level. When the need arises to From nascheme at users.sourceforge.net Fri Sep 24 17:35:18 2004 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Fri Sep 24 17:35:21 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_types.py,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2082/Lib/test Modified Files: test_types.py Log Message: Add a few more tests for the buffer() object. Index: test_types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_types.py,v retrieving revision 1.60 retrieving revision 1.61 diff -u -d -r1.60 -r1.61 --- test_types.py 31 May 2004 16:29:04 -0000 1.60 +++ test_types.py 24 Sep 2004 15:35:15 -0000 1.61 @@ -245,6 +245,14 @@ raise TestFailed, 'repeated buffer zero times has wrong content' if str(a + buffer('def')) != 'asdfdef': raise TestFailed, 'concatenation of buffers yields wrong content' +if str(buffer(a)) != 'asdf': + raise TestFailed, 'composing buffers failed' +if str(buffer(a, 2)) != 'df': + raise TestFailed, 'specifying buffer offset failed' +if str(buffer(a, 0, 2)) != 'as': + raise TestFailed, 'specifying buffer size failed' +if str(buffer(a, 1, 2)) != 'sd': + raise TestFailed, 'specifying buffer offset and size failed' try: a[1] = 'g' except TypeError: pass From nascheme at users.sourceforge.net Fri Sep 24 17:41:29 2004 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Fri Sep 24 17:41:32 2004 Subject: [Python-checkins] python/dist/src/Objects bufferobject.c,2.24,2.25 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3359/Objects Modified Files: bufferobject.c Log Message: Fix buffer offset calculation (need to compute it before changing 'base'). Fixes SF bug #1033720. Move offset sanity checking to buffer_from_memory(). Index: bufferobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/bufferobject.c,v retrieving revision 2.24 retrieving revision 2.25 diff -u -d -r2.24 -r2.25 --- bufferobject.c 25 Mar 2004 16:16:28 -0000 2.24 +++ bufferobject.c 24 Sep 2004 15:41:27 -0000 2.25 @@ -66,6 +66,11 @@ "size must be zero or positive"); return NULL; } + if (offset < 0) { + PyErr_SetString(PyExc_ValueError, + "offset must be zero or positive"); + return NULL; + } b = PyObject_NEW(PyBufferObject, &PyBuffer_Type); if ( b == NULL ) @@ -85,20 +90,11 @@ static PyObject * buffer_from_object(PyObject *base, int size, int offset, int readonly) { - if ( offset < 0 ) { - PyErr_SetString(PyExc_ValueError, - "offset must be zero or positive"); - return NULL; - } - - /* if the base object is another buffer, then try to refer to the - * base object. - */ if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) { + /* another buffer, refer to the base object */ + offset += ((PyBufferObject *)base)->b_offset; base = ((PyBufferObject *)base)->b_base; - offset = ((PyBufferObject *)base)->b_offset + offset; } - return buffer_from_memory(base, size, offset, NULL, readonly); } From nascheme at users.sourceforge.net Fri Sep 24 21:17:30 2004 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Fri Sep 24 21:17:34 2004 Subject: [Python-checkins] python/dist/src/Objects bufferobject.c,2.25,2.26 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12799/Objects Modified Files: bufferobject.c Log Message: Ensure negative offsets cannot be passed to buffer(). When composing buffers, compute the new buffer size based on the old buffer size. Fixes SF bug #1034242. Index: bufferobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/bufferobject.c,v retrieving revision 2.25 retrieving revision 2.26 diff -u -d -r2.25 -r2.26 --- bufferobject.c 24 Sep 2004 15:41:27 -0000 2.25 +++ bufferobject.c 24 Sep 2004 19:17:26 -0000 2.26 @@ -90,10 +90,23 @@ static PyObject * buffer_from_object(PyObject *base, int size, int offset, int readonly) { + if (offset < 0) { + PyErr_SetString(PyExc_ValueError, + "offset must be zero or positive"); + return NULL; + } if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) { /* another buffer, refer to the base object */ - offset += ((PyBufferObject *)base)->b_offset; - base = ((PyBufferObject *)base)->b_base; + PyBufferObject *b = (PyBufferObject *)base; + if (b->b_size != Py_END_OF_BUFFER) { + int base_size = b->b_size - offset; + if (base_size < 0) + base_size = 0; + if (size == Py_END_OF_BUFFER || size > base_size) + size = base_size; + } + offset += b->b_offset; + base = b->b_base; } return buffer_from_memory(base, size, offset, NULL, readonly); } From nascheme at users.sourceforge.net Fri Sep 24 21:18:45 2004 From: nascheme at users.sourceforge.net (nascheme@users.sourceforge.net) Date: Fri Sep 24 21:18:47 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_types.py,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12951/Lib/test Modified Files: test_types.py Log Message: Add yet more tests for buffer(). Index: test_types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_types.py,v retrieving revision 1.61 retrieving revision 1.62 diff -u -d -r1.61 -r1.62 --- test_types.py 24 Sep 2004 15:35:15 -0000 1.61 +++ test_types.py 24 Sep 2004 19:18:42 -0000 1.62 @@ -253,6 +253,17 @@ raise TestFailed, 'specifying buffer size failed' if str(buffer(a, 1, 2)) != 'sd': raise TestFailed, 'specifying buffer offset and size failed' +try: buffer(buffer('asdf', 1), -1) +except ValueError: pass +else: raise TestFailed, "buffer(buffer('asdf', 1), -1) should raise ValueError" +if str(buffer(buffer('asdf', 0, 2), 0)) != 'as': + raise TestFailed, 'composing length-specified buffer failed' +if str(buffer(buffer('asdf', 0, 2), 0, 5000)) != 'as': + raise TestFailed, 'composing length-specified buffer failed' +if str(buffer(buffer('asdf', 0, 2), 0, -1)) != 'as': + raise TestFailed, 'composing length-specified buffer failed' +if str(buffer(buffer('asdf', 0, 2), 1, 2)) != 's': + raise TestFailed, 'composing length-specified buffer failed' try: a[1] = 'g' except TypeError: pass From jlgijsbers at users.sourceforge.net Fri Sep 24 23:36:55 2004 From: jlgijsbers at users.sourceforge.net (jlgijsbers@users.sourceforge.net) Date: Fri Sep 24 23:36:57 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_unpack.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4712 Modified Files: test_unpack.py Log Message: Port test_unpack to doctest (patch #736962). Index: test_unpack.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unpack.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- test_unpack.py 30 Jul 2002 23:27:12 -0000 1.7 +++ test_unpack.py 24 Sep 2004 21:36:52 -0000 1.8 @@ -1,144 +1,131 @@ -from test.test_support import TestFailed, verbose +doctests = """ -t = (1, 2, 3) -l = [4, 5, 6] +Unpack tuple -class Seq: - def __getitem__(self, i): - if i >= 0 and i < 3: return i - raise IndexError + >>> t = (1, 2, 3) + >>> a, b, c = t + >>> a == 1 and b == 2 and c == 3 + True -a = -1 -b = -1 -c = -1 +Unpack list -# unpack tuple -if verbose: - print 'unpack tuple' -a, b, c = t -if a != 1 or b != 2 or c != 3: - raise TestFailed + >>> l = [4, 5, 6] + >>> a, b, c = l + >>> a == 4 and b == 5 and c == 6 + True -# unpack list -if verbose: - print 'unpack list' -a, b, c = l -if a != 4 or b != 5 or c != 6: - raise TestFailed +Unpack implied tuple -# unpack implied tuple -if verbose: - print 'unpack implied tuple' -a, b, c = 7, 8, 9 -if a != 7 or b != 8 or c != 9: - raise TestFailed + >>> a, b, c = 7, 8, 9 + >>> a == 7 and b == 8 and c == 9 + True -# unpack string... fun! -if verbose: - print 'unpack string' -a, b, c = 'one' -if a != 'o' or b != 'n' or c != 'e': - raise TestFailed +Unpack string... fun! -# unpack generic sequence -if verbose: - print 'unpack sequence' -a, b, c = Seq() -if a != 0 or b != 1 or c != 2: - raise TestFailed + >>> a, b, c = 'one' + >>> a == 'o' and b == 'n' and c == 'e' + True -# single element unpacking, with extra syntax -if verbose: - print 'unpack single tuple/list' -st = (99,) -sl = [100] -a, = st -if a != 99: - raise TestFailed -b, = sl -if b != 100: - raise TestFailed +Unpack generic sequence -# now for some failures + >>> class Seq: + ... def __getitem__(self, i): + ... if i >= 0 and i < 3: return i + ... raise IndexError + ... + >>> a, b, c = Seq() + >>> a == 0 and b == 1 and c == 2 + True -# unpacking non-sequence -if verbose: - print 'unpack non-sequence' -try: - a, b, c = 7 - raise TestFailed -except TypeError: - pass +Single element unpacking, with extra syntax + >>> st = (99,) + >>> sl = [100] + >>> a, = st + >>> a + 99 + >>> b, = sl + >>> b + 100 -# unpacking tuple of wrong size -if verbose: - print 'unpack tuple wrong size' -try: - a, b = t - raise TestFailed -except ValueError: - pass +Now for some failures -# unpacking list of wrong size -if verbose: - print 'unpack list wrong size' -try: - a, b = l - raise TestFailed -except ValueError: - pass +Unpacking non-sequence + >>> a, b, c = 7 + Traceback (most recent call last): + ... + TypeError: unpack non-sequence -# unpacking sequence too short -if verbose: - print 'unpack sequence too short' -try: - a, b, c, d = Seq() - raise TestFailed -except ValueError: - pass +Unpacking tuple of wrong size + >>> a, b = t + Traceback (most recent call last): + ... + ValueError: too many values to unpack -# unpacking sequence too long -if verbose: - print 'unpack sequence too long' -try: - a, b = Seq() - raise TestFailed -except ValueError: - pass +Unpacking tuple of wrong size + >>> a, b = l + Traceback (most recent call last): + ... + ValueError: too many values to unpack -# unpacking a sequence where the test for too long raises a different -# kind of error -class BozoError(Exception): - pass +Unpacking sequence too short -class BadSeq: - def __getitem__(self, i): - if i >= 0 and i < 3: - return i - elif i == 3: - raise BozoError - else: - raise IndexError + >>> a, b, c, d = Seq() + Traceback (most recent call last): + ... + ValueError: need more than 3 values to unpack +Unpacking sequence too long -# trigger code while not expecting an IndexError -if verbose: - print 'unpack sequence too long, wrong error' -try: - a, b, c, d, e = BadSeq() - raise TestFailed -except BozoError: - pass + >>> a, b = Seq() + Traceback (most recent call last): + ... + ValueError: too many values to unpack -# trigger code while expecting an IndexError -if verbose: - print 'unpack sequence too short, wrong error' -try: - a, b, c = BadSeq() - raise TestFailed -except BozoError: - pass +Unpacking a sequence where the test for too long raises a different kind of +error + + >>> class BozoError(Exception): + ... pass + ... + >>> class BadSeq: + ... def __getitem__(self, i): + ... if i >= 0 and i < 3: + ... return i + ... elif i == 3: + ... raise BozoError + ... else: + ... raise IndexError + ... + +Trigger code while not expecting an IndexError (unpack sequence too long, wrong +error) + + >>> a, b, c, d, e = BadSeq() + Traceback (most recent call last): + ... + BozoError + +Trigger code while expecting an IndexError (unpack sequence too short, wrong +error) + + >>> a, b, c = BadSeq() + Traceback (most recent call last): + ... + BozoError + +""" + +__test__ = {'doctests' : doctests} + +def test_main(verbose=False): + import sys + from test import test_support + from test import test_unpack + test_support.run_doctest(test_unpack, verbose) + +if __name__ == "__main__": + test_main(verbose=True) From tim_one at users.sourceforge.net Sat Sep 25 01:16:44 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 01:16:46 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_types.py,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25322/Lib/test Modified Files: test_types.py Log Message: Whitespace normalization. Index: test_types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_types.py,v retrieving revision 1.62 retrieving revision 1.63 diff -u -d -r1.62 -r1.63 --- test_types.py 24 Sep 2004 19:18:42 -0000 1.62 +++ test_types.py 24 Sep 2004 23:16:41 -0000 1.63 @@ -261,7 +261,7 @@ if str(buffer(buffer('asdf', 0, 2), 0, 5000)) != 'as': raise TestFailed, 'composing length-specified buffer failed' if str(buffer(buffer('asdf', 0, 2), 0, -1)) != 'as': - raise TestFailed, 'composing length-specified buffer failed' + raise TestFailed, 'composing length-specified buffer failed' if str(buffer(buffer('asdf', 0, 2), 1, 2)) != 's': raise TestFailed, 'composing length-specified buffer failed' From jlgijsbers at users.sourceforge.net Sat Sep 25 01:25:29 2004 From: jlgijsbers at users.sourceforge.net (jlgijsbers@users.sourceforge.net) Date: Sat Sep 25 01:25:33 2004 Subject: [Python-checkins] python/dist/src/Doc/tut tut.tex,1.250,1.251 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28003 Modified Files: tut.tex Log Message: - Use itemize instead of plain-text '*' for marking up a list. - Add more ulink's to modules (this should probably become a standard macro). Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.250 retrieving revision 1.251 diff -u -d -r1.250 -r1.251 --- tut.tex 14 Sep 2004 06:32:20 -0000 1.250 +++ tut.tex 24 Sep 2004 23:25:25 -0000 1.251 @@ -4682,9 +4682,9 @@ \end{verbatim} In contrast to \module{timeit}'s fine level of granularity, the -\ulink{\module{profile}}{../lib/module-profile.html} and \module{pstats} -modules provide tools for identifying time critical sections in larger -blocks of code. +\ulink{\module{profile}}{../lib/module-profile.html} and +\ulink{\module{pstats}}{../lib/module-pstats.html} modules provide tools for +identifying time critical sections in larger blocks of code. \section{Quality Control\label{quality-control}} @@ -4737,32 +4737,30 @@ through the sophisticated and robust capabilities of its larger packages. For example: -* The \ulink{\module{xmlrpclib}}{../lib/module-xmlrpclib.html} and -\ulink{\module{SimpleXMLRPCServer}}{../lib/module-SimpleXMLRPCServer.html} -modules make implementing remote procedure calls into an almost trivial -task. Despite the names, no direct knowledge or handling of XML is needed. - -* The \ulink{\module{email}}{../lib/module-email.html} -package is a library for managing email messages, -including MIME and other RFC 2822-based message documents. Unlike -\module{smtplib} and \module{poplib} which actually send and receive -messages, the email package has a complete toolset for building or -decoding complex message structures (including attachments) -and for implementing internet encoding and header protocols. - -* The \ulink{\module{xml.dom}}{../lib/module-xml.dom.html} and -\ulink{\module{xml.sax}}{../lib/module-xml.sax.html} packages provide -robust support for parsing this popular data interchange format. Likewise, -the \module{csv} module supports direct reads and writes in a common -database format. Together, these modules and packages greatly simplify -data interchange between python applications and other tools. - -* Internationalization is supported by a number of modules including -\ulink{\module{gettext}}{../lib/module-gettext.html}, -\ulink{\module{locale}}{../lib/module-locale.html}, and the -\ulink{\module{codecs}}{../lib/module-codecs.html} package. - - +\begin{itemize} +\item The \ulink{\module{xmlrpclib}}{../lib/module-xmlrpclib.html} and + \ulink{\module{SimpleXMLRPCServer}}{../lib/module-SimpleXMLRPCServer.html} + modules make implementing remote procedure calls into an almost trivial task. + Despite the names, no direct knowledge or handling of XML is needed. +\item The \ulink{\module{email}}{../lib/module-email.html} package is a library + for managing email messages, including MIME and other RFC 2822-based message + documents. Unlike \ulink{\module{smptlib}}{../lib/module-smtplib.html} and + \ulink{\module{poplib}}{../lib/module-poplib.html} which actually send and + receive messages, the email package has a complete toolset for building or + decoding complex message structures (including attachments) and for + implementing internet encoding and header protocols. +\item The \ulink{\module{xml.dom}}{../lib/module-xml.dom.html} and + \ulink{\module{xml.sax}}{../lib/module-xml.sax.html} packages provide robust + support for parsing this popular data interchange format. Likewise, the + \ulink{\module{csv}}{../lib/module-csv.html} module supports direct reads and + writes in a common database format. Together, these modules and packages + greatly simplify data interchange between python applications and other + tools. +\item Internationalization is supported by a number of modules including + \ulink{\module{gettext}}{../lib/module-gettext.html}, + \ulink{\module{locale}}{../lib/module-locale.html}, and the + \ulink{\module{codecs}}{../lib/module-codecs.html} package. +\end{itemize} \chapter{Brief Tour of the Standard Library -- Part II\label{briefTourTwo}} From tim_one at users.sourceforge.net Sat Sep 25 02:10:56 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 02:10:59 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5908/Doc/lib Modified Files: libdoctest.tex Log Message: Since the LaTeX isn't doctest'ed, examples are always wrong . Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.44 retrieving revision 1.45 diff -u -d -r1.44 -r1.45 --- libdoctest.tex 21 Sep 2004 03:00:51 -0000 1.44 +++ libdoctest.tex 25 Sep 2004 00:10:53 -0000 1.45 @@ -2,8 +2,8 @@ Test interactive Python examples} \declaremodule{standard}{doctest} -\moduleauthor{Tim Peters}{tim_one@users.sourceforge.net} -\sectionauthor{Tim Peters}{tim_one@users.sourceforge.net} +\moduleauthor{Tim Peters}{tim@python.org} +\sectionauthor{Tim Peters}{tim@python.org} \sectionauthor{Moshe Zadka}{moshez@debian.org} \sectionauthor{Edward Loper}{edloper@users.sourceforge.net} @@ -11,17 +11,21 @@ The \module{doctest} module searches for pieces of text that look like interactive Python sessions, and then executes those sessions to -verify that they work exactly as shown. There are two common ways to +verify that they work exactly as shown. There are several common ways to use doctest: -\begin{enumerate} +\begin{itemize} \item To check that a module's docstrings are up-to-date by verifying that all interactive examples still work as documented. \item To perform regression testing by verifying that interactive examples from a test file or a test object work as expected. -\end{enumerate} +\item To write tutorial documentation for a package, liberally + illustrated with input-ouput examples. Depending on whether + the examples or the expository text are emphasized, this has + the flavor of "literate testing" or "executable documentation". +\end{itemize} -Here's a complete but small example: +Here's a complete but small example module: \begin{verbatim} """ @@ -81,16 +85,13 @@ result = 1 factor = 2 while factor <= n: - try: - result *= factor - except OverflowError: - result *= long(factor) + result *= factor factor += 1 return result def _test(): import doctest - return doctest.testmod() + doctest.testmod() if __name__ == "__main__": _test() @@ -138,10 +139,12 @@ ... OverflowError: n too large ok +1 items had no tests: + __main__._test 2 items passed all tests: - 1 tests in example - 8 tests in example.factorial -9 tests in 2 items. + 1 tests in __main__ + 8 tests in __main__.factorial +9 tests in 3 items. 9 passed and 0 failed. Test passed. $ @@ -150,9 +153,10 @@ That's all you need to know to start making productive use of \module{doctest}! Jump in. The following sections provide full details. Note that there are many examples of doctests in -the standard Python test suite and libraries. +the standard Python test suite and libraries. Especially useful examples +can be found in the standard test file \file{Lib/test/test_doctest.py}. -\subsection{Simple Usage: Checking Examples in +\subsection{Simple Usage: Checking Examples in Docstrings\label{doctest-simple-testmod}} The simplest way to start using doctest (but not necessarily the way @@ -1262,7 +1266,7 @@ \class{DocTestFinder} defines the following method: -\begin{methoddesc}{find}{obj\optional{, name}\optional{, +\begin{methoddesc}{find}{obj\optional{, name}\optional{, module}\optional{, globs}\optional{, extraglobs}} Return a list of the \class{DocTest}s that are defined by \var{obj}'s docstring, or by any of its contained objects' From tim_one at users.sourceforge.net Sat Sep 25 02:11:46 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 02:11:50 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6112/Doc/lib Modified Files: libdoctest.tex Log Message: Typo. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.45 retrieving revision 1.46 diff -u -d -r1.45 -r1.46 --- libdoctest.tex 25 Sep 2004 00:10:53 -0000 1.45 +++ libdoctest.tex 25 Sep 2004 00:11:43 -0000 1.46 @@ -20,7 +20,7 @@ \item To perform regression testing by verifying that interactive examples from a test file or a test object work as expected. \item To write tutorial documentation for a package, liberally - illustrated with input-ouput examples. Depending on whether + illustrated with input-output examples. Depending on whether the examples or the expository text are emphasized, this has the flavor of "literate testing" or "executable documentation". \end{itemize} From tim_one at users.sourceforge.net Sat Sep 25 02:49:56 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 02:49:58 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12175/Doc/lib Modified Files: libdoctest.tex Log Message: Beef up the section on testfile(), giving a complete example in reStructuredText format. Remove words describing the return value of testmod() and testfile() in the intro sections, since it's never useful in such simple cases. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.46 retrieving revision 1.47 diff -u -d -r1.46 -r1.47 --- libdoctest.tex 25 Sep 2004 00:11:43 -0000 1.46 +++ libdoctest.tex 25 Sep 2004 00:49:53 -0000 1.47 @@ -165,14 +165,13 @@ \begin{verbatim} def _test(): import doctest - return doctest.testmod() + doctest.testmod() if __name__ == "__main__": _test() \end{verbatim} -\module{doctest} then examines docstrings in the module calling -\function{testmod()}. +\module{doctest} then examines docstrings in module \module{M}. Running the module as a script causes the examples in the docstrings to get executed and verified: @@ -184,7 +183,7 @@ This won't display anything unless an example fails, in which case the failing example(s) and the cause(s) of the failure(s) are printed to stdout, and the final line of output is -\samp{'***Test Failed*** \var{N} failures.'}, where \var{N} is the +\samp{***Test Failed*** \var{N} failures.}, where \var{N} is the number of examples that failed. Run it with the \programopt{-v} switch instead: @@ -199,12 +198,8 @@ You can force verbose mode by passing \code{verbose=True} to \function{testmod()}, or prohibit it by passing \code{verbose=False}. In either of those cases, -\code{sys.argv} is not examined by \function{testmod()}. - -In any case, \function{testmod()} returns a 2-tuple of ints -\samp{(\var{failure_count}, \var{test_count})}, where -\var{failure_count} is the number of docstring examples that failed -and \var{test_count} is the total number of docstring examples tested. +\code{sys.argv} is not examined by \function{testmod()} (so passing +\programopt{-v} or not has no effect). For more information on \function{testmod()}, see section~\ref{doctest-basic-api}. @@ -218,15 +213,50 @@ \begin{verbatim} import doctest -doctest.testfile("mytests.txt") +doctest.testfile("example.txt") \end{verbatim} -This short script will execute and verify any interactive Python -examples contained in the file \file{mytests.txt}. As with -\function{testmod()}, it won't display anything unless an example -fails. If an example does fail, then the failing example(s) and the -cause(s) of the failure(s) are printed to stdout, using the same -format as \function{testmod()}. +That short script executes and verifies any interactive Python +examples contained in the file \file{example.txt}. The file content +is treated as if it were a single giant docstring; the file doesn't +need to contain a Python program! For example, perhaps \file{example.txt} +contains this: + +\begin{verbatim} +The ``example`` module +====================== + +Using ``factorial`` +------------------- + +This is an example text file in reStructuredText format. First import +``factorial`` from the ``example`` module: + + >>> from example import factorial + +Now use it: + + >>> factorial(6) + 120 +\end{verbatim} + +Running \code{doctest.testfile("example.txt")} then finds the error +in this documentation: + +\begin{verbatim} +File "./example.txt", line 14, in example.txt +Failed example: + factorial(6) +Expected: + 120 +Got: + 720 +\end{verbatim} + +As with \function{testmod()}, \function{testfile()} won't display anything +unless an example fails. If an example does fail, then the failing +example(s) and the cause(s) of the failure(s) are printed to stdout, using +the same format as \function{testmod()}. By default, \function{testfile()} looks for files in the calling module's directory. See section~\ref{doctest-basic-api} for a @@ -235,11 +265,7 @@ Like \function{testmod()}, \function{testfile()}'s verbosity can be set with the \programopt{-v} command-line switch or with the optional -keyword argument \var{verbose}. And like \function{testmod()}, -\function{testfile()} returns a 2-tuple of ints -\samp{(\var{failure_count}, \var{test_count})}, where -\var{failure_count} is the number of docstring examples that failed -and \var{test_count} is the total number of docstring examples tested. +keyword argument \var{verbose}. For more information on \function{testfile()}, see section~\ref{doctest-basic-api}. From jlgijsbers at users.sourceforge.net Sat Sep 25 02:55:41 2004 From: jlgijsbers at users.sourceforge.net (jlgijsbers@users.sourceforge.net) Date: Sat Sep 25 02:55:44 2004 Subject: [Python-checkins] python/dist/src/Doc/tut tut.tex,1.251,1.252 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13450 Modified Files: tut.tex Log Message: Raymond observed that sometimes it's better not to link modules, so I reverted part of my previous last changes. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.251 retrieving revision 1.252 diff -u -d -r1.251 -r1.252 --- tut.tex 24 Sep 2004 23:25:25 -0000 1.251 +++ tut.tex 25 Sep 2004 00:55:38 -0000 1.252 @@ -4682,9 +4682,9 @@ \end{verbatim} In contrast to \module{timeit}'s fine level of granularity, the -\ulink{\module{profile}}{../lib/module-profile.html} and -\ulink{\module{pstats}}{../lib/module-pstats.html} modules provide tools for -identifying time critical sections in larger blocks of code. +\ulink{\module{profile}}{../lib/module-profile.html} and \module{pstats} +modules provide tools for identifying time critical sections in larger blocks +of code. \section{Quality Control\label{quality-control}} @@ -4744,10 +4744,9 @@ Despite the names, no direct knowledge or handling of XML is needed. \item The \ulink{\module{email}}{../lib/module-email.html} package is a library for managing email messages, including MIME and other RFC 2822-based message - documents. Unlike \ulink{\module{smptlib}}{../lib/module-smtplib.html} and - \ulink{\module{poplib}}{../lib/module-poplib.html} which actually send and - receive messages, the email package has a complete toolset for building or - decoding complex message structures (including attachments) and for + documents. Unlike \module{smptlib} and \module{poplib} which actually send + and receive messages, the email package has a complete toolset for building + or decoding complex message structures (including attachments) and for implementing internet encoding and header protocols. \item The \ulink{\module{xml.dom}}{../lib/module-xml.dom.html} and \ulink{\module{xml.sax}}{../lib/module-xml.sax.html} packages provide robust From tim_one at users.sourceforge.net Sat Sep 25 03:22:32 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 03:22:35 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.47,1.48 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17874/Doc/lib Modified Files: libdoctest.tex Log Message: In the "doctest warnings" section, removed obsolete info, and noted that ELLIPSIS can be used to deal with examples that embed object addresses. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.47 retrieving revision 1.48 diff -u -d -r1.47 -r1.48 --- libdoctest.tex 25 Sep 2004 00:49:53 -0000 1.47 +++ libdoctest.tex 25 Sep 2004 01:22:29 -0000 1.48 @@ -365,8 +365,8 @@ \end{verbatim} Otherwise, the backslash will be interpreted as part of the string. - E.g., the "{\textbackslash}" above would be interpreted as a newline - character. Alternatively, you can double each backslash in the + For example, the "{\textbackslash}" above would be interpreted as a + newline character. Alternatively, you can double each backslash in the doctest version (and not use a raw string): \begin{verbatim} @@ -497,8 +497,9 @@ \end{itemize} -\versionchanged[The ability to handle a multi-line exception detail - was added]{2.4} +\versionchanged[The ability to handle a multi-line exception detail, + and the \constant{IGNORE_EXCEPTION_DETAIL} doctest option, + were added]{2.4} \subsubsection{Option Flags and Directives\label{doctest-options}} @@ -750,6 +751,17 @@ \begin{verbatim} >>> id(1.0) # certain to fail some of the time 7948648 +>>> class C: pass +>>> C() # the default repr() for instances embeds an address +<__main__.C instance at 0x00AC18F0> +\end{verbatim} + +The \constant{ELLIPSIS} directive gives a nice approach for the last +example: + +\begin{verbatim} +>>> C() #doctest: +ELLIPSIS +<__main__.C instance at 0x...> \end{verbatim} Floating-point numbers are also subject to small output variations across @@ -776,34 +788,6 @@ Simple fractions are also easier for people to understand, and that makes for better documentation. -\item Be careful if you have code that must only execute once. - -If you have module-level code that must only execute once, a more foolproof -definition of \function{_test()} is - -% [XX] How is this safer?? The only difference I see is that this -% imports (but doesn't use) sys. -edloper -\begin{verbatim} -def _test(): - import doctest, sys - doctest.testmod() -\end{verbatim} - -\item WYSIWYG isn't always the case, starting in Python 2.3. The - string form of boolean results changed from \code{'0'} and - \code{'1'} to \code{'False'} and \code{'True'} in Python 2.3. - This makes it clumsy to write a doctest showing boolean results that - passes under multiple versions of Python. In Python 2.3, by default, - and as a special case, if an expected output block consists solely - of \code{'0'} and the actual output block consists solely of - \code{'False'}, that's accepted as an exact match, and similarly for - \code{'1'} versus \code{'True'}. This behavior can be turned off by - passing the new (in 2.3) module constant - \constant{DONT_ACCEPT_TRUE_FOR_1} as the value of \function{testmod()}'s - new (in 2.3) optional \var{optionflags} argument. Some years after - the integer spellings of booleans are history, this hack will - probably be removed again. - \end{itemize} \subsection{Basic API\label{doctest-basic-api}} From tim_one at users.sourceforge.net Sat Sep 25 03:30:19 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 03:30:22 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.48,1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19010/Doc/lib Modified Files: libdoctest.tex Log Message: Since the doctest warnings section was reduced to one bullet point, get rid of the itemize structure. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.48 retrieving revision 1.49 diff -u -d -r1.48 -r1.49 --- libdoctest.tex 25 Sep 2004 01:22:29 -0000 1.48 +++ libdoctest.tex 25 Sep 2004 01:30:16 -0000 1.49 @@ -712,14 +712,12 @@ \subsubsection{Warnings\label{doctest-warnings}} -\begin{itemize} - -\item \module{doctest} is serious about requiring exact matches in expected - output. If even a single character doesn't match, the test fails. This - will probably surprise you a few times, as you learn exactly what Python - does and doesn't guarantee about output. For example, when printing a - dict, Python doesn't guarantee that the key-value pairs will be printed - in any particular order, so a test like +\module{doctest} is serious about requiring exact matches in expected +output. If even a single character doesn't match, the test fails. This +will probably surprise you a few times, as you learn exactly what Python +does and doesn't guarantee about output. For example, when printing a +dict, Python doesn't guarantee that the key-value pairs will be printed +in any particular order, so a test like % Hey! What happened to Monty Python examples? % Tim: ask Guido -- it's his example! @@ -788,8 +786,6 @@ Simple fractions are also easier for people to understand, and that makes for better documentation. -\end{itemize} - \subsection{Basic API\label{doctest-basic-api}} The functions \function{testmod()} and \function{testfile()} provide a From bcannon at users.sourceforge.net Sat Sep 25 03:37:26 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Sat Sep 25 03:37:29 2004 Subject: [Python-checkins] python/dist/src/Objects object.c,2.223,2.224 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20010/Objects Modified Files: object.c Log Message: Remove 'extern' declaration for _Py_SwappedOp. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.223 retrieving revision 2.224 diff -u -d -r2.223 -r2.224 --- object.c 23 Sep 2004 02:39:37 -0000 2.223 +++ object.c 25 Sep 2004 01:37:24 -0000 2.224 @@ -476,7 +476,7 @@ ? (t)->tp_richcompare : NULL) /* Map rich comparison operators to their swapped version, e.g. LT --> GT */ -extern int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE}; +int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE}; /* Try a genuine rich comparison, returning an object. Return: NULL for exception; From bcannon at users.sourceforge.net Sat Sep 25 03:39:58 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Sat Sep 25 03:40:01 2004 Subject: [Python-checkins] python/dist/src/Misc vimrc,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20650/Misc Modified Files: vimrc Log Message: Add warning notation about using 'bomb' setting. Index: vimrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/vimrc,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- vimrc 20 Sep 2004 22:33:21 -0000 1.2 +++ vimrc 25 Sep 2004 01:39:56 -0000 1.3 @@ -67,7 +67,9 @@ " Set the default file encoding to UTF-8: ``set encoding=utf-8`` " Put a marker at the beginning of the file to differentiate between UTF and -" UCS encoding: ``set bomb`` +" UCS encoding (warning: always done when reasonable, which can mess up shells +" into thinking a text file is actually a binary file when executing the text +" file): ``set bomb`` " For full syntax highlighting: "``let python_highlight_all=1`` From tim_one at users.sourceforge.net Sat Sep 25 03:51:51 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 03:51:54 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.49,1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22822/Doc/lib Modified Files: libdoctest.tex Log Message: Repaired mistakes in the descriptions of testmod()/testfile(), and squashed massive duplication of common argument descriptions. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.49 retrieving revision 1.50 diff -u -d -r1.49 -r1.50 --- libdoctest.tex 25 Sep 2004 01:30:16 -0000 1.49 +++ libdoctest.tex 25 Sep 2004 01:51:49 -0000 1.50 @@ -790,7 +790,7 @@ The functions \function{testmod()} and \function{testfile()} provide a simple interface to doctest that should be sufficient for most basic -uses. For a more informal introduction to these two functions, see +uses. For a less formal introduction to these two functions, see sections \ref{doctest-simple-testmod} and \ref{doctest-simple-testfile}. @@ -811,15 +811,15 @@ \begin{itemize} \item If \var{module_relative} is \code{True} (the default), then - \var{filename} specifies an os-independent module-relative + \var{filename} specifies an OS-independent module-relative path. By default, this path is relative to the calling module's directory; but if the \var{package} argument is specified, then it is relative to that package. To ensure - os-independence, \var{filename} should use \code{/} characters + OS-independence, \var{filename} should use \code{/} characters to separate path segments, and may not be an absolute path (i.e., it may not begin with \code{/}). \item If \var{module_relative} is \code{False}, then \var{filename} - specifies an os-specific path. The path may be absolute or + specifies an OS-specific path. The path may be absolute or relative; relative paths are resolved with respect to the current working directory. \end{itemize} @@ -835,9 +835,9 @@ if \var{module_relative} is \code{False}. Optional argument \var{globs} gives a dict to be used as the globals - when executing examples; by default, or if \code{None}, - \code{\var{m}.__dict__} is used. A new shallow copy of this dict is + when executing examples. A new shallow copy of this dict is created for the doctest, so its examples start with a clean slate. + By default, or if \code{None}, a new empty dict is used. Optional argument \var{extraglobs} gives a dict merged into the globals used to execute examples. This works like @@ -880,8 +880,8 @@ specified in keyword form. Test examples in docstrings in functions and classes reachable - from module \var{m} (or the current module if \var{m} is not supplied - or is \code{None}), starting with \code{\var{m}.__doc__}. + from module \var{m} (or module \module{__main__} if \var{m} is not + supplied or is \code{None}), starting with \code{\var{m}.__doc__}. Also test examples reachable from dict \code{\var{m}.__test__}, if it exists and is not \code{None}. \code{\var{m}.__test__} maps @@ -897,40 +897,6 @@ Optional argument \var{name} gives the name of the module; by default, or if \code{None}, \code{\var{m}.__name__} is used. - Optional argument \var{globs} gives a dict to be used as the globals - when executing examples; by default, or if \code{None}, - \code{\var{m}.__dict__} is used. A new shallow copy of this dict is - created for each docstring with examples, so that each docstring's - examples start with a clean slate. - - Optional argument \var{extraglobs} gives a dict merged into the - globals used to execute examples. This works like - \method{dict.update()}: if \var{globs} and \var{extraglobs} have a - common key, the associated value in \var{extraglobs} appears in the - combined dict. By default, or if \code{None}, no extra globals are - used. This is an advanced feature that allows parameterization of - doctests. For example, a doctest can be written for a base class, using - a generic name for the class, then reused to test any number of - subclasses by passing an \var{extraglobs} dict mapping the generic - name to the subclass to be tested. - - Optional argument \var{verbose} prints lots of stuff if true, and prints - only failures if false; by default, or if \code{None}, it's true - if and only if \code{'-v'} is in \code{sys.argv}. - - Optional argument \var{report} prints a summary at the end when true, - else prints nothing at the end. In verbose mode, the summary is - detailed, else the summary is very brief (in fact, empty if all tests - passed). - - Optional argument \var{optionflags} or's together option flags. See - see section~\ref{doctest-options}. - - Optional argument \var{raise_on_error} defaults to false. If true, - an exception is raised upon the first failure or unexpected exception - in an example. This allows failures to be post-mortem debugged. - Default behavior is to continue running examples. - Optional argument \var{exclude_empty} defaults to false. If true, objects for which no doctests are found are excluded from consideration. The default is a backward compatibility hack, so that code still @@ -939,6 +905,11 @@ The \var{exclude_empty} argument to the newer \class{DocTestFinder} constructor defaults to true. + Optional arguments \var{extraglobs}, \var{verbose}, \var{report}, + \var{optionflags}, \var{raise_on_error}, and \var{globs} are the same as + for function \function{testfile()} above, except that \var{globs} + defaults to \code{\var{m}.__dict__}. + Optional argument \var{isprivate} specifies a function used to determine whether a name is private. The default function treats all names as public. \var{isprivate} can be set to @@ -988,15 +959,15 @@ \begin{itemize} \item If \var{module_relative} is \code{True} (the default), then - each filename specifies an os-independent module-relative + each filename specifies an OS-independent module-relative path. By default, this path is relative to the calling module's directory; but if the \var{package} argument is specified, then it is relative to that package. To ensure - os-independence, each filename should use \code{/} characters + OS-independence, each filename should use \code{/} characters to separate path segments, and may not be an absolute path (i.e., it may not begin with \code{/}). \item If \var{module_relative} is \code{False}, then each filename - specifies an os-specific path. The path may be absolute or + specifies an OS-specific path. The path may be absolute or relative; relative paths are resolved with respect to the current working directory. \end{itemize} From tim_one at users.sourceforge.net Sat Sep 25 04:41:31 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 04:41:35 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30047/lib Modified Files: doctest.py Log Message: Removed most of the module docstring. There's too much to explain now, and the LaTeX docs are in increasingly good shape. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.109 retrieving revision 1.110 diff -u -d -r1.109 -r1.110 --- doctest.py 21 Sep 2004 03:24:24 -0000 1.109 +++ doctest.py 25 Sep 2004 02:41:28 -0000 1.110 @@ -8,13 +8,11 @@ r"""Module doctest -- a framework for running examples in docstrings. -NORMAL USAGE - In simplest use, end each module M to be tested with: def _test(): import doctest - return doctest.testmod() + doctest.testmod() if __name__ == "__main__": _test() @@ -40,133 +38,13 @@ it by passing "verbose=False". In either of those cases, sys.argv is not examined by testmod. -In any case, testmod returns a 2-tuple of ints (f, t), where f is the -number of docstring examples that failed and t is the total number of -docstring examples attempted. - There are a variety of other ways to run doctests, including integration with the unittest framework, and support for running non-Python text files containing doctests. There are also many ways to override parts of doctest's default behaviors. See the Library Reference Manual for details. - - -WHICH DOCSTRINGS ARE EXAMINED? - -+ M.__doc__. - -+ f.__doc__ for all functions f in M.__dict__.values(), except those - defined in other modules. - -+ C.__doc__ for all classes C in M.__dict__.values(), except those - defined in other modules. - -+ If M.__test__ exists and "is true", it must be a dict, and - each entry maps a (string) name to a function object, class object, or - string. Function and class object docstrings found from M.__test__ - are searched, and strings are searched directly as if they were docstrings. - In output, a key K in M.__test__ appears with name - .__test__.K - -Any classes found are recursively searched similarly, to test docstrings in -their contained methods and nested classes. - - -WHAT'S THE EXECUTION CONTEXT? - -By default, each time testmod finds a docstring to test, it uses a *copy* -of M's globals (so that running tests on a module doesn't change the -module's real globals, and so that one test in M can't leave behind crumbs -that accidentally allow another test to work). This means examples can -freely use any names defined at top-level in M. It also means that sloppy -imports (see above) can cause examples in external docstrings to use -globals inappropriate for them. - -You can force use of your own dict as the execution context by passing -"globs=your_dict" to testmod instead. Presumably this would be a copy of -M.__dict__ merged with the globals from other imported modules. - - -WHAT ABOUT EXCEPTIONS? - -No problem, as long as the only output generated by the example is the -traceback itself. For example: - - >>> [1, 2, 3].remove(42) - Traceback (most recent call last): - File "", line 1, in ? - ValueError: list.remove(x): x not in list - >>> - -Note that only the exception type and value are compared. - - -SO WHAT DOES A DOCTEST EXAMPLE LOOK LIKE ALREADY!? - -Oh ya. It's easy! In most cases a copy-and-paste of an interactive -console session works fine -- just make sure the leading whitespace is -rigidly consistent (you can mix tabs and spaces if you're too lazy to do it -right, but doctest is not in the business of guessing what you think a tab -means). - - >>> # comments are ignored - >>> x = 12 - >>> x - 12 - >>> if x == 13: - ... print "yes" - ... else: - ... print "no" - ... print "NO" - ... print "NO!!!" - ... - no - NO - NO!!! - >>> - -Any expected output must immediately follow the final ">>>" or "..." line -containing the code, and the expected output (if any) extends to the next -">>>" or all-whitespace line. That's it. - -Bummers: - -+ Output to stdout is captured, but not output to stderr (exception - tracebacks are captured via a different means). - -+ If you continue a line via backslashing in an interactive session, - or for any other reason use a backslash, you should use a raw - docstring, which will preserve your backslahses exactly as you type - them: - - >>> def f(x): - ... r'''Backslashes in a raw docstring: m\n''' - >>> print f.__doc__ - Backslashes in a raw docstring: m\n - - Otherwise, the backslash will be interpreted as part of the string. - E.g., the "\n" above would be interpreted as a newline character. - Alternatively, you can double each backslash in the doctest version - (and not use a raw string): - - >>> def f(x): - ... '''Backslashes in a raw docstring: m\\n''' - >>> print f.__doc__ - Backslashes in a raw docstring: m\n - -The starting column doesn't matter: - ->>> assert "Easy!" - >>> import math - >>> math.floor(1.9) - 1.0 - -and as many leading whitespace characters are stripped from the expected -output as appeared in the initial ">>>" line that triggered it. - -If you execute this very file, the examples above will be found and -executed. """ + __docformat__ = 'reStructuredText en' __all__ = [ From tim_one at users.sourceforge.net Sat Sep 25 05:02:26 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 05:02:28 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv947/Doc/lib Modified Files: libdoctest.tex Log Message: Explain the motivation for the unittest functions, and beef up the example. Squash repeated argument descriptions. Minor rewordings. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- libdoctest.tex 25 Sep 2004 01:51:49 -0000 1.50 +++ libdoctest.tex 25 Sep 2004 03:02:23 -0000 1.51 @@ -860,7 +860,7 @@ passed). Optional argument \var{optionflags} or's together option flags. See - see section~\ref{doctest-options}. + section~\ref{doctest-options}. Optional argument \var{raise_on_error} defaults to false. If true, an exception is raised upon the first failure or unexpected exception @@ -927,34 +927,46 @@ \subsection{Unittest API\label{doctest-unittest-api}} -Doctest provides several functions that can be used to create -\module{unittest} test suites from doctest examples. These test -suites can then be run using \module{unittest} test runners: +As your collection of doctest'ed modules grows, you'll want a way to run +all their doctests systematically. Prior to Python 2.4, \module{doctest} +had a barely documented \class{Tester} class that supplied a rudimentary +way to combine doctests from multiple modules. \class{Tester} was feeble, +and in practice most serious Python testing frameworks build on the +\module{unittest} module, which supplies many flexible ways to combine +tests from multiple sources. So, in Python 2.4, module{doctest}'s +\class{Tester} class is deprecated, and \module{doctest} provides several +functions that can be used to create \module{unittest} test suites from +modules and text files containing doctests. These test suites can then be +run using \module{unittest} test runners: \begin{verbatim} - import unittest - import doctest - import my_module_with_doctests +import unittest +import doctest +import my_module_with_doctests, and_another - suite = doctest.DocTestSuite(my_module_with_doctests) - runner = unittest.TextTestRunner() - runner.run(suite) +suite = unittest.TestSuite() +for mod in my_module_with_doctests, and_another: + suite.addTest(doctest.DocTestSuite(mod)) +runner = unittest.TextTestRunner() +runner.run(suite) \end{verbatim} \begin{funcdesc}{DocFileSuite}{*paths, **kw} Convert doctest tests from one or more text files to a \class{\refmodule{unittest}.TestSuite}. - The returned \class{TestSuite} is to be run by the unittest + The returned \class{unittest.TestSuite} is to be run by the unittest framework and runs the interactive examples in each file. If an example in any file fails, then the synthesized unit test fails, and a \exception{failureException} exception is raised showing the name of the file containing the test and a (sometimes approximate) line number. - A number of options may be provided as keyword arguments: + Pass one or more paths (as strings) to text files to be examined. - The optional argument \var{module_relative} specifies how + Options may be provided as keyword arguments: + + Optional argument \var{module_relative} specifies how the the filenames in \var{paths} should be interpreted: \begin{itemize} @@ -972,33 +984,33 @@ current working directory. \end{itemize} - The optional argument \var{package} is a Python package or the name + Optional argument \var{package} is a Python package or the name of a Python package whose directory should be used as the base directory for module-relative filenames. If no package is specified, then the calling module's directory is used as the base directory for module-relative filenames. It is an error to specify \var{package} if \var{module_relative} is \code{False}. - The optional argument \var{setUp} specifies a set-up function for + Optional argument \var{setUp} specifies a set-up function for the test suite. This is called before running the tests in each file. The \var{setUp} function will be passed a \class{DocTest} object. The setUp function can access the test globals as the \var{globs} attribute of the test passed. - The optional argument \var{tearDown} specifies a tear-down function + Optional argument \var{tearDown} specifies a tear-down function for the test suite. This is called after running the tests in each file. The \var{tearDown} function will be passed a \class{DocTest} object. The setUp function can access the test globals as the \var{globs} attribute of the test passed. - The optional argument \var{globs} is a dictionary containing the + Optional argument \var{globs} is a dictionary containing the initial global variables for the tests. A new copy of this dictionary is created for each test. By default, \var{globs} is - empty. + a new empty dictionary. - The optional argument \var{optionflags} specifies the default - doctest options for the tests. It is created by or-ing together - individual option flags. + Optional argument \var{optionflags} specifies the default + doctest options for the tests, created by or-ing together + individual option flags. See section~\ref{doctest-options}. \versionadded{2.4} \end{funcdesc} @@ -1010,58 +1022,44 @@ Convert doctest tests for a module to a \class{\refmodule{unittest}.TestSuite}. - The returned \class{TestSuite} is to be run by the unittest framework - and runs each doctest in the module. If any of the doctests fail, - then the synthesized unit test fails, and a \exception{failureException} - exception is raised showing the name of the file containing the test and a - (sometimes approximate) line number. + The returned \class{unittest.TestSuite} is to be run by the unittest + framework and runs each doctest in the module. If any of the doctests + fail, then the synthesized unit test fails, and a + \exception{failureException} exception is raised showing the name of the + file containing the test and a (sometimes approximate) line number. - The optional argument \var{module} provides the module to be tested. It + Optional argument \var{module} provides the module to be tested. It can be a module object or a (possibly dotted) module name. If not specified, the module calling this function is used. - The optional argument \var{globs} is a dictionary containing the + Optional argument \var{globs} is a dictionary containing the initial global variables for the tests. A new copy of this dictionary is created for each test. By default, \var{globs} is - empty. + a new empty dictionary. - The optional argument \var{extraglobs} specifies an extra set of + Optional argument \var{extraglobs} specifies an extra set of global variables, which is merged into \var{globs}. By default, no extra globals are used. - The optional argument \var{test_finder} is the \class{DocTestFinder} + Optional argument \var{test_finder} is the \class{DocTestFinder} object (or a drop-in replacement) that is used to extract doctests from the module. - The optional argument \var{setUp} specifies a set-up function for - the test suite. This is called before running the tests in each - file. The \var{setUp} function will be passed a \class{DocTest} - object. The setUp function can access the test globals as the - \var{globs} attribute of the test passed. - - The optional argument \var{tearDown} specifies a tear-down function - for the test suite. This is called after running the tests in each - file. The \var{tearDown} function will be passed a \class{DocTest} - object. The setUp function can access the test globals as the - \var{globs} attribute of the test passed. - - The optional argument \var{optionflags} specifies the default - doctest options for the tests. It is created by or-ing together - individual option flags. + Optional arguments \var{setUp}, \var{tearDown}, and \var{optionflags} + are the same as for function \function{DocFileSuite()} above. \versionadded{2.3} \versionchanged[The parameters \var{globs}, \var{extraglobs}, \var{test_finder}, \var{setUp}, \var{tearDown}, and - \var{optionflags} were added]{2.4} - \versionchanged[This function now uses the same search technique as - \function{testmod()}.]{2.4} + \var{optionflags} were added; this function now uses the same search + technique as \function{testmod()}]{2.4} \end{funcdesc} \subsection{Advanced API\label{doctest-advanced-api}} The basic API is a simple wrapper that's intended to make doctest easy -to use. It is fairly flexible, and should meet most user's needs; -however, if you require more fine grained control over testing, or +to use. It is fairly flexible, and should meet most users' needs; +however, if you require more fine-grained control over testing, or wish to extend doctest's capabilities, then you should use the advanced API. From tim_one at users.sourceforge.net Sat Sep 25 05:50:44 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat Sep 25 05:50:49 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.51,1.52 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9212/Doc/lib Modified Files: libdoctest.tex Log Message: Assorted minor changes, plus a lot more soap. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.51 retrieving revision 1.52 diff -u -d -r1.51 -r1.52 --- libdoctest.tex 25 Sep 2004 03:02:23 -0000 1.51 +++ libdoctest.tex 25 Sep 2004 03:50:35 -0000 1.52 @@ -1090,7 +1090,7 @@ they match. \end{itemize} -The relationship between these processing classes is summarized in the +The relationships among these processing classes are summarized in the following diagram: \begin{verbatim} @@ -1099,7 +1099,7 @@ |module| --DocTestFinder-> | DocTest | --DocTestRunner-> results +------+ | ^ +---------+ | ^ (printed) | | | Example | | | - V | | ... | V | + v | | ... | v | DocTestParser | Example | OutputChecker +---------+ \end{verbatim} @@ -1196,7 +1196,7 @@ \end{memberdesc} \begin{memberdesc}{indent} - The example's indentation in the containing string. I.e., the + The example's indentation in the containing string, i.e., the number of space characters that preceed the example's first prompt. \end{memberdesc} @@ -1206,8 +1206,8 @@ \code{False}, which is used to override default options for this example. Any option flags not contained in this dictionary are left at their default value (as specified by the - \class{DocTestRunner}'s -\member{optionflags}). By default, no options are set. + \class{DocTestRunner}'s \member{optionflags}). + By default, no options are set. \end{memberdesc} \subsubsection{DocTestFinder objects\label{doctest-DocTestFinder}} @@ -1250,7 +1250,7 @@ The optional argument \var{name} specifies the object's name; this name will be used to construct names for the returned \class{DocTest}s. If \var{name} is not specified, then - \code{var.__name__} is used. + \code{\var{obj}.__name__} is used. The optional parameter \var{module} is the module that contains the given object. If the module is not specified or is None, then @@ -1258,7 +1258,7 @@ correct module. The object's module is used: \begin{itemize} - \item As a default namespace, if `globs` is not specified. + \item As a default namespace, if \var{globs} is not specified. \item To prevent the DocTestFinder from extracting DocTests from objects that are imported from other modules. (Contained objects with modules other than \var{module} are ignored.) @@ -1275,7 +1275,7 @@ The globals for each \class{DocTest} is formed by combining \var{globs} and \var{extraglobs} (bindings in \var{extraglobs} - override bindings in \var{globs}). A new copy of the globals + override bindings in \var{globs}). A new shallow copy of the globals dictionary is created for each \class{DocTest}. If \var{globs} is not specified, then it defaults to the module's \var{__dict__}, if specified, or \code{\{\}} otherwise. If \var{extraglobs} is not @@ -1577,15 +1577,16 @@ \subsection{Soapbox\label{doctest-soapbox}} -As mentioned in the introduction, \module{doctest} has two primary -uses: +As mentioned in the introduction, \module{doctest} has grown to have +three primary uses: \begin{enumerate} \item Checking examples in docstrings. \item Regression testing. +\item Executable documentation / literate testing. \end{enumerate} -These two uses have different requirements, and it is important to +These uses have different requirements, and it is important to distinguish them. In particular, filling your docstrings with obscure test cases makes for bad documentation. @@ -1593,39 +1594,44 @@ There's an art to this that needs to be learned---it may not be natural at first. Examples should add genuine value to the documentation. A good example can often be worth many words. -% [edloper] I think this may be excessive for many cases; let's -% just leave it to the user's judgement: -%% If possible, show just a few normal cases, show endcases, show -%% interesting subtle cases, and show an example of each kind of -%% exception that can be raised. You're probably testing for endcases -%% and subtle cases anyway in an interactive shell: -%% \refmodule{doctest} wants to make it as easy as possible to capture -%% those sessions, and will verify they continue to work as designed -%% forever after. If done with care, the examples will be invaluable for your users, and will pay back the time it takes to collect them many times over as the years go by and things change. I'm still amazed at how often one of -my \refmodule{doctest} examples stops working after a ``harmless'' +my \refmodule{doctest} examples stops working after a "harmless" change. -Doctest also makes an excellent tool for writing regression testing. -By interleaving prose and examples, it becomes much easier to keep -track of what's actually being tested, and why. When a test fails, -the prose descriptions makes it much easier to figure out what the -problem is, and how it should be fixed. Regression testing is best -confined to dedicated objects or files. There are several options for -organizing regressions: +Doctest also makes an excellent tool for regression testing, especially if +you don't skimp on explanatory text. By interleaving prose and examples, +it becomes much easier to keep track of what's actually being tested, and +why. When a test fails, good prose can make it much easier to figure out +what the problem is, and how it should be fixed. It's true that you could +write extensive comments in code-based testing, but few programmers do. +Many have found that using doctest approaches instead leads to much clearer +tests. Perhaps this is simply because doctest makes writing prose a little +easier than writing code, while writing comments in code is a little +harder. I think it goes deeper than just that: the natural attitude +when writing a doctest-based test is that you want to explain the fine +points of your software, and illustrate them with examples. This in +turn naturally leads to test files that start with the simplest features, +and logically progress to complications and edge cases. A coherent +narrative is the result, instead of a collection of isolated functions +that test isolated bits of functionality seemingly at random. It's +a different attitude, and produces different results, blurring the +distinction between testing and explaining. + +Regression testing is best confined to dedicated objects or files. There +are several options for organizing tests: \begin{itemize} +\item Write text files containing test cases as interactive examples, + and test the files using \function{testfile()} or + \function{DocFileSuite()}. This is recommended, although is + easiest to do for new projects, designed from the start to use + doctest. \item Define functions named \code{_regrtest_\textit{topic}} that consist of single docstrings, containing test cases for the named topics. These functions can be included in the same file as the module, or separated out into a separate test file. \item Define a \code{__test__} dictionary mapping from regression test topics to docstrings containing test cases. -\item Write a text file containing test cases as interactive examples, - and test that file using \function{testfunc()}. \end{itemize} - - - From rhettinger at users.sourceforge.net Sat Sep 25 10:09:26 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat Sep 25 10:09:29 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16722 Modified Files: libdoctest.tex Log Message: Fix double word error. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.52 retrieving revision 1.53 diff -u -d -r1.52 -r1.53 --- libdoctest.tex 25 Sep 2004 03:50:35 -0000 1.52 +++ libdoctest.tex 25 Sep 2004 08:09:23 -0000 1.53 @@ -967,7 +967,7 @@ Options may be provided as keyword arguments: Optional argument \var{module_relative} specifies how - the the filenames in \var{paths} should be interpreted: + the filenames in \var{paths} should be interpreted: \begin{itemize} \item If \var{module_relative} is \code{True} (the default), then From tim_one at users.sourceforge.net Sun Sep 26 03:24:26 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 03:24:27 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.110,1.111 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20970/Lib Modified Files: doctest.py Log Message: Removed two undocumented unittest support classes, and one undocumented unittest support function, from the public interface. If they're not documented, they shouldn't be public. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.110 retrieving revision 1.111 diff -u -d -r1.110 -r1.111 --- doctest.py 25 Sep 2004 02:41:28 -0000 1.110 +++ doctest.py 26 Sep 2004 01:24:23 -0000 1.111 @@ -83,10 +83,7 @@ # 7. Tester 'Tester', # 8. Unittest Support - 'DocTestCase', 'DocTestSuite', - 'DocFileCase', - 'DocFileTest', 'DocFileSuite', # 9. Debugging Support 'script_from_examples', From tim_one at users.sourceforge.net Sun Sep 26 03:50:29 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 03:50:33 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.111,1.112 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25940/Lib Modified Files: doctest.py Log Message: Add set_unittest_reportflags() to the public API. Docs will follow "soon", after I repair the LaTeX I somehow damaged. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.111 retrieving revision 1.112 diff -u -d -r1.111 -r1.112 --- doctest.py 26 Sep 2004 01:24:23 -0000 1.111 +++ doctest.py 26 Sep 2004 01:50:24 -0000 1.112 @@ -85,6 +85,7 @@ # 8. Unittest Support 'DocTestSuite', 'DocFileSuite', + 'set_unittest_reportflags', # 9. Debugging Support 'script_from_examples', 'testsource', From tim_one at users.sourceforge.net Sun Sep 26 04:12:42 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 04:12:46 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30898/Doc/lib Modified Files: libdoctest.tex Log Message: Document set_unittest_reportflags(). Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.53 retrieving revision 1.54 diff -u -d -r1.53 -r1.54 --- libdoctest.tex 25 Sep 2004 08:09:23 -0000 1.53 +++ libdoctest.tex 26 Sep 2004 02:12:40 -0000 1.54 @@ -933,8 +933,8 @@ way to combine doctests from multiple modules. \class{Tester} was feeble, and in practice most serious Python testing frameworks build on the \module{unittest} module, which supplies many flexible ways to combine -tests from multiple sources. So, in Python 2.4, module{doctest}'s -\class{Tester} class is deprecated, and \module{doctest} provides several +tests from multiple sources. So, in Python 2.4, \module{doctest}'s +\class{Tester} class is deprecated, and \module{doctest} provides two functions that can be used to create \module{unittest} test suites from modules and text files containing doctests. These test suites can then be run using \module{unittest} test runners: @@ -951,6 +951,9 @@ runner.run(suite) \end{verbatim} +There are two main functions for creating \class{unittest.TestSuite} +instances from text files and modules with doctests: + \begin{funcdesc}{DocFileSuite}{*paths, **kw} Convert doctest tests from one or more text files to a \class{\refmodule{unittest}.TestSuite}. @@ -1011,6 +1014,8 @@ Optional argument \var{optionflags} specifies the default doctest options for the tests, created by or-ing together individual option flags. See section~\ref{doctest-options}. + See function \function{set_unittest_reportflags()} below for + a better way to set reporting options. \versionadded{2.4} \end{funcdesc} @@ -1049,12 +1054,64 @@ are the same as for function \function{DocFileSuite()} above. \versionadded{2.3} + \versionchanged[The parameters \var{globs}, \var{extraglobs}, \var{test_finder}, \var{setUp}, \var{tearDown}, and \var{optionflags} were added; this function now uses the same search technique as \function{testmod()}]{2.4} \end{funcdesc} +Under the covers, \function{DocTestSuite()} creates a +\class{unittest.TestSuite} out of \class{doctest.DocTestCase} instances, +and \class{DocTestCase} is a subclass of \class{unittest.TestCase}. +\class{DocTestCase} isn't documented here (it's an internal detail), but +studying its code can answer questions about the exact details of +\module{unittest} integration. + +Similarly, \function{DocFileSuite()} creates a \class{unittest.TestSuite} +out of \class{doctest.DocFileCase} instances, and \class{DocFileCase} +is a subclass of \class{DocTestCase}. + +So both ways of creating a \class{unittest.TestSuite} run instances of +\class{DocTestCase}. This is important for a subtle reason: when you +run \module{doctest} functions yourself, you can control the +\module{doctest} options in use directly, by passing option flags to +\module{doctest} functions. However, if you're writing a \module{unittest} +framework, \module{unittest} ultimately controls when and how tests +get run. The framework author typically wants to control \module{doctest} +reporting options (perhaps, e.g., specified by command line options), +but there's no way to pass options through \module{unittest} to +\module{doctest} test runners. + +For this reason, \module{doctest} also supports a notion of +\module{doctest} reporting flags specific to \module{unittest} support, +via this function: + +\begin{funcdesc}{set_unittest_reportflags}{flags} + Set the \module{doctest} reporting flags to use. + + Argument \var{flags} or's together option flags. See + section~\ref{doctest-options}. Only "reporting flags" can be used. + + This is a module-global setting, and affects all future doctests run + by module \module{unittest}: the \method{runTest()} method of + \class{DocTestCase} looks at the option flags specified for the test + case when the \class{DocTestCase} instance was constructed. If no + reporting flags were specified (which is the typical and expected case), + \module{doctest}'s \module{unittest} reporting flags are or'ed into the + option flags, and the option flags so augmented are passed to the + \class{DocTestRunner} instance created to run the doctest. If any + reporting flags were specified when the \class{DocTestCase} instance + was constructed, \module{doctest}'s \module{unittest} reporting flags + are ignored. + + The value of the \module{unittest} reporting flags in effect before the + function was called is returned by the function. + + \versionadded{2.4} +\end{funcdesc} + + \subsection{Advanced API\label{doctest-advanced-api}} The basic API is a simple wrapper that's intended to make doctest easy From tim_one at users.sourceforge.net Sun Sep 26 04:38:43 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 04:38:47 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3828/Doc/lib Modified Files: libdoctest.tex Log Message: register_optionflag(): Moved from the Debugging section to the section on option flags; added a versionadded decoration. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.54 retrieving revision 1.55 diff -u -d -r1.54 -r1.55 --- libdoctest.tex 26 Sep 2004 02:12:40 -0000 1.54 +++ libdoctest.tex 26 Sep 2004 02:38:41 -0000 1.55 @@ -710,6 +710,25 @@ matches an empty line in actual output; and doctest directives were added]{2.4} +There's also a way to register new option flag names, although this +isn't useful unless you intend to extend \module{doctest} internals +via subclassing: + +\begin{funcdesc}{register_optionflag}{name} + Create a new option flag with a given name, and return the new + flag's integer value. \function{register_optionflag()} can be + used when subclassing \class{OutputChecker} or + \class{DocTestRunner} to create new options that are supported by + your subclasses. \function{register_optionflag} should always be + called using the following idiom: + +\begin{verbatim} + MY_FLAG = register_optionflag('MY_FLAG') +\end{verbatim} + + \versionadded{2.4} +\end{funcdesc} + \subsubsection{Warnings\label{doctest-warnings}} \module{doctest} is serious about requiring exact matches in expected @@ -1620,18 +1639,6 @@ returned by \function{sys.exc_info()}. \end{memberdesc} -\begin{funcdesc}{register_optionflag}{name} - Create a new option flag with a given name, and return the new - flag's integer value. \function{register_optionflag()} can be - used when subclassing \class{OutputChecker} or - \class{DocTestRunner} to create new options that are supported by - your subclasses. \function{register_optionflag} should always be - called using the following idiom: -\begin{verbatim} - MY_FLAG = register_optionflag('MY_FLAG') -\end{verbatim} -\end{funcdesc} - \subsection{Soapbox\label{doctest-soapbox}} As mentioned in the introduction, \module{doctest} has grown to have From tim_one at users.sourceforge.net Sun Sep 26 05:50:08 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 05:50:12 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.112,1.113 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18696/Lib Modified Files: doctest.py Log Message: Removed debug_script from the public API: no docs, not public. I'm in the process of writing docs for the other "missing" debug support functions. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.112 retrieving revision 1.113 diff -u -d -r1.112 -r1.113 --- doctest.py 26 Sep 2004 01:50:24 -0000 1.112 +++ doctest.py 26 Sep 2004 03:50:06 -0000 1.113 @@ -90,7 +90,6 @@ 'script_from_examples', 'testsource', 'debug_src', - 'debug_script', 'debug', ] From tim_one at users.sourceforge.net Sun Sep 26 07:10:03 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 07:10:06 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv848/doc/lib Modified Files: libdoctest.tex Log Message: Added a lot of new stuff to the debugging section. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.55 retrieving revision 1.56 diff -u -d -r1.55 -r1.56 --- libdoctest.tex 26 Sep 2004 02:38:41 -0000 1.55 +++ libdoctest.tex 26 Sep 2004 05:09:59 -0000 1.56 @@ -1547,34 +1547,174 @@ \subsection{Debugging\label{doctest-debugging}} -Doctest provides three mechanisms for debugging doctest examples: +Doctest provides several mechanisms for debugging doctest examples: -\begin{enumerate} -\item The \function{debug()} function converts a specified doctest - to a Python script, and executes that script using \module{pdb}. +\begin{itemize} +\item Several functions convert doctests to executable Python + programs, which can be run under the Python debugger, \refmodule{pdb}. \item The \class{DebugRunner} class is a subclass of \class{DocTestRunner} that raises an exception for the first failing example, containing information about that example. This information can be used to perform post-mortem debugging on the example. -\item The unittest cases generated by \function{DocTestSuite()} - support the \method{debug} method defined by +\item The \module{unittest} cases generated by \function{DocTestSuite()} + support the \method{debug()} method defined by \class{unittest.TestCase}. -\end{enumerate} +\item You can add a call to \function{pdb.set_trace()} in a doctest + example, and you'll drop into the Python debugger when that + line is executed. Then you can inspect current values of variables, + and so on. For example, suppose \file{a.py} contains just this + module docstring: -\begin{funcdesc}{debug}{module, name} - Debug a single doctest docstring. +\begin{verbatim} +""" +>>> def f(x): +... g(x*2) +>>> def g(x): +... print x+3 +... import pdb; pdb.set_trace() +>>> f(3) +9 +""" +\end{verbatim} - Provide the \var{module} (or dotted name of the module) containing - the docstring to be debugged and the fully qualified dotted - \var{name} of the object with the docstring to be debugged. + Then an interactive Python session may look like this: + +\begin{verbatim} +>>> import a, doctest +>>> doctest.testmod(a) +--Return-- +> (3)g()->None +-> import pdb; pdb.set_trace() +(Pdb) list + 1 def g(x): + 2 print x+3 + 3 -> import pdb; pdb.set_trace() +[EOF] +(Pdb) print x +6 +(Pdb) step +--Return-- +> (2)f()->None +-> g(x*2) +(Pdb) list + 1 def f(x): + 2 -> g(x*2) +[EOF] +(Pdb) print x +3 +(Pdb) step +--Return-- +> (1)?()->None +-> f(3) +(Pdb) cont +(0, 3) +>>> +\end{verbatim} + + \versionchanged[The ability to use \code{pdb.set_trace()} usefully + inside doctests was added]{2.4} +\end{itemize} + +Functions that convert doctests to Python code, and possibly run +the synthesized code under the debugger: + +\begin{funcdesc}{script_from_examples}{s} + Convert text with examples to a script. + + Argument \var{s} is a string containing doctest examples. The string + is converted to a Python script, where doctest examples in \var{s} + are converted to regular code, and everything else is converted to + Python comments. The generated script is returned as a string. + For example, given file \file{a.py} as above, + + \begin{verbatim} + >>> print doctest.script_from_examples(open("a.py").read()) + # """ + def f(x): + g(x*2) + def g(x): + print x+3 + import pdb; pdb.set_trace() + f(3) + # Expected: + ## 9 + ## """ + \end{verbatim} + + \versionadded{2.4} +\end{funcdesc} + +\begin{funcdesc}{testsource}{module, name} + Convert the doctest for an object to a script. + + Argument \var{module} is a module object, or dotted name of a module, + containing the object whose doctests are of interest. Argument + \var{name} is the name (within the module) of the object with the + doctests of interest. The result is a string, containing the + object's docstring converted to a Python script, as described for + \function{script_from_examples()} above. For example, if module + \file{a.py} contains a top-level function \function{f()}, then + + \begin{verbatim} + import a, doctest + print doctest.testsource(a, "a.f") + \end{verbatim} + + prints a script version of function \function{f()}'s docstring, + with doctests converted to code, and the rest placed in comments. + + \versionadded{2.3} +\end{funcdesc} + +\begin{funcdesc}{debug}{module, name\optional{, pm}} + Debug the doctests for an object. + + The \var{module} and \var{name} arguments are the same as for function + \function{testsource()} above. The synthesized Python script for the + named object's docstring is written to a temporary file, and then that + file is run under the control of the Python debugger, \refmodule{pdb}. + + A shallow copy of \code{\var{module}.__dict__} is used for both local + and global execution context. + + Optional argument \var{pm} controls whether post-mortem debugging is + used. If \var{pm} has a true value, the script file is run directly, + and the debugger gets involved only if the script terminates via raising + an unhandled exception. If it does, then post-mortem debugging is + invoked, via \code{pdb.post_mortem()}, passing the traceback object + from the unhandled exception. If \var{pm} is not specified, or is false, + the script is run under the debugger from the start, via passing an + appropriate \function{execfile()} call to \code{pdb.run()}. - The doctest examples are extracted (see function \function{testsource()}), - and written to a temporary file. The Python debugger, \refmodule{pdb}, - is then invoked on that file. \versionadded{2.3} + + \versionchanged[The \var{pm} argument was added]{2.4} +\end{funcdesc} + +\begin{funcdesc}{debug_src}{src\optional{, pm}\optional{, globs}} + Debug the doctests in a string. + + This is like function \function{debug()} above, except that + a string containing doctest examples is specified directly, via + the \var{src} argument. + + Optional argument \var{pm} has the same meaning as in function + \function{debug()} above. + + Optional argument \var{globs} gives a dictionary to use as both + local and global execution context. If not specified, or \code{None}, + an empty dictionary is used. If specified, a shallow copy of the + dictionary is used. + + \versionadded{2.4} \end{funcdesc} +The \class{DebugRunner} class, and the special exceptions it may raise, +are of most interest to testing framework authors, and will only be +sketched here. See the source code, and especially \class{DebugRunner}'s +docstring (which is a doctest!) for more details: + \begin{classdesc}{DebugRunner}{\optional{checker}\optional{, verbose}\optional{, optionflags}} @@ -1591,6 +1731,9 @@ section~\ref{doctest-advanced-api}. \end{classdesc} +There are two exceptions that may be raised by \class{DebugRunner} +instances: + \begin{excclassdesc}{DocTestFailure}{test, example, got} An exception thrown by \class{DocTestRunner} to signal that a doctest example's actual output did not match its expected output. @@ -1608,20 +1751,7 @@ The example's actual output. \end{memberdesc} -\begin{funcdesc}{testsource}{module, name} - Extract the doctest examples from a docstring. - - Provide the \var{module} (or dotted name of the module) containing the - tests to be extracted and the \var{name} (within the module) of the object - with the docstring containing the tests to be extracted. - - The doctest examples are returned as a string containing Python - code. The expected output blocks in the examples are converted - to Python comments. - \versionadded{2.3} -\end{funcdesc} - -\begin{excclassdesc}{UnexpectedException}{test, example, got} +\begin{excclassdesc}{UnexpectedException}{test, example, exc_info} An exception thrown by \class{DocTestRunner} to signal that a doctest example raised an unexpected exception. The constructor arguments are used to initialize the member variables of the same From tim_one at users.sourceforge.net Sun Sep 26 07:13:21 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 07:13:24 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1144,1.1145 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1694/misc Modified Files: NEWS Log Message: Updated doctest doc news. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1144 retrieving revision 1.1145 diff -u -d -r1.1144 -r1.1145 --- NEWS 24 Sep 2004 03:40:57 -0000 1.1144 +++ NEWS 26 Sep 2004 05:13:18 -0000 1.1145 @@ -67,12 +67,15 @@ ``codecs.StreamReader.readlines()`` have a new argument ``keepends``. Trailing "\n"s will be stripped from the lines if ``keepends`` is false. +- The documentation for doctest is greatly expanded, and now covers all + the new public features (of which there are many). + - ``doctest.master`` was put back in, and ``doctest.testmod()`` once again updates it. This isn't good, because every ``testmod()`` call contributes to bloating the "hidden" state of ``doctest.master``, but some old code apparently relies on it. For now, all we can do is encourage people to stitch doctests together via doctest's unittest - integration features instead. It would help if those were documented. + integration features instead. - httplib now handles ipv6 address/port pairs. From loewis at users.sourceforge.net Sun Sep 26 19:22:25 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun Sep 26 19:22:29 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS, 1.831.4.151, 1.831.4.152 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7630/Misc Modified Files: Tag: release23-maint NEWS Log Message: Replace -soname with -h for Solaris compatibility. Fixes #1034496. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.831.4.151 retrieving revision 1.831.4.152 diff -u -d -r1.831.4.151 -r1.831.4.152 --- NEWS 18 Sep 2004 16:04:21 -0000 1.831.4.151 +++ NEWS 26 Sep 2004 17:22:11 -0000 1.831.4.152 @@ -123,6 +123,8 @@ Build ----- +- Bug #1034496: Use -h instead of -soname for Solaris compatibility. + - Patch #973204: Use -rpath instead of -R for runtime_library_dirs on Irix and True64. From loewis at users.sourceforge.net Sun Sep 26 19:22:44 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun Sep 26 19:22:47 2004 Subject: [Python-checkins] python/dist/src Makefile.pre.in, 1.136.6.3, 1.136.6.4 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7630 Modified Files: Tag: release23-maint Makefile.pre.in Log Message: Replace -soname with -h for Solaris compatibility. Fixes #1034496. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.136.6.3 retrieving revision 1.136.6.4 diff -u -d -r1.136.6.3 -r1.136.6.4 --- Makefile.pre.in 18 Nov 2003 19:54:00 -0000 1.136.6.3 +++ Makefile.pre.in 26 Sep 2004 17:22:10 -0000 1.136.6.4 @@ -345,7 +345,7 @@ libpython$(VERSION).so: $(LIBRARY_OBJS) if test $(INSTSONAME) != $(LDLIBRARY); then \ - $(LDSHARED) -Wl,-soname=$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ + $(LDSHARED) -Wl,-h=$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ $(LN) -f $(INSTSONAME) $@; \ else\ $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ From loewis at users.sourceforge.net Sun Sep 26 19:26:19 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun Sep 26 19:26:22 2004 Subject: [Python-checkins] python/dist/src Makefile.pre.in, 1.136.6.4, 1.136.6.5 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8743 Modified Files: Tag: release23-maint Makefile.pre.in Log Message: Remove bogus = from -h option. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.136.6.4 retrieving revision 1.136.6.5 diff -u -d -r1.136.6.4 -r1.136.6.5 --- Makefile.pre.in 26 Sep 2004 17:22:10 -0000 1.136.6.4 +++ Makefile.pre.in 26 Sep 2004 17:26:16 -0000 1.136.6.5 @@ -345,7 +345,7 @@ libpython$(VERSION).so: $(LIBRARY_OBJS) if test $(INSTSONAME) != $(LDLIBRARY); then \ - $(LDSHARED) -Wl,-h=$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ + $(LDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ $(LN) -f $(INSTSONAME) $@; \ else\ $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ From loewis at users.sourceforge.net Sun Sep 26 19:26:58 2004 From: loewis at users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun Sep 26 19:27:01 2004 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.147,1.148 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8928 Modified Files: Makefile.pre.in Log Message: Replace -soname with -h for Solaris compatibility. Fixes #1034496. Backported to 2.3. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.147 retrieving revision 1.148 diff -u -d -r1.147 -r1.148 --- Makefile.pre.in 16 Jul 2004 08:42:35 -0000 1.147 +++ Makefile.pre.in 26 Sep 2004 17:26:55 -0000 1.148 @@ -351,7 +351,7 @@ libpython$(VERSION).so: $(LIBRARY_OBJS) if test $(INSTSONAME) != $(LDLIBRARY); then \ - $(LDSHARED) -Wl,-soname=$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ + $(LDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ $(LN) -f $(INSTSONAME) $@; \ else\ $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ From rhettinger at users.sourceforge.net Sun Sep 26 20:56:47 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 26 20:56:51 2004 Subject: [Python-checkins] python/dist/src/Lib string.py,1.84,1.85 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3573 Modified Files: string.py Log Message: Make the regex pattern easier to read, understand, and modify by factoring out the common prefix (the delimiter). Index: string.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/string.py,v retrieving revision 1.84 retrieving revision 1.85 diff -u -d -r1.84 -r1.85 --- string.py 18 Sep 2004 00:06:34 -0000 1.84 +++ string.py 26 Sep 2004 18:56:44 -0000 1.85 @@ -101,10 +101,12 @@ class _TemplateMetaclass(type): pattern = r""" - (?P%(delim)s{2}) | # Escape sequence of two delimiters - %(delim)s(?P%(id)s) | # delimiter and a Python identifier - %(delim)s{(?P%(id)s)} | # delimiter and a braced identifier - (?P%(delim)s) # Other ill-formed delimiter exprs + %(delim)s(?: + (?P%(delim)s) | # Escape sequence of two delimiters + (?P%(id)s) | # delimiter and a Python identifier + {(?P%(id)s)} | # delimiter and a braced identifier + (?P) # Other ill-formed delimiter exprs + ) """ def __init__(cls, name, bases, dct): From rhettinger at users.sourceforge.net Sun Sep 26 21:24:26 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 26 21:24:31 2004 Subject: [Python-checkins] python/dist/src/Objects listobject.c,2.223,2.224 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9824/objects Modified Files: listobject.c Log Message: Checkin Tim's fix to an error discussed on python-dev. Also, add a testcase. Formerly, the list_extend() code used several local variables to remember its state across iterations. Since an iteration could call arbitrary Python code, it was possible for the list state to be changed. The new code uses dynamic structure references instead of C locals. So, they are always up-to-date. After list_resize() is called, its size has been updated but the new cells are filled with NULLs. These needed to be filled before arbitrary iteration code was called; otherwise, that code could attempt to modify a list that was in a semi-invalid state. The solution was to change the ob->size field back to a value reflecting the actual number of valid cells. Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.223 retrieving revision 2.224 diff -u -d -r2.223 -r2.224 --- listobject.c 12 Sep 2004 19:53:07 -0000 2.223 +++ listobject.c 26 Sep 2004 19:24:20 -0000 2.224 @@ -769,12 +769,20 @@ } m = self->ob_size; mn = m + n; - if (list_resize(self, mn) == -1) - goto error; - memset(&(self->ob_item[m]), 0, sizeof(*self->ob_item) * n); + if (mn >= m) { + /* Make room. */ + if (list_resize(self, mn) == -1) + goto error; + /* Make the list sane again. */ + self->ob_size = m; + } + /* Else m + n overflowed; on the chance that n lied, and there really + * is enough room, ignore it. If n was telling the truth, we'll + * eventually run out of memory during the loop. + */ /* Run iterator to exhaustion. */ - for (i = m; ; i++) { + for (;;) { PyObject *item = iternext(it); if (item == NULL) { if (PyErr_Occurred()) { @@ -785,8 +793,11 @@ } break; } - if (i < mn) - PyList_SET_ITEM(self, i, item); /* steals ref */ + if (self->ob_size < self->allocated) { + /* steals ref */ + PyList_SET_ITEM(self, self->ob_size, item); + ++self->ob_size; + } else { int status = app1(self, item); Py_DECREF(item); /* append creates a new ref */ @@ -796,10 +807,9 @@ } /* Cut back result list if initial guess was too large. */ - if (i < mn && self != NULL) { - if (list_ass_slice(self, i, mn, (PyObject *)NULL) != 0) - goto error; - } + if (self->ob_size < self->allocated) + list_resize(self, self->ob_size); /* shrinking can't fail */ + Py_DECREF(it); Py_RETURN_NONE; From rhettinger at users.sourceforge.net Sun Sep 26 21:24:27 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun Sep 26 21:24:32 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_builtin.py, 1.34, 1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9824/lib/test Modified Files: test_builtin.py Log Message: Checkin Tim's fix to an error discussed on python-dev. Also, add a testcase. Formerly, the list_extend() code used several local variables to remember its state across iterations. Since an iteration could call arbitrary Python code, it was possible for the list state to be changed. The new code uses dynamic structure references instead of C locals. So, they are always up-to-date. After list_resize() is called, its size has been updated but the new cells are filled with NULLs. These needed to be filled before arbitrary iteration code was called; otherwise, that code could attempt to modify a list that was in a semi-invalid state. The solution was to change the ob->size field back to a value reflecting the actual number of valid cells. Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- test_builtin.py 7 Aug 2004 19:20:05 -0000 1.34 +++ test_builtin.py 26 Sep 2004 19:24:19 -0000 1.35 @@ -712,6 +712,11 @@ # http://sources.redhat.com/ml/newlib/2002/msg00369.html self.assertRaises(MemoryError, list, xrange(sys.maxint // 2)) + # This code used to segfault in Py2.4a3 + x = [] + x.extend(-y for y in x) + self.assertEqual(x, []) + def test_long(self): self.assertEqual(long(314), 314L) self.assertEqual(long(3.14), 3L) From tim_one at users.sourceforge.net Sun Sep 26 22:45:07 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 22:45:13 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.56,1.57 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2067/Doc/lib Modified Files: libdoctest.tex Log Message: Docs for run_docstring_examples(). Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.56 retrieving revision 1.57 diff -u -d -r1.56 -r1.57 --- libdoctest.tex 26 Sep 2004 05:09:59 -0000 1.56 +++ libdoctest.tex 26 Sep 2004 20:45:04 -0000 1.57 @@ -944,6 +944,36 @@ and \var{exclude_empty} were added]{2.4} \end{funcdesc} +There's also a function to run the doctests associated with a single object. +This function is provided for backward compatibility. There are no plans +to deprecate it, but it's rarely useful: + +\begin{funcdesc}{run_docstring_examples}{f, globs\optional{, + verbose}\optional{, name}\optional{, + compileflags}\optional{, optionflags}} + + Test examples associated with object \var{f}; for example, \var{f} may + be a module, function, or class object. + + A shallow copy of dictionary argument \var{globs} is used for the + execution context. + + Optional argument \var{name} is used in failure messages, and defaults + to \code{"NoName"}. + + If optional argument \var{verbose} is true, output is generated even + if there are no failures. By default, output is generated only in case + of an example failure. + + Optional argument \var{compileflags} gives the set of flags that should + be used by the Python compiler when running the examples. By default, or + if \code{None}, flags are deduced corresponding to the set of future + features found in \var{globs}. + + Optional argument \var{optionflags} works as for function + \function{testfile()} above. +\end{funcdesc} + \subsection{Unittest API\label{doctest-unittest-api}} As your collection of doctest'ed modules grows, you'll want a way to run From tim_one at users.sourceforge.net Sun Sep 26 23:05:06 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 23:05:10 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.57,1.58 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6256/Doc/lib Modified Files: libdoctest.tex Log Message: Made most module references "clickable". Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.57 retrieving revision 1.58 diff -u -d -r1.57 -r1.58 --- libdoctest.tex 26 Sep 2004 20:45:04 -0000 1.57 +++ libdoctest.tex 26 Sep 2004 21:05:03 -0000 1.58 @@ -9,7 +9,7 @@ \modulesynopsis{A framework for verifying interactive Python examples.} -The \module{doctest} module searches for pieces of text that look like +The \refmodule{doctest} module searches for pieces of text that look like interactive Python sessions, and then executes those sessions to verify that they work exactly as shown. There are several common ways to use doctest: @@ -98,7 +98,7 @@ \end{verbatim} If you run \file{example.py} directly from the command line, -\module{doctest} works its magic: +\refmodule{doctest} works its magic: \begin{verbatim} $ python example.py @@ -106,7 +106,7 @@ \end{verbatim} There's no output! That's normal, and it means all the examples -worked. Pass \programopt{-v} to the script, and \module{doctest} +worked. Pass \programopt{-v} to the script, and \refmodule{doctest} prints a detailed log of what it's trying, and prints a summary at the end: @@ -151,7 +151,7 @@ \end{verbatim} That's all you need to know to start making productive use of -\module{doctest}! Jump in. The following sections provide full +\refmodule{doctest}! Jump in. The following sections provide full details. Note that there are many examples of doctests in the standard Python test suite and libraries. Especially useful examples can be found in the standard test file \file{Lib/test/test_doctest.py}. @@ -171,7 +171,7 @@ _test() \end{verbatim} -\module{doctest} then examines docstrings in module \module{M}. +\refmodule{doctest} then examines docstrings in module \module{M}. Running the module as a script causes the examples in the docstrings to get executed and verified: @@ -392,7 +392,7 @@ \subsubsection{What's the Execution Context?\label{doctest-execution-context}} -By default, each time \module{doctest} finds a docstring to test, it +By default, each time \refmodule{doctest} finds a docstring to test, it uses a \emph{shallow copy} of \module{M}'s globals, so that running tests doesn't change the module's real globals, and so that one test in \module{M} can't leave behind crumbs that accidentally allow another test @@ -711,7 +711,7 @@ were added]{2.4} There's also a way to register new option flag names, although this -isn't useful unless you intend to extend \module{doctest} internals +isn't useful unless you intend to extend \refmodule{doctest} internals via subclassing: \begin{funcdesc}{register_optionflag}{name} @@ -731,7 +731,7 @@ \subsubsection{Warnings\label{doctest-warnings}} -\module{doctest} is serious about requiring exact matches in expected +\refmodule{doctest} is serious about requiring exact matches in expected output. If even a single character doesn't match, the test fails. This will probably surprise you a few times, as you learn exactly what Python does and doesn't guarantee about output. For example, when printing a @@ -977,16 +977,16 @@ \subsection{Unittest API\label{doctest-unittest-api}} As your collection of doctest'ed modules grows, you'll want a way to run -all their doctests systematically. Prior to Python 2.4, \module{doctest} +all their doctests systematically. Prior to Python 2.4, \refmodule{doctest} had a barely documented \class{Tester} class that supplied a rudimentary way to combine doctests from multiple modules. \class{Tester} was feeble, and in practice most serious Python testing frameworks build on the -\module{unittest} module, which supplies many flexible ways to combine -tests from multiple sources. So, in Python 2.4, \module{doctest}'s -\class{Tester} class is deprecated, and \module{doctest} provides two -functions that can be used to create \module{unittest} test suites from +\refmodule{unittest} module, which supplies many flexible ways to combine +tests from multiple sources. So, in Python 2.4, \refmodule{doctest}'s +\class{Tester} class is deprecated, and \refmodule{doctest} provides two +functions that can be used to create \refmodule{unittest} test suites from modules and text files containing doctests. These test suites can then be -run using \module{unittest} test runners: +run using \refmodule{unittest} test runners: \begin{verbatim} import unittest @@ -1000,19 +1000,18 @@ runner.run(suite) \end{verbatim} -There are two main functions for creating \class{unittest.TestSuite} +There are two main functions for creating \class{\refmodule{unittest}.TestSuite} instances from text files and modules with doctests: \begin{funcdesc}{DocFileSuite}{*paths, **kw} Convert doctest tests from one or more text files to a \class{\refmodule{unittest}.TestSuite}. - The returned \class{unittest.TestSuite} is to be run by the unittest - framework and runs the interactive examples in each file. If an - example in any file fails, then the synthesized unit test fails, and - a \exception{failureException} exception is raised showing the - name of the file containing the test and a (sometimes approximate) - line number. + The returned \class{\refmodule{unittest}.TestSuite} is to be run by the + unittest framework and runs the interactive examples in each file. If an + example in any file fails, then the synthesized unit test fails, and a + \exception{failureException} exception is raised showing the name of the + file containing the test and a (sometimes approximate) line number. Pass one or more paths (as strings) to text files to be examined. @@ -1076,9 +1075,9 @@ Convert doctest tests for a module to a \class{\refmodule{unittest}.TestSuite}. - The returned \class{unittest.TestSuite} is to be run by the unittest - framework and runs each doctest in the module. If any of the doctests - fail, then the synthesized unit test fails, and a + The returned \class{\refmodule{unittest}.TestSuite} is to be run by the + unittest framework and runs each doctest in the module. If any of the + doctests fail, then the synthesized unit test fails, and a \exception{failureException} exception is raised showing the name of the file containing the test and a (sometimes approximate) line number. @@ -1111,50 +1110,50 @@ \end{funcdesc} Under the covers, \function{DocTestSuite()} creates a -\class{unittest.TestSuite} out of \class{doctest.DocTestCase} instances, -and \class{DocTestCase} is a subclass of \class{unittest.TestCase}. -\class{DocTestCase} isn't documented here (it's an internal detail), but -studying its code can answer questions about the exact details of -\module{unittest} integration. +\class{\refmodule{unittest}.TestSuite} out of \class{doctest.DocTestCase} +instances, and \class{DocTestCase} is a subclass of +\class{\refmodule{unittest}.TestCase}. \class{DocTestCase} isn't documented +here (it's an internal detail), but studying its code can answer questions +about the exact details of \refmodule{unittest} integration. -Similarly, \function{DocFileSuite()} creates a \class{unittest.TestSuite} -out of \class{doctest.DocFileCase} instances, and \class{DocFileCase} -is a subclass of \class{DocTestCase}. +Similarly, \function{DocFileSuite()} creates a +\class{\refmodule{unittest}.TestSuite} out of \class{doctest.DocFileCase} +instances, and \class{DocFileCase} is a subclass of \class{DocTestCase}. -So both ways of creating a \class{unittest.TestSuite} run instances of -\class{DocTestCase}. This is important for a subtle reason: when you -run \module{doctest} functions yourself, you can control the -\module{doctest} options in use directly, by passing option flags to -\module{doctest} functions. However, if you're writing a \module{unittest} -framework, \module{unittest} ultimately controls when and how tests -get run. The framework author typically wants to control \module{doctest} -reporting options (perhaps, e.g., specified by command line options), -but there's no way to pass options through \module{unittest} to -\module{doctest} test runners. +So both ways of creating a \class{\refmodule{unittest}.TestSuite} run +instances of \class{DocTestCase}. This is important for a subtle reason: +when you run \refmodule{doctest} functions yourself, you can control the +\refmodule{doctest} options in use directly, by passing option flags to +\refmodule{doctest} functions. However, if you're writing a +\refmodule{unittest} framework, \refmodule{unittest} ultimately controls +when and how tests get run. The framework author typically wants to +control \refmodule{doctest} reporting options (perhaps, e.g., specified by +command line options), but there's no way to pass options through +\refmodule{unittest} to \refmodule{doctest} test runners. -For this reason, \module{doctest} also supports a notion of -\module{doctest} reporting flags specific to \module{unittest} support, -via this function: +For this reason, \refmodule{doctest} also supports a notion of +\refmodule{doctest} reporting flags specific to \refmodule{unittest} +support, via this function: \begin{funcdesc}{set_unittest_reportflags}{flags} - Set the \module{doctest} reporting flags to use. + Set the \refmodule{doctest} reporting flags to use. Argument \var{flags} or's together option flags. See section~\ref{doctest-options}. Only "reporting flags" can be used. - This is a module-global setting, and affects all future doctests run - by module \module{unittest}: the \method{runTest()} method of - \class{DocTestCase} looks at the option flags specified for the test - case when the \class{DocTestCase} instance was constructed. If no - reporting flags were specified (which is the typical and expected case), - \module{doctest}'s \module{unittest} reporting flags are or'ed into the - option flags, and the option flags so augmented are passed to the + This is a module-global setting, and affects all future doctests run by + module \refmodule{unittest}: the \method{runTest()} method of + \class{DocTestCase} looks at the option flags specified for the test case + when the \class{DocTestCase} instance was constructed. If no reporting + flags were specified (which is the typical and expected case), + \refmodule{doctest}'s \refmodule{unittest} reporting flags are or'ed into + the option flags, and the option flags so augmented are passed to the \class{DocTestRunner} instance created to run the doctest. If any - reporting flags were specified when the \class{DocTestCase} instance - was constructed, \module{doctest}'s \module{unittest} reporting flags + reporting flags were specified when the \class{DocTestCase} instance was + constructed, \refmodule{doctest}'s \refmodule{unittest} reporting flags are ignored. - The value of the \module{unittest} reporting flags in effect before the + The value of the \refmodule{unittest} reporting flags in effect before the function was called is returned by the function. \versionadded{2.4} @@ -1587,11 +1586,11 @@ failing example, containing information about that example. This information can be used to perform post-mortem debugging on the example. -\item The \module{unittest} cases generated by \function{DocTestSuite()} +\item The \refmodule{unittest} cases generated by \function{DocTestSuite()} support the \method{debug()} method defined by - \class{unittest.TestCase}. -\item You can add a call to \function{pdb.set_trace()} in a doctest - example, and you'll drop into the Python debugger when that + \class{\refmodule{unittest}.TestCase}. +\item You can add a call to \function{\refmodule{pdb}.set_trace()} in a + doctest example, and you'll drop into the Python debugger when that line is executed. Then you can inspect current values of variables, and so on. For example, suppose \file{a.py} contains just this module docstring: @@ -1642,8 +1641,8 @@ >>> \end{verbatim} - \versionchanged[The ability to use \code{pdb.set_trace()} usefully - inside doctests was added]{2.4} + \versionchanged[The ability to use \code{\refmodule{pdb}.set_trace()} + usefully inside doctests was added]{2.4} \end{itemize} Functions that convert doctests to Python code, and possibly run @@ -1709,13 +1708,13 @@ and global execution context. Optional argument \var{pm} controls whether post-mortem debugging is - used. If \var{pm} has a true value, the script file is run directly, - and the debugger gets involved only if the script terminates via raising - an unhandled exception. If it does, then post-mortem debugging is - invoked, via \code{pdb.post_mortem()}, passing the traceback object + used. If \var{pm} has a true value, the script file is run directly, and + the debugger gets involved only if the script terminates via raising an + unhandled exception. If it does, then post-mortem debugging is invoked, + via \code{\refmodule{pdb}.post_mortem()}, passing the traceback object from the unhandled exception. If \var{pm} is not specified, or is false, the script is run under the debugger from the start, via passing an - appropriate \function{execfile()} call to \code{pdb.run()}. + appropriate \function{execfile()} call to \code{\refmodule{pdb}.run()}. \versionadded{2.3} @@ -1801,7 +1800,7 @@ \subsection{Soapbox\label{doctest-soapbox}} -As mentioned in the introduction, \module{doctest} has grown to have +As mentioned in the introduction, \refmodule{doctest} has grown to have three primary uses: \begin{enumerate} From tim_one at users.sourceforge.net Sun Sep 26 23:51:28 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun Sep 26 23:51:30 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17602/Doc/lib Modified Files: libdoctest.tex Log Message: Give a saner example for script_from_examples(); also mention an intended but not entirely obvious use case. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.58 retrieving revision 1.59 diff -u -d -r1.58 -r1.59 --- libdoctest.tex 26 Sep 2004 21:05:03 -0000 1.58 +++ libdoctest.tex 26 Sep 2004 21:51:25 -0000 1.59 @@ -1655,22 +1655,36 @@ is converted to a Python script, where doctest examples in \var{s} are converted to regular code, and everything else is converted to Python comments. The generated script is returned as a string. - For example, given file \file{a.py} as above, + For example, \begin{verbatim} - >>> print doctest.script_from_examples(open("a.py").read()) - # """ - def f(x): - g(x*2) - def g(x): - print x+3 - import pdb; pdb.set_trace() - f(3) + import doctest + print doctest.script_from_examples(r""" + Set x and y to 1 and 2. + >>> x, y = 1, 2 + + Print their sum: + >>> print x+y + 3 + """) + \end{verbatim} + + displays: + + \begin{verbatim} + # Set x and y to 1 and 2. + x, y = 1, 2 + # + # Print their sum: + print x+y # Expected: - ## 9 - ## """ + ## 3 \end{verbatim} + This function is used internally by other functions (see below), but + can also be useful when you want to transform an interactive Python + session into a Python script. + \versionadded{2.4} \end{funcdesc} From edloper at users.sourceforge.net Mon Sep 27 05:30:47 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Mon Sep 27 05:30:50 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26868/Doc/lib Modified Files: libdoctest.tex Log Message: - Fixed typo in multi-line exception example - Fixed indentation for a verbatim block Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.59 retrieving revision 1.60 diff -u -d -r1.59 -r1.60 --- libdoctest.tex 26 Sep 2004 21:51:25 -0000 1.59 +++ libdoctest.tex 27 Sep 2004 03:30:44 -0000 1.60 @@ -443,7 +443,7 @@ exception has a multi-line detail: \begin{verbatim} ->>> raise ValueError('multi\n line\ndetail') +>>> raise ValueError('multi\n line\ndetail') Traceback (most recent call last): File "", line 1, in ? ValueError: multi @@ -460,7 +460,7 @@ is probably better as: \begin{verbatim} ->>> raise ValueError('multi\n line\ndetail') +>>> raise ValueError('multi\n line\ndetail') Traceback (most recent call last): ... ValueError: multi @@ -1699,10 +1699,10 @@ \function{script_from_examples()} above. For example, if module \file{a.py} contains a top-level function \function{f()}, then - \begin{verbatim} - import a, doctest - print doctest.testsource(a, "a.f") - \end{verbatim} +\begin{verbatim} +import a, doctest +print doctest.testsource(a, "a.f") +\end{verbatim} prints a script version of function \function{f()}'s docstring, with doctests converted to code, and the rest placed in comments. From edloper at users.sourceforge.net Mon Sep 27 05:43:01 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Mon Sep 27 05:43:04 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.113,1.114 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30397/Lib Modified Files: doctest.py Log Message: - Added a "parser" option to testfile() and DocFileTest(). Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.113 retrieving revision 1.114 diff -u -d -r1.113 -r1.114 --- doctest.py 26 Sep 2004 03:50:06 -0000 1.113 +++ doctest.py 27 Sep 2004 03:42:58 -0000 1.114 @@ -1852,7 +1852,7 @@ def testfile(filename, module_relative=True, name=None, package=None, globs=None, verbose=None, report=True, optionflags=0, - extraglobs=None, raise_on_error=False): + extraglobs=None, raise_on_error=False, parser=DocTestParser()): """ Test examples in the given file. Return (#failures, #tests). @@ -1914,6 +1914,9 @@ first unexpected exception or failure. This allows failures to be post-mortem debugged. + Optional keyword arg "parser" specifies a DocTestParser (or + subclass) that should be used to extract tests from the files. + Advanced tomfoolery: testmod runs methods of a local instance of class doctest.Tester, then merges the results into (or creates) global Tester instance doctest.master. Methods of doctest.master @@ -1952,7 +1955,7 @@ # Read the file, convert it to a test, and run it. s = open(filename).read() - test = DocTestParser().get_doctest(s, globs, name, filename, 0) + test = parser.get_doctest(s, globs, name, filename, 0) runner.run(test) if report: @@ -2321,7 +2324,7 @@ ) def DocFileTest(path, module_relative=True, package=None, - globs=None, **options): + globs=None, parser=DocTestParser(), **options): if globs is None: globs = {} @@ -2339,7 +2342,7 @@ doc = open(path).read() # Convert it to a test, and wrap it in a DocFileCase. - test = DocTestParser().get_doctest(doc, globs, name, path, 0) + test = parser.get_doctest(doc, globs, name, path, 0) return DocFileCase(test, **options) def DocFileSuite(*paths, **kw): @@ -2389,7 +2392,11 @@ A dictionary containing initial global variables for the tests. optionflags - A set of doctest option flags expressed as an integer. + A set of doctest option flags expressed as an integer. + + parser + A DocTestParser (or subclass) that should be used to extract + tests from the files. """ suite = unittest.TestSuite() From edloper at users.sourceforge.net Mon Sep 27 06:08:23 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Mon Sep 27 06:08:25 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2621/Doc/lib Modified Files: libdoctest.tex Log Message: - Added a "parser" option to testfile() and DocFileTest(). Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.60 retrieving revision 1.61 diff -u -d -r1.60 -r1.61 --- libdoctest.tex 27 Sep 2004 03:30:44 -0000 1.60 +++ libdoctest.tex 27 Sep 2004 04:08:20 -0000 1.61 @@ -817,7 +817,8 @@ name}\optional{, package}\optional{, globs}\optional{, verbose}\optional{, report}\optional{, optionflags}\optional{, - extraglobs}\optional{, raise_on_error}} + extraglobs}\optional{, raise_on_error}\optional{, + parser}} All arguments except \var{filename} are optional, and should be specified in keyword form. @@ -886,6 +887,10 @@ in an example. This allows failures to be post-mortem debugged. Default behavior is to continue running examples. + Optional argument \var{parser} specifies a \class{DocTestParser} (or + subclass) that should be used to extract tests from the files. It + defaults to a normal parser (i.e., \code{\class{DocTestParser}()}). + \versionadded{2.4} \end{funcdesc} @@ -1065,6 +1070,10 @@ See function \function{set_unittest_reportflags()} below for a better way to set reporting options. + Optional argument \var{parser} specifies a \class{DocTestParser} (or + subclass) that should be used to extract tests from the files. It + defaults to a normal parser (i.e., \code{\class{DocTestParser}()}). + \versionadded{2.4} \end{funcdesc} From rhettinger at users.sourceforge.net Mon Sep 27 16:23:43 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 27 16:23:46 2004 Subject: [Python-checkins] python/dist/src/Lib decimal.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15229 Modified Files: decimal.py Log Message: Use floor division operator. Index: decimal.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/decimal.py,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- decimal.py 19 Sep 2004 01:54:09 -0000 1.24 +++ decimal.py 27 Sep 2004 14:23:40 -0000 1.25 @@ -1924,7 +1924,7 @@ tmp = Decimal(self) - expadd = tmp._exp / 2 + expadd = tmp._exp // 2 if tmp._exp & 1: tmp._int += (0,) tmp._exp = 0 @@ -1939,12 +1939,12 @@ ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) ) ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)), context=context), context=context) - ans._exp -= 1 + tmp.adjusted()/2 + ans._exp -= 1 + tmp.adjusted() // 2 else: ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) ) ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)), context=context), context=context) - ans._exp -= 1 + tmp.adjusted()/2 + ans._exp -= 1 + tmp.adjusted() // 2 #ans is now a linear approximation. From rhettinger at users.sourceforge.net Mon Sep 27 17:29:06 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 27 17:29:09 2004 Subject: [Python-checkins] python/dist/src/Lib imaplib.py, 1.72, 1.73 random.py, 1.68, 1.69 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29983 Modified Files: imaplib.py random.py Log Message: Use floor division operator. Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.72 retrieving revision 1.73 diff -u -d -r1.72 -r1.73 --- imaplib.py 10 Aug 2004 01:24:54 -0000 1.72 +++ imaplib.py 27 Sep 2004 15:29:02 -0000 1.73 @@ -1361,7 +1361,7 @@ zone = -time.altzone else: zone = -time.timezone - return '"' + dt + " %+03d%02d" % divmod(zone/60, 60) + '"' + return '"' + dt + " %+03d%02d" % divmod(zone//60, 60) + '"' Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.68 retrieving revision 1.69 diff -u -d -r1.68 -r1.69 --- random.py 13 Sep 2004 22:23:20 -0000 1.68 +++ random.py 27 Sep 2004 15:29:03 -0000 1.69 @@ -197,9 +197,9 @@ if istep != step: raise ValueError, "non-integer step for randrange()" if istep > 0: - n = (width + istep - 1) / istep + n = (width + istep - 1) // istep elif istep < 0: - n = (width + istep + 1) / istep + n = (width + istep + 1) // istep else: raise ValueError, "zero step for randrange()" From rhettinger at users.sourceforge.net Mon Sep 27 17:29:11 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon Sep 27 17:29:14 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_deque.py, 1.14, 1.15 test_enumerate.py, 1.12, 1.13 test_itertools.py, 1.32, 1.33 test_random.py, 1.21, 1.22 test_set.py, 1.13, 1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29983/test Modified Files: test_deque.py test_enumerate.py test_itertools.py test_random.py test_set.py Log Message: Use floor division operator. Index: test_deque.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_deque.py,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- test_deque.py 26 Aug 2004 04:29:47 -0000 1.14 +++ test_deque.py 27 Sep 2004 15:29:04 -0000 1.15 @@ -385,7 +385,7 @@ def __iter__(self): return self def next(self): - 3/0 + 3 // 0 class S: 'Test immediate stop' Index: test_enumerate.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_enumerate.py,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- test_enumerate.py 10 Mar 2004 10:10:42 -0000 1.12 +++ test_enumerate.py 27 Sep 2004 15:29:04 -0000 1.13 @@ -50,7 +50,7 @@ def __iter__(self): return self def next(self): - 3/0 + 3 // 0 class N: 'Iterator missing next()' Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_itertools.py,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- test_itertools.py 23 Sep 2004 07:27:39 -0000 1.32 +++ test_itertools.py 27 Sep 2004 15:29:04 -0000 1.33 @@ -476,7 +476,7 @@ def __iter__(self): return self def next(self): - 3/0 + 3 // 0 class S: 'Test immediate stop' Index: test_random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_random.py,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- test_random.py 13 Sep 2004 22:23:20 -0000 1.21 +++ test_random.py 27 Sep 2004 15:29:05 -0000 1.22 @@ -79,7 +79,7 @@ def factorial(n): return reduce(int.__mul__, xrange(1, n), 1) for k in xrange(n): - expected = factorial(n) / factorial(n-k) + expected = factorial(n) // factorial(n-k) perms = {} for i in xrange(trials): perms[tuple(self.gen.sample(pop, k))] = None Index: test_set.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_set.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- test_set.py 9 Jul 2004 04:51:24 -0000 1.13 +++ test_set.py 27 Sep 2004 15:29:05 -0000 1.14 @@ -1241,7 +1241,7 @@ def __iter__(self): return self def next(self): - 3/0 + 3 // 0 class S: 'Test immediate stop' From arigo at users.sourceforge.net Mon Sep 27 19:49:04 2004 From: arigo at users.sourceforge.net (arigo@users.sourceforge.net) Date: Mon Sep 27 19:49:07 2004 Subject: [Python-checkins] python/dist/src/Lib asynchat.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1673 Modified Files: asynchat.py Log Message: Trivial bug fix: deque == [] is not a good way to check if a deque is empty. Index: asynchat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asynchat.py,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- asynchat.py 1 Mar 2004 23:16:22 -0000 1.24 +++ asynchat.py 27 Sep 2004 17:49:00 -0000 1.25 @@ -259,7 +259,7 @@ return len(self.list) def is_empty (self): - return self.list == [] + return not self.list def first (self): return self.list[0] From arigo at users.sourceforge.net Mon Sep 27 21:27:53 2004 From: arigo at users.sourceforge.net (arigo@users.sourceforge.net) Date: Mon Sep 27 21:27:56 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_struct.py, 1.18, 1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22138/Lib/test Modified Files: test_struct.py Log Message: Patch #1011240: SystemError generated by struct.pack('P', 'foo'). Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- test_struct.py 12 Feb 2004 17:35:11 -0000 1.18 +++ test_struct.py 27 Sep 2004 19:27:50 -0000 1.19 @@ -54,6 +54,7 @@ simple_err(struct.pack, 'iii', 3) simple_err(struct.pack, 'i', 3, 3, 3) simple_err(struct.pack, 'i', 'foo') +simple_err(struct.pack, 'P', 'foo') simple_err(struct.unpack, 'd', 'flap') s = struct.pack('ii', 1, 2) simple_err(struct.unpack, 'iii', s) From arigo at users.sourceforge.net Mon Sep 27 21:27:53 2004 From: arigo at users.sourceforge.net (arigo@users.sourceforge.net) Date: Mon Sep 27 21:27:57 2004 Subject: [Python-checkins] python/dist/src/Modules structmodule.c,2.61,2.62 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22138/Modules Modified Files: structmodule.c Log Message: Patch #1011240: SystemError generated by struct.pack('P', 'foo'). Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.61 retrieving revision 2.62 diff -u -d -r2.61 -r2.62 --- structmodule.c 19 Nov 2003 22:52:23 -0000 2.61 +++ structmodule.c 27 Sep 2004 19:27:51 -0000 2.62 @@ -518,14 +518,16 @@ static int np_void_p(char *p, PyObject *v, const formatdef *f) { - void *x = PyLong_AsVoidPtr(v); - if (x == NULL && PyErr_Occurred()) { - /* ### hrm. PyLong_AsVoidPtr raises SystemError */ - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_SetString(StructError, - "required argument is not an integer"); + void *x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsVoidPtr(v); + Py_DECREF(v); + if (x == NULL && PyErr_Occurred()) return -1; - } memcpy(p, (char *)&x, sizeof x); return 0; } From arigo at users.sourceforge.net Mon Sep 27 21:54:35 2004 From: arigo at users.sourceforge.net (arigo@users.sourceforge.net) Date: Mon Sep 27 21:54:39 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.141,1.142 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27542/Doc/lib Modified Files: libos.tex Log Message: Patch #1009075, bug #952953: allow execve with empty 2nd argument Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.141 retrieving revision 1.142 diff -u -d -r1.141 -r1.142 --- libos.tex 29 Aug 2004 15:46:20 -0000 1.141 +++ libos.tex 27 Sep 2004 19:54:32 -0000 1.142 @@ -1226,8 +1226,8 @@ \function{execl*()} functions. The \character{v} variants are good when the number of parameters is variable, with the arguments being passed in a list or tuple as the \var{args} parameter. In either -case, the arguments to the child process must start with the name of -the command being run. +case, the arguments to the child process should start with the name of +the command being run, but this is not enforced. The variants which include a \character{p} near the end (\function{execlp()}, \function{execlpe()}, \function{execvp()}, From arigo at users.sourceforge.net Mon Sep 27 21:54:36 2004 From: arigo at users.sourceforge.net (arigo@users.sourceforge.net) Date: Mon Sep 27 21:54:40 2004 Subject: [Python-checkins] python/dist/src/Modules posixmodule.c, 2.326, 2.327 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27542/Modules Modified Files: posixmodule.c Log Message: Patch #1009075, bug #952953: allow execve with empty 2nd argument Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.326 retrieving revision 2.327 diff -u -d -r2.326 -r2.327 --- posixmodule.c 30 Aug 2004 17:36:46 -0000 2.326 +++ posixmodule.c 27 Sep 2004 19:54:33 -0000 2.327 @@ -2171,12 +2171,6 @@ return NULL; } - if (argc == 0) { - PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); - PyMem_Free(path); - return NULL; - } - argvlist = PyMem_NEW(char *, argc+1); if (argvlist == NULL) { PyMem_Free(path); @@ -2253,12 +2247,6 @@ goto fail_0; } - if (argc == 0) { - PyErr_SetString(PyExc_ValueError, - "execve() arg 2 must not be empty"); - goto fail_0; - } - argvlist = PyMem_NEW(char *, argc+1); if (argvlist == NULL) { PyErr_NoMemory(); From rhettinger at users.sourceforge.net Tue Sep 28 00:48:43 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 00:48:47 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_bisect.py, 1.11, 1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31537 Modified Files: test_bisect.py Log Message: Beef-up tests for greater coverage and refcount checking. Index: test_bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bisect.py,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- test_bisect.py 29 Jan 2004 06:37:49 -0000 1.11 +++ test_bisect.py 27 Sep 2004 22:48:40 -0000 1.12 @@ -151,6 +151,47 @@ #============================================================================== + +class LenOnly: + "Dummy sequence class defining __len__ but not __getitem__." + def __len__(self): + return 10 + +class GetOnly: + "Dummy sequence class defining __getitem__ but not __len__." + def __getitem__(self, ndx): + return 10 + +class CmpErr: + "Dummy element that always raises an error during comparison" + def __cmp__(self, other): + raise ZeroDivisionError + +class TestErrorHandling(unittest.TestCase): + + def test_non_sequence(self): + for f in (bisect_left, bisect_right, insort_left, insort_right): + self.assertRaises(TypeError, f, 10, 10) + + def test_len_only(self): + for f in (bisect_left, bisect_right, insort_left, insort_right): + self.assertRaises(AttributeError, f, LenOnly(), 10) + + def test_get_only(self): + for f in (bisect_left, bisect_right, insort_left, insort_right): + self.assertRaises(AttributeError, f, GetOnly(), 10) + + def test_get_only(self): + seq = [CmpErr(), CmpErr(), CmpErr()] + for f in (bisect_left, bisect_right, insort_left, insort_right): + self.assertRaises(ZeroDivisionError, f, seq, 10) + + def test_arg_parsing(self): + for f in (bisect_left, bisect_right, insort_left, insort_right): + self.assertRaises(TypeError, f, 10) + +#============================================================================== + libreftest = """ Example from the Library Reference: Doc/lib/libbisect.tex @@ -178,8 +219,25 @@ def test_main(verbose=None): from test import test_bisect - test_support.run_unittest(TestBisect, TestInsort) + from types import BuiltinFunctionType + import sys + + test_classes = [TestBisect, TestInsort] + if isinstance(bisect_left, BuiltinFunctionType): + test_classes.append(TestErrorHandling) + + test_support.run_unittest(*test_classes) test_support.run_doctest(test_bisect, verbose) + # verify reference counting + if verbose and hasattr(sys, "gettotalrefcount"): + import gc + counts = [None] * 5 + for i in xrange(len(counts)): + test_support.run_unittest(*test_classes) + gc.collect() + counts[i] = sys.gettotalrefcount() + print counts + if __name__ == "__main__": test_main(verbose=True) From rhettinger at users.sourceforge.net Tue Sep 28 01:11:37 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 01:11:40 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_bisect.py, 1.12, 1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4584 Modified Files: test_bisect.py Log Message: Rename test for comparision errors. Index: test_bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bisect.py,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- test_bisect.py 27 Sep 2004 22:48:40 -0000 1.12 +++ test_bisect.py 27 Sep 2004 23:11:35 -0000 1.13 @@ -181,7 +181,7 @@ for f in (bisect_left, bisect_right, insort_left, insort_right): self.assertRaises(AttributeError, f, GetOnly(), 10) - def test_get_only(self): + def test_cmp_err(self): seq = [CmpErr(), CmpErr(), CmpErr()] for f in (bisect_left, bisect_right, insort_left, insort_right): self.assertRaises(ZeroDivisionError, f, seq, 10) From rhettinger at users.sourceforge.net Tue Sep 28 02:04:11 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 02:04:15 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_heapq.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16444/Lib/test Modified Files: test_heapq.py Log Message: Plug a leak and beef-up test coverage. Index: test_heapq.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_heapq.py,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- test_heapq.py 8 Jul 2004 04:22:19 -0000 1.14 +++ test_heapq.py 28 Sep 2004 00:03:54 -0000 1.15 @@ -110,8 +110,157 @@ for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100): self.assertEqual(nlargest(n, data), sorted(data, reverse=True)[:n]) + +#============================================================================== + +class LenOnly: + "Dummy sequence class defining __len__ but not __getitem__." + def __len__(self): + return 10 + +class GetOnly: + "Dummy sequence class defining __getitem__ but not __len__." + def __getitem__(self, ndx): + return 10 + +class CmpErr: + "Dummy element that always raises an error during comparison" + def __cmp__(self, other): + raise ZeroDivisionError + +def R(seqn): + 'Regular generator' + for i in seqn: + yield i + +class G: + 'Sequence using __getitem__' + def __init__(self, seqn): + self.seqn = seqn + def __getitem__(self, i): + return self.seqn[i] + +class I: + 'Sequence using iterator protocol' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + return self + def next(self): + if self.i >= len(self.seqn): raise StopIteration + v = self.seqn[self.i] + self.i += 1 + return v + +class Ig: + 'Sequence using iterator protocol defined with a generator' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + for val in self.seqn: + yield val + +class X: + 'Missing __getitem__ and __iter__' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def next(self): + if self.i >= len(self.seqn): raise StopIteration + v = self.seqn[self.i] + self.i += 1 + return v + +class N: + 'Iterator missing next()' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + return self + +class E: + 'Test propagation of exceptions' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + return self + def next(self): + 3 // 0 + +class S: + 'Test immediate stop' + def __init__(self, seqn): + pass + def __iter__(self): + return self + def next(self): + raise StopIteration + +from itertools import chain, imap +def L(seqn): + 'Test multiple tiers of iterators' + return chain(imap(lambda x:x, R(Ig(G(seqn))))) + +class TestErrorHandling(unittest.TestCase): + + def test_non_sequence(self): + for f in (heapify, heappop): + self.assertRaises(TypeError, f, 10) + for f in (heappush, heapreplace, nlargest, nsmallest): + self.assertRaises(TypeError, f, 10, 10) + + def test_len_only(self): + for f in (heapify, heappop): + self.assertRaises(TypeError, f, LenOnly()) + for f in (heappush, heapreplace): + self.assertRaises(TypeError, f, LenOnly(), 10) + for f in (nlargest, nsmallest): + self.assertRaises(TypeError, f, 2, LenOnly()) + + def test_get_only(self): + for f in (heapify, heappop): + self.assertRaises(TypeError, f, GetOnly()) + for f in (heappush, heapreplace): + self.assertRaises(TypeError, f, GetOnly(), 10) + for f in (nlargest, nsmallest): + self.assertRaises(TypeError, f, 2, GetOnly()) + + def test_get_only(self): + seq = [CmpErr(), CmpErr(), CmpErr()] + for f in (heapify, heappop): + self.assertRaises(ZeroDivisionError, f, seq) + for f in (heappush, heapreplace): + self.assertRaises(ZeroDivisionError, f, seq, 10) + for f in (nlargest, nsmallest): + self.assertRaises(ZeroDivisionError, f, 2, seq) + + def test_arg_parsing(self): + for f in (heapify, heappop, heappush, heapreplace, nlargest, nsmallest): + self.assertRaises(TypeError, f, 10) + + def test_iterable_args(self): + for f in (nlargest, nsmallest): + for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)): + for g in (G, I, Ig, L, R): + self.assertEqual(f(2, g(s)), f(2,s)) + self.assertEqual(f(2, S(s)), []) + self.assertRaises(TypeError, f, 2, X(s)) + self.assertRaises(TypeError, f, 2, N(s)) + self.assertRaises(ZeroDivisionError, f, 2, E(s)) + +#============================================================================== + + def test_main(verbose=None): + from types import BuiltinFunctionType + test_classes = [TestHeap] + if isinstance(heapify, BuiltinFunctionType): + test_classes.append(TestErrorHandling) test_support.run_unittest(*test_classes) # verify reference counting From rhettinger at users.sourceforge.net Tue Sep 28 02:04:26 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 02:04:28 2004 Subject: [Python-checkins] python/dist/src/Modules _heapqmodule.c,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16444/Modules Modified Files: _heapqmodule.c Log Message: Plug a leak and beef-up test coverage. Index: _heapqmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_heapqmodule.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- _heapqmodule.c 6 Sep 2004 07:04:08 -0000 1.7 +++ _heapqmodule.c 28 Sep 2004 00:03:53 -0000 1.8 @@ -28,8 +28,10 @@ parentpos = (pos - 1) >> 1; parent = PyList_GET_ITEM(heap, parentpos); cmp = PyObject_RichCompareBool(parent, newitem, Py_LE); - if (cmp == -1) + if (cmp == -1) { + Py_DECREF(newitem); return -1; + } if (cmp == 1) break; Py_INCREF(parent); @@ -69,8 +71,10 @@ PyList_GET_ITEM(heap, rightpos), PyList_GET_ITEM(heap, childpos), Py_LE); - if (cmp == -1) + if (cmp == -1) { + Py_DECREF(newitem); return -1; + } if (cmp == 1) childpos = rightpos; } @@ -315,8 +319,10 @@ parentpos = (pos - 1) >> 1; parent = PyList_GET_ITEM(heap, parentpos); cmp = PyObject_RichCompareBool(newitem, parent, Py_LE); - if (cmp == -1) + if (cmp == -1) { + Py_DECREF(newitem); return -1; + } if (cmp == 1) break; Py_INCREF(parent); @@ -356,8 +362,10 @@ PyList_GET_ITEM(heap, childpos), PyList_GET_ITEM(heap, rightpos), Py_LE); - if (cmp == -1) + if (cmp == -1) { + Py_DECREF(newitem); return -1; + } if (cmp == 1) childpos = rightpos; } From goodger at users.sourceforge.net Tue Sep 28 03:05:43 2004 From: goodger at users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue Sep 28 03:05:45 2004 Subject: [Python-checkins] python/nondist/peps pep-0301.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28154 Modified Files: pep-0301.txt Log Message: tweak Index: pep-0301.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0301.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- pep-0301.txt 30 Apr 2003 13:37:17 -0000 1.8 +++ pep-0301.txt 28 Sep 2004 01:05:40 -0000 1.9 @@ -394,7 +394,7 @@ The many participants of the Distutils and Catalog SIGs for their ideas over the years. - + .. Local Variables: mode: indented-text From goodger at users.sourceforge.net Tue Sep 28 03:11:21 2004 From: goodger at users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue Sep 28 03:11:24 2004 Subject: [Python-checkins] python/nondist/peps pep-0273.txt, 1.11, 1.12 pep-0302.txt, 1.15, 1.16 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29347 Modified Files: pep-0273.txt pep-0302.txt Log Message: details and clarifications, should have been checked in long ago Index: pep-0273.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0273.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- pep-0273.txt 27 Aug 2004 18:13:48 -0000 1.11 +++ pep-0273.txt 28 Sep 2004 01:11:15 -0000 1.12 @@ -17,6 +17,7 @@ same code is used to speed up normal directory imports provided os.listdir is available. + Note Zip imports were added to Python 2.3, but the final implementation @@ -189,14 +190,19 @@ Implementation A C implementation is available as SourceForge patch 492105. + Superceded by patch 652586 and current CVS. http://python.org/sf/492105 A newer version (updated for recent CVS by Paul Moore) is 645650. + Superceded by patch 652586 and current CVS. http://python.org/sf/645650 - A competing implementation by Just van Rossum is 652586. + A competing implementation by Just van Rossum is 652586, which is + the basis for the final implementation of PEP 302. PEP 273 has + been implemented using PEP 302's import hooks. http://python.org/sf/652586 + Copyright This document has been placed in the public domain. Index: pep-0302.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0302.txt,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- pep-0302.txt 23 Sep 2004 13:54:53 -0000 1.15 +++ pep-0302.txt 28 Sep 2004 01:11:15 -0000 1.16 @@ -526,12 +526,14 @@ Implementation - The PEP 302 implementation has been integrated with Python as of - 2.3a1. An earlier version is available as SourceForge patch - #652586, but more interestingly, the SF item contains a fairly - detailed history of the development and design. + The PEP 302 implementation is complete and has been integrated + with Python as of 2.3a1. An earlier version is available as + SourceForge patch #652586, but more interestingly, the SF item + contains a fairly detailed history of the development and design. http://www.python.org/sf/652586 + PEP 273 has been implemented using PEP 302's import hooks. + References and Footnotes From gward at users.sourceforge.net Tue Sep 28 03:30:27 2004 From: gward at users.sourceforge.net (gward@users.sourceforge.net) Date: Tue Sep 28 03:30:30 2004 Subject: [Python-checkins] python/dist/src/Doc/lib liboptparse.tex, 1.15, 1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv389 Modified Files: liboptparse.tex Log Message: Major overhaul to reflect Optik 1.5. Section references currently broken. Index: liboptparse.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liboptparse.tex,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- liboptparse.tex 11 Sep 2004 15:47:30 -0000 1.15 +++ liboptparse.tex 28 Sep 2004 01:30:23 -0000 1.16 @@ -1,27 +1,23 @@ -\section{\module{optparse} --- - Powerful parser for command line options.} - +\section{\module{optparse} --- More powerful command line option parser} \declaremodule{standard}{optparse} \moduleauthor{Greg Ward}{gward@python.net} -\sectionauthor{Johannes Gijsbers}{jlgijsbers@users.sf.net} -\sectionauthor{Greg Ward}{gward@python.net} - -\modulesynopsis{Powerful, flexible, extensible, easy-to-use command-line - parsing library.} [...2548 lines suppressed...] -\module{optparse}. - -Version 1: Add a method to \class{OptionParser} which applications -must call after parsing arguments: - -\verbatiminput{required_1.py} - -Version 2: Extend \class{Option} and add a \member{required} -attribute; extend \class{OptionParser} to ensure that required options -are present after parsing: - -\verbatiminput{required_2.py} +numbers in the arguments following \code{"-c"} will be interpreted as +further options (probably causing an error), rather than as arguments to +\code{"-c"}. Fixing this is left as an exercise for the reader. +% $Id$ -\begin{seealso} - \seemodule{getopt}{More traditional \UNIX-style command line option parsing.} -\end{seealso} From rhettinger at users.sourceforge.net Tue Sep 28 03:51:37 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 03:51:40 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_set.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4767/Lib/test Modified Files: test_set.py Log Message: Use Py_CLEAR(). Add unrelated test. Index: test_set.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_set.py,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- test_set.py 27 Sep 2004 15:29:05 -0000 1.14 +++ test_set.py 28 Sep 2004 01:51:35 -0000 1.15 @@ -23,6 +23,9 @@ self.s = self.thetype(word) self.d = dict.fromkeys(word) + def test_new_or_init(self): + self.assertRaises(TypeError, self.thetype, [], 2) + def test_uniquification(self): actual = sorted(self.s) expected = sorted(self.d) From rhettinger at users.sourceforge.net Tue Sep 28 03:51:37 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 03:51:41 2004 Subject: [Python-checkins] python/dist/src/Objects setobject.c,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4767/Objects Modified Files: setobject.c Log Message: Use Py_CLEAR(). Add unrelated test. Index: setobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/setobject.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- setobject.c 15 Jul 2004 15:54:05 -0000 1.29 +++ setobject.c 28 Sep 2004 01:51:34 -0000 1.30 @@ -105,7 +105,7 @@ w = (PySetObject *)make_new_set(&PyFrozenSet_Type, NULL); if (w == NULL) return NULL; - Py_DECREF(w->data); + Py_CLEAR(w->data); Py_INCREF(d); w->data = d; return (PyObject *)w; From rhettinger at users.sourceforge.net Tue Sep 28 04:19:43 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 04:19:45 2004 Subject: [Python-checkins] python/dist/src/Modules socketmodule.c, 1.306, 1.307 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9574 Modified Files: socketmodule.c Log Message: Silence a compiler warning by supplying the correct argument type to the htons() function. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.306 retrieving revision 1.307 diff -u -d -r1.306 -r1.307 --- socketmodule.c 13 Sep 2004 17:48:41 -0000 1.306 +++ socketmodule.c 28 Sep 2004 02:19:40 -0000 1.307 @@ -2944,10 +2944,10 @@ static PyObject * socket_getservbyport(PyObject *self, PyObject *args) { - int port; + unsigned short port; char *proto=NULL; struct servent *sp; - if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto)) + if (!PyArg_ParseTuple(args, "H|s:getservbyport", &port, &proto)) return NULL; Py_BEGIN_ALLOW_THREADS sp = getservbyport(htons(port), proto); From edloper at users.sourceforge.net Tue Sep 28 04:53:52 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 04:53:56 2004 Subject: [Python-checkins] python/dist/src/Doc/lib compiler.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15678/dist/src/Doc/lib Modified Files: compiler.tex Log Message: Updated interactive examples in the "Examples" session to reflect the fact that compiler.ast.Function now takes a "decorators" argument. Index: compiler.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/compiler.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- compiler.tex 30 Oct 2003 05:42:15 -0000 1.4 +++ compiler.tex 28 Sep 2004 02:53:50 -0000 1.5 @@ -269,21 +269,24 @@ >>> mod = compiler.parseFile("/tmp/doublelib.py") >>> mod Module('This is an example module.\n\nThis is the docstring.\n', - Stmt([Function('double', ['x'], [], 0, 'Return twice the argument', - Stmt([Return(Mul((Name('x'), Const(2))))]))])) + Stmt([Function(None, 'double', ['x'], [], 0, + 'Return twice the argument', + Stmt([Return(Mul((Name('x'), Const(2))))]))])) >>> from compiler.ast import * >>> Module('This is an example module.\n\nThis is the docstring.\n', -... Stmt([Function('double', ['x'], [], 0, 'Return twice the argument', -... Stmt([Return(Mul((Name('x'), Const(2))))]))])) +... Stmt([Function(None, 'double', ['x'], [], 0, +... 'Return twice the argument', +... Stmt([Return(Mul((Name('x'), Const(2))))]))])) Module('This is an example module.\n\nThis is the docstring.\n', - Stmt([Function('double', ['x'], [], 0, 'Return twice the argument', - Stmt([Return(Mul((Name('x'), Const(2))))]))])) + Stmt([Function(None, 'double', ['x'], [], 0, + 'Return twice the argument', + Stmt([Return(Mul((Name('x'), Const(2))))]))])) >>> mod.doc 'This is an example module.\n\nThis is the docstring.\n' >>> for node in mod.node.nodes: ... print node ... -Function('double', ['x'], [], 0, 'Return twice the argument', +Function(None, 'double', ['x'], [], 0, 'Return twice the argument', Stmt([Return(Mul((Name('x'), Const(2))))])) >>> func = mod.node.nodes[0] >>> func.code From edloper at users.sourceforge.net Tue Sep 28 04:54:57 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 04:55:00 2004 Subject: [Python-checkins] python/dist/src/Doc/lib emailheaders.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15847/dist/src/Doc/lib Modified Files: emailheaders.tex Log Message: Fixed minor typo in interactive example (backslash shouldn't be doubled) Index: emailheaders.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailheaders.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- emailheaders.tex 6 Mar 2003 06:06:54 -0000 1.4 +++ emailheaders.tex 28 Sep 2004 02:54:54 -0000 1.5 @@ -157,7 +157,7 @@ \begin{verbatim} >>> from email.Header import decode_header >>> decode_header('=?iso-8859-1?q?p=F6stal?=') -[('p\\xf6stal', 'iso-8859-1')] +[('p\xf6stal', 'iso-8859-1')] \end{verbatim} \end{funcdesc} From edloper at users.sourceforge.net Tue Sep 28 04:56:48 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 04:56:51 2004 Subject: [Python-checkins] python/dist/src/Doc/lib emailmessage.tex, 1.14, 1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16099/dist/src/Doc/lib Modified Files: emailmessage.tex Log Message: Fixed minor typo in interactive example Index: emailmessage.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailmessage.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- emailmessage.tex 31 Dec 2003 18:37:28 -0000 1.14 +++ emailmessage.tex 28 Sep 2004 02:56:45 -0000 1.15 @@ -498,7 +498,7 @@ \begin{verbatim} >>> for part in msg.walk(): ->>> print part.get_content_type() +... print part.get_content_type() multipart/report text/plain message/delivery-status From rhettinger at users.sourceforge.net Tue Sep 28 05:04:26 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 05:04:29 2004 Subject: [Python-checkins] python/dist/src/Doc/lib librandom.tex,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17262 Modified Files: librandom.tex Log Message: SF bug #1033038: Misleading error message in random.choice Added a clarifying line to the docs. Index: librandom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librandom.tex,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- librandom.tex 13 Sep 2004 22:23:21 -0000 1.37 +++ librandom.tex 28 Sep 2004 03:04:23 -0000 1.38 @@ -129,6 +129,7 @@ \begin{funcdesc}{choice}{seq} Return a random element from the non-empty sequence \var{seq}. + If \var{seq} is empty, raises \exception{IndexError}. \end{funcdesc} \begin{funcdesc}{shuffle}{x\optional{, random}} From edloper at users.sourceforge.net Tue Sep 28 05:09:00 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 05:09:01 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdecimal.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18068/dist/src/Doc/lib Modified Files: libdecimal.tex Log Message: Fixed minor typo in interactive example (extra blank line) Index: libdecimal.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdecimal.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- libdecimal.tex 26 Aug 2004 03:11:56 -0000 1.18 +++ libdecimal.tex 28 Sep 2004 03:08:57 -0000 1.19 @@ -266,7 +266,6 @@ Decimal("Infinity") >>> getcontext().traps[DivisionByZero] = 1 >>> Decimal(1) / Decimal(0) - Traceback (most recent call last): File "", line 1, in -toplevel- Decimal(1) / Decimal(0) From edloper at users.sourceforge.net Tue Sep 28 05:12:19 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 05:12:22 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libre.tex,1.110,1.111 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18657/dist/src/Doc/lib Modified Files: libre.tex Log Message: Fixed minor typo in interactive example (extra '.'s in '...' prompts) Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.110 retrieving revision 1.111 diff -u -d -r1.110 -r1.111 --- libre.tex 24 Sep 2004 03:41:05 -0000 1.110 +++ libre.tex 28 Sep 2004 03:12:01 -0000 1.111 @@ -598,8 +598,8 @@ \begin{verbatim} >>> def dashrepl(matchobj): -.... if matchobj.group(0) == '-': return ' ' -.... else: return '-' +... if matchobj.group(0) == '-': return ' ' +... else: return '-' >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files' \end{verbatim} From bcannon at users.sourceforge.net Tue Sep 28 05:49:55 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Tue Sep 28 05:49:58 2004 Subject: [Python-checkins] python/dist/src setup.py,1.201,1.202 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25324 Modified Files: setup.py Log Message: Add the directories where DarwinPorts installs library and include files to the proper path directories for compiling extension modules. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.201 retrieving revision 1.202 diff -u -d -r1.201 -r1.202 --- setup.py 31 Aug 2004 13:37:25 -0000 1.201 +++ setup.py 28 Sep 2004 03:49:52 -0000 1.202 @@ -245,11 +245,14 @@ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') - # fink installs lots of goodies in /sw/... - make sure we - # check there + # Add paths to popular package managers on OS X/darwin if sys.platform == "darwin": + # Fink installs into /sw by default add_dir_to_list(self.compiler.library_dirs, '/sw/lib') add_dir_to_list(self.compiler.include_dirs, '/sw/include') + # DarwinPorts installs into /opt/local by default + add_dir_to_list(self.compiler.library_dirs, '/opt/local/lib') + add_dir_to_list(self.compiler.include_dirs, '/opt/local/include') if os.path.normpath(sys.prefix) != '/usr': add_dir_to_list(self.compiler.library_dirs, From bcannon at users.sourceforge.net Tue Sep 28 06:08:15 2004 From: bcannon at users.sourceforge.net (bcannon@users.sourceforge.net) Date: Tue Sep 28 06:08:17 2004 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.1145,1.1146 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28610/Misc Modified Files: NEWS Log Message: Add note about inclusion of DarwinPorts directories in setup.py on darwin. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.1145 retrieving revision 1.1146 diff -u -d -r1.1145 -r1.1146 --- NEWS 26 Sep 2004 05:13:18 -0000 1.1145 +++ NEWS 28 Sep 2004 04:08:11 -0000 1.1146 @@ -82,6 +82,10 @@ Build ----- +- Building on darwin now includes /opt/local/include and /opt/local/lib for + building extension modules. This is so as to include software installed as + a DarwinPorts port + - pyport.h now defines a Py_IS_NAN macro. It works as-is when the platform C computes true for ``x != x`` if and only if X is a NaN. Other platforms can override the default definition with a platform- From edloper at users.sourceforge.net Tue Sep 28 06:29:59 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 06:30:04 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32322/dist/src/Doc/lib Modified Files: libdoctest.tex Log Message: Added a new NORMALIZE_NUMBERS option, which causes number literals in the expected output to match corresponding number literals in the actual output if their values are equal (to ten digits of precision). Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.61 retrieving revision 1.62 diff -u -d -r1.61 -r1.62 --- libdoctest.tex 27 Sep 2004 04:08:20 -0000 1.61 +++ libdoctest.tex 28 Sep 2004 04:29:57 -0000 1.62 @@ -581,6 +581,17 @@ \end{datadesc} +\begin{datadesc}{NORMALIZE_NUMBERS} + When specified, number literals in the expected output will match + corresponding number literals in the actual output if their values + are equal (to ten digits of precision). For example, \code{1.1} + will match \code{1.1000000000000001}; and \code{1L} will match + \code{1} and \code{1.0}. Currently, \constant{NORMALIZE_NUMBERS} + can fail to normalize numbers when used in conjunction with + ellipsis. In particular, if an ellipsis marker matches one or + more numbers, then number normalization is not supported. +\end{datadesc} + \begin{datadesc}{COMPARISON_FLAGS} A bitmask or'ing together all the comparison flags above. \end{datadesc} @@ -702,7 +713,7 @@ \versionchanged[Constants \constant{DONT_ACCEPT_BLANKLINE}, \constant{NORMALIZE_WHITESPACE}, \constant{ELLIPSIS}, - \constant{IGNORE_EXCEPTION_DETAIL}, + \constant{IGNORE_EXCEPTION_DETAIL}, \constant{NORMALIZE_NUMBERS}, \constant{REPORT_UDIFF}, \constant{REPORT_CDIFF}, \constant{REPORT_NDIFF}, \constant{REPORT_ONLY_FIRST_FAILURE}, \constant{COMPARISON_FLAGS} and \constant{REPORTING_FLAGS} @@ -740,6 +751,7 @@ % Hey! What happened to Monty Python examples? % Tim: ask Guido -- it's his example! +% doctest: ignore \begin{verbatim} >>> foo() {"Hermione": "hippogryph", "Harry": "broomstick"} @@ -747,6 +759,7 @@ is vulnerable! One workaround is to do +% doctest: ignore \begin{verbatim} >>> foo() == {"Hermione": "hippogryph", "Harry": "broomstick"} True @@ -754,6 +767,7 @@ instead. Another is to do +% doctest: ignore \begin{verbatim} >>> d = foo().items() >>> d.sort() @@ -765,6 +779,7 @@ Another bad idea is to print things that embed an object address, like +% doctest: ignore \begin{verbatim} >>> id(1.0) # certain to fail some of the time 7948648 @@ -776,6 +791,7 @@ The \constant{ELLIPSIS} directive gives a nice approach for the last example: +% doctest: ignore \begin{verbatim} >>> C() #doctest: +ELLIPSIS <__main__.C instance at 0x...> @@ -785,6 +801,7 @@ platforms, because Python defers to the platform C library for float formatting, and C libraries vary widely in quality here. +% doctest: ignore \begin{verbatim} >>> 1./7 # risky 0.14285714285714285 @@ -1618,6 +1635,7 @@ Then an interactive Python session may look like this: +% doctest: ignore \begin{verbatim} >>> import a, doctest >>> doctest.testmod(a) From edloper at users.sourceforge.net Tue Sep 28 06:30:00 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 06:30:06 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.114,1.115 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32322/dist/src/Lib Modified Files: doctest.py Log Message: Added a new NORMALIZE_NUMBERS option, which causes number literals in the expected output to match corresponding number literals in the actual output if their values are equal (to ten digits of precision). Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.114 retrieving revision 1.115 diff -u -d -r1.114 -r1.115 --- doctest.py 27 Sep 2004 03:42:58 -0000 1.114 +++ doctest.py 28 Sep 2004 04:29:57 -0000 1.115 @@ -55,6 +55,7 @@ 'NORMALIZE_WHITESPACE', 'ELLIPSIS', 'IGNORE_EXCEPTION_DETAIL', + 'NORMALIZE_NUMBERS', 'COMPARISON_FLAGS', 'REPORT_UDIFF', 'REPORT_CDIFF', @@ -139,12 +140,14 @@ NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE') ELLIPSIS = register_optionflag('ELLIPSIS') IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') +NORMALIZE_NUMBERS = register_optionflag('NORMALIZE_NUMBERS') COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | DONT_ACCEPT_BLANKLINE | NORMALIZE_WHITESPACE | ELLIPSIS | - IGNORE_EXCEPTION_DETAIL) + IGNORE_EXCEPTION_DETAIL | + NORMALIZE_NUMBERS) REPORT_UDIFF = register_optionflag('REPORT_UDIFF') REPORT_CDIFF = register_optionflag('REPORT_CDIFF') @@ -277,6 +280,72 @@ if hasattr(self, "softspace"): del self.softspace +# The number of digits of precision that must be equal for +# NORMALIZE_NUMBERS to consider two numbers equal. +_NORMALIZE_NUMBERS_PRECISION_THRESHOLD = 10 + +# A regular expression that matches Python number literals. This is +# used by _normalize_numbers to look for numbers that should be +# normalized. +_NUMBER_LITERAL = re.compile(r''' + (\d+[.]\d*(?:[eE][-+]?\d+)?[jJ]? | # float (w/ digits left of ".") + [.]\d+(?:[eE][-+]?\d+)?[jJ]? | # float (no digits left of ".") + \d+ (?:[eE][-+]?\d+) [jJ]? | # float (no ".", exponent only) + \d [jJ] | # float (no ".", imaginary only) + 0[xX]\d+[lL]? | # hexint + 0[0-7]*[lL]? | # octint or zero + \d+[lL]? ) # decint + ''', re.VERBOSE) + +def _normalize_numbers(want, got): + """ + If all the numbers in `want` and `got` match (one-for-one), then + return a new version of `got` with the exact number strings from + `want` spliced in. Two numbers match if `str` of their float + values are equal. (I.e., `x` matches `y` if + `str(float(x))==str(float(y))`). + """ + want_pieces = _NUMBER_LITERAL.split(want) + got_pieces = _NUMBER_LITERAL.split(got) + + # If they don't have the same number of numbers, fail immediately. + if len(want_pieces) != len(got_pieces): + return got + + # If any individual numbers don't match, then fail. + for i in range(1, len(got_pieces), 2): + w, g = eval(want_pieces[i]), eval(got_pieces[i]) + if not _numbers_match(w, g): + return got + + # Success; replace numbers in got w/ numbers from want. + for i in range(1, len(got_pieces), 2): + got_pieces[i] = want_pieces[i] + return ''.join(got_pieces) + +def _numbers_match(x, y): + """ + A helper function for _normalize_numbers, that returns true if the + numbers `x` and `y` are close enough to match for NORMALIZE_NUMBERS. + """ + # Equal numbers match. + if x == y: + return True + # Split up complex numbers into real & imag. + if isinstance(x, complex): + return (isinstance(y, complex) and + _numbers_match(x.real, y.real) and + _numbers_match(x.imag, y.imag)) + # If the signs are different, they don't match. + if x*y < 0: + return False + # If one is zero and the other isn't, they don't match. + if x==0 or y==0: + return False + # They're not exactly equal, but are they close enough? + threshold = 10**-_NORMALIZE_NUMBERS_PRECISION_THRESHOLD + return (abs(x-y) / min(abs(x), abs(y))) < threshold + # Worst-case linear-time ellipsis matching. def _ellipsis_match(want, got): """ @@ -1503,6 +1572,13 @@ if got == want: return True + # This flag causes doctest to treat numbers that are within a + # small threshold as if they are equal. + if optionflags & NORMALIZE_NUMBERS: + got = _normalize_numbers(want, got) + if got == want: + return True + # The ELLIPSIS flag says to let the sequence "..." in `want` # match any substring in `got`. if optionflags & ELLIPSIS: @@ -1783,6 +1859,7 @@ NORMALIZE_WHITESPACE ELLIPSIS IGNORE_EXCEPTION_DETAIL + NORMALIZE_NUMBERS REPORT_UDIFF REPORT_CDIFF REPORT_NDIFF @@ -1905,6 +1982,7 @@ NORMALIZE_WHITESPACE ELLIPSIS IGNORE_EXCEPTION_DETAIL + NORMALIZE_NUMBERS REPORT_UDIFF REPORT_CDIFF REPORT_NDIFF From edloper at users.sourceforge.net Tue Sep 28 06:30:14 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 06:30:16 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_doctest.py, 1.49, 1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32322/dist/src/Lib/test Modified Files: test_doctest.py Log Message: Added a new NORMALIZE_NUMBERS option, which causes number literals in the expected output to match corresponding number literals in the actual output if their values are equal (to ten digits of precision). Index: test_doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v retrieving revision 1.49 retrieving revision 1.50 diff -u -d -r1.49 -r1.50 --- test_doctest.py 21 Sep 2004 03:20:34 -0000 1.49 +++ test_doctest.py 28 Sep 2004 04:29:57 -0000 1.50 @@ -1032,6 +1032,107 @@ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] +The NORMALIZE_NUMBERS flag causes numbers that are equal (to +approximately 10 decimal places) but formatted differently to match. + + >>> def f(x): ''' + ... Numbers will match if they are exactly equal: + ... + ... >>> print 1.1, 'intervening text', 1L # should match + ... 1.1 intervening text 1L + ... >>> print 1.0j, 22, 22.0, 1, 1e1 # should match + ... 1j 22.0 22 1 10.0 + ... + ... Numbers will match if they are equal to 14 digits of + ... precision: + ... + ... >>> 2.00000000001 # should match + ... 1.99999999999 + ... >>> 2.000000001 # should not match + ... 1.999999999 + ... >>> 2.00000000001e10 # should match + ... 1.99999999999e10 + ... >>> 2.000000001e10 # should not match + ... 1.999999999e10 + ... ''' + + >>> # Without the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 4, in f + Failed example: + print 1.1, 'intervening text', 1L # should match + Expected: + 1.1 intervening text 1L + Got: + 1.1 intervening text 1 + ********************************************************************** + File ..., line 6, in f + Failed example: + print 1.0j, 22, 22.0, 1, 1e1 # should match + Expected: + 1j 22.0 22 1 10.0 + Got: + 1j 22 22.0 1 10.0 + ********************************************************************** + File ..., line 12, in f + Failed example: + 2.00000000001 # should match + Expected: + 1.99999999999 + Got: + 2.00000000001 + ********************************************************************** + File ..., line 14, in f + Failed example: + 2.000000001 # should not match + Expected: + 1.999999999 + Got: + 2.0000000010000001 + ********************************************************************** + File ..., line 16, in f + Failed example: + 2.00000000001e10 # should match + Expected: + 1.99999999999e10 + Got: + 20000000000.099998 + ********************************************************************** + File ..., line 18, in f + Failed example: + 2.000000001e10 # should not match + Expected: + 1.999999999e10 + Got: + 20000000010.0 + (6, 6) + + >>> # With the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.NORMALIZE_NUMBERS + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 14, in f + Failed example: + 2.000000001 # should not match + Expected: + 1.999999999 + Got: + 2.0000000010000001 + ********************************************************************** + File ..., line 18, in f + Failed example: + 2.000000001e10 # should not match + Expected: + 1.999999999e10 + Got: + 20000000010.0 + (2, 6) + The ELLIPSIS flag causes ellipsis marker ("...") in the expected output to match any substring in the actual output: From rhettinger at users.sourceforge.net Tue Sep 28 06:45:30 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 06:45:33 2004 Subject: [Python-checkins] python/dist/src/Modules itertoolsmodule.c, 1.35, 1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2652/Modules Modified Files: itertoolsmodule.c Log Message: * Increase test coverage. * Have groupby() be careful about decreffing structure members. Index: itertoolsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v retrieving revision 1.35 retrieving revision 1.36 diff -u -d -r1.35 -r1.36 --- itertoolsmodule.c 1 Sep 2004 07:02:43 -0000 1.35 +++ itertoolsmodule.c 28 Sep 2004 04:45:27 -0000 1.36 @@ -75,7 +75,7 @@ static PyObject * groupby_next(groupbyobject *gbo) { - PyObject *newvalue, *newkey, *r, *grouper; + PyObject *newvalue, *newkey, *r, *grouper, *tmp; /* skip to next iteration group */ for (;;) { @@ -110,15 +110,19 @@ } } - Py_XDECREF(gbo->currkey); + tmp = gbo->currkey; gbo->currkey = newkey; - Py_XDECREF(gbo->currvalue); + Py_XDECREF(tmp); + + tmp = gbo->currvalue; gbo->currvalue = newvalue; + Py_XDECREF(tmp); } - Py_XDECREF(gbo->tgtkey); - gbo->tgtkey = gbo->currkey; Py_INCREF(gbo->currkey); + tmp = gbo->tgtkey; + gbo->tgtkey = gbo->currkey; + Py_XDECREF(tmp); grouper = _grouper_create(gbo, gbo->tgtkey); if (grouper == NULL) From rhettinger at users.sourceforge.net Tue Sep 28 06:45:30 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 06:45:34 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_itertools.py, 1.33, 1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2652/Lib/test Modified Files: test_itertools.py Log Message: * Increase test coverage. * Have groupby() be careful about decreffing structure members. Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_itertools.py,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- test_itertools.py 27 Sep 2004 15:29:04 -0000 1.33 +++ test_itertools.py 28 Sep 2004 04:45:28 -0000 1.34 @@ -53,6 +53,10 @@ self.assertRaises(TypeError, count, 'a') c = count(sys.maxint-2) # verify that rollover doesn't crash c.next(); c.next(); c.next(); c.next(); c.next() + c = count(3) + self.assertEqual(repr(c), 'count(3)') + c.next() + self.assertEqual(repr(c), 'count(4)') def test_cycle(self): self.assertEqual(take(10, cycle('abc')), list('abcabcabca')) @@ -67,6 +71,7 @@ self.assertEqual([], list(groupby([], key=id))) self.assertRaises(TypeError, list, groupby('abc', [])) self.assertRaises(TypeError, groupby, None) + self.assertRaises(TypeError, groupby, 'abc', lambda x:x, 10) # Check normal input s = [(0, 10, 20), (0, 11,21), (0,12,21), (1,13,21), (1,14,22), @@ -199,6 +204,12 @@ self.assertRaises(TypeError, repeat) self.assertRaises(TypeError, repeat, None, 3, 4) self.assertRaises(TypeError, repeat, None, 'a') + r = repeat(1+0j) + self.assertEqual(repr(r), 'repeat((1+0j))') + r = repeat(1+0j, 5) + self.assertEqual(repr(r), 'repeat((1+0j), 5)') + list(r) + self.assertEqual(repr(r), 'repeat((1+0j), 0)') def test_imap(self): self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), @@ -275,6 +286,9 @@ self.assertRaises(TypeError, takewhile, operator.pow, [(4,5)], 'extra') self.assertRaises(TypeError, takewhile(10, [(4,5)]).next) self.assertRaises(ValueError, takewhile(errfunc, [(4,5)]).next) + t = takewhile(bool, [1, 1, 1, 0, 0, 0]) + self.assertEqual(list(t), [1, 1, 1]) + self.assertRaises(StopIteration, t.next) def test_dropwhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] @@ -347,11 +361,26 @@ self.assertEqual(list(a), range(100,2000)) self.assertEqual(list(c), range(2,2000)) + # test values of n + self.assertRaises(TypeError, tee, 'abc', 'invalid') + for n in xrange(5): + result = tee('abc', n) + self.assertEqual(type(result), tuple) + self.assertEqual(len(result), n) + self.assertEqual(map(list, result), [list('abc')]*n) + # tee pass-through to copyable iterator a, b = tee('abc') c, d = tee(a) self.assert_(a is c) + # test tee_new + t1, t2 = tee('abc') + tnew = type(t1) + self.assertRaises(TypeError, tnew) + self.assertRaises(TypeError, tnew, 10) + t3 = tnew(t1) + self.assert_(list(t1) == list(t2) == list(t3) == list('abc')) def test_StopIteration(self): self.assertRaises(StopIteration, izip().next) From bwarsaw at users.sourceforge.net Tue Sep 28 06:55:38 2004 From: bwarsaw at users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue Sep 28 06:55:41 2004 Subject: [Python-checkins] python/dist/src/Lib/email Message.py, 1.32.10.4, 1.32.10.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4759 Modified Files: Tag: release23-maint Message.py Log Message: __getitem__(): Fix docstring, SF 979924. Index: Message.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v retrieving revision 1.32.10.4 retrieving revision 1.32.10.5 diff -u -d -r1.32.10.4 -r1.32.10.5 --- Message.py 16 Aug 2004 15:31:42 -0000 1.32.10.4 +++ Message.py 28 Sep 2004 04:55:34 -0000 1.32.10.5 @@ -298,7 +298,7 @@ Return None if the header is missing instead of raising an exception. Note that if the header appeared multiple times, exactly which - occurrance gets returned is undefined. Use getall() to get all + occurrance gets returned is undefined. Use get_all() to get all the values matching a header field name. """ return self.get(name) From edloper at users.sourceforge.net Tue Sep 28 07:51:00 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 07:51:03 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_doctest.py, 1.50, 1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14073/Lib/test Modified Files: test_doctest.py Log Message: Reverted the addition of a NORMALIZE_NUMBERS option, per Tim Peter's request. Tim says that "correct 'fuzzy' comparison of floats cannot be automated." (The motivation behind adding the new option was verifying interactive examples in Python's latex documentation; several such examples use numbers that don't print consistently on different platforms.) Index: test_doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest.py,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- test_doctest.py 28 Sep 2004 04:29:57 -0000 1.50 +++ test_doctest.py 28 Sep 2004 05:50:57 -0000 1.51 @@ -1032,107 +1032,6 @@ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] -The NORMALIZE_NUMBERS flag causes numbers that are equal (to -approximately 10 decimal places) but formatted differently to match. - - >>> def f(x): ''' - ... Numbers will match if they are exactly equal: - ... - ... >>> print 1.1, 'intervening text', 1L # should match - ... 1.1 intervening text 1L - ... >>> print 1.0j, 22, 22.0, 1, 1e1 # should match - ... 1j 22.0 22 1 10.0 - ... - ... Numbers will match if they are equal to 14 digits of - ... precision: - ... - ... >>> 2.00000000001 # should match - ... 1.99999999999 - ... >>> 2.000000001 # should not match - ... 1.999999999 - ... >>> 2.00000000001e10 # should match - ... 1.99999999999e10 - ... >>> 2.000000001e10 # should not match - ... 1.999999999e10 - ... ''' - - >>> # Without the flag: - >>> test = doctest.DocTestFinder().find(f)[0] - >>> doctest.DocTestRunner(verbose=False).run(test) - ... # doctest: +ELLIPSIS - ********************************************************************** - File ..., line 4, in f - Failed example: - print 1.1, 'intervening text', 1L # should match - Expected: - 1.1 intervening text 1L - Got: - 1.1 intervening text 1 - ********************************************************************** - File ..., line 6, in f - Failed example: - print 1.0j, 22, 22.0, 1, 1e1 # should match - Expected: - 1j 22.0 22 1 10.0 - Got: - 1j 22 22.0 1 10.0 - ********************************************************************** - File ..., line 12, in f - Failed example: - 2.00000000001 # should match - Expected: - 1.99999999999 - Got: - 2.00000000001 - ********************************************************************** - File ..., line 14, in f - Failed example: - 2.000000001 # should not match - Expected: - 1.999999999 - Got: - 2.0000000010000001 - ********************************************************************** - File ..., line 16, in f - Failed example: - 2.00000000001e10 # should match - Expected: - 1.99999999999e10 - Got: - 20000000000.099998 - ********************************************************************** - File ..., line 18, in f - Failed example: - 2.000000001e10 # should not match - Expected: - 1.999999999e10 - Got: - 20000000010.0 - (6, 6) - - >>> # With the flag: - >>> test = doctest.DocTestFinder().find(f)[0] - >>> flags = doctest.NORMALIZE_NUMBERS - >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) - ... # doctest: +ELLIPSIS - ********************************************************************** - File ..., line 14, in f - Failed example: - 2.000000001 # should not match - Expected: - 1.999999999 - Got: - 2.0000000010000001 - ********************************************************************** - File ..., line 18, in f - Failed example: - 2.000000001e10 # should not match - Expected: - 1.999999999e10 - Got: - 20000000010.0 - (2, 6) - The ELLIPSIS flag causes ellipsis marker ("...") in the expected output to match any substring in the actual output: From edloper at users.sourceforge.net Tue Sep 28 07:50:59 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 07:51:05 2004 Subject: [Python-checkins] python/dist/src/Lib doctest.py,1.115,1.116 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14073/Lib Modified Files: doctest.py Log Message: Reverted the addition of a NORMALIZE_NUMBERS option, per Tim Peter's request. Tim says that "correct 'fuzzy' comparison of floats cannot be automated." (The motivation behind adding the new option was verifying interactive examples in Python's latex documentation; several such examples use numbers that don't print consistently on different platforms.) Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.115 retrieving revision 1.116 diff -u -d -r1.115 -r1.116 --- doctest.py 28 Sep 2004 04:29:57 -0000 1.115 +++ doctest.py 28 Sep 2004 05:50:57 -0000 1.116 @@ -55,7 +55,6 @@ 'NORMALIZE_WHITESPACE', 'ELLIPSIS', 'IGNORE_EXCEPTION_DETAIL', - 'NORMALIZE_NUMBERS', 'COMPARISON_FLAGS', 'REPORT_UDIFF', 'REPORT_CDIFF', @@ -140,14 +139,12 @@ NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE') ELLIPSIS = register_optionflag('ELLIPSIS') IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') -NORMALIZE_NUMBERS = register_optionflag('NORMALIZE_NUMBERS') COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | DONT_ACCEPT_BLANKLINE | NORMALIZE_WHITESPACE | ELLIPSIS | - IGNORE_EXCEPTION_DETAIL | - NORMALIZE_NUMBERS) + IGNORE_EXCEPTION_DETAIL) REPORT_UDIFF = register_optionflag('REPORT_UDIFF') REPORT_CDIFF = register_optionflag('REPORT_CDIFF') @@ -280,72 +277,6 @@ if hasattr(self, "softspace"): del self.softspace -# The number of digits of precision that must be equal for -# NORMALIZE_NUMBERS to consider two numbers equal. -_NORMALIZE_NUMBERS_PRECISION_THRESHOLD = 10 - -# A regular expression that matches Python number literals. This is -# used by _normalize_numbers to look for numbers that should be -# normalized. -_NUMBER_LITERAL = re.compile(r''' - (\d+[.]\d*(?:[eE][-+]?\d+)?[jJ]? | # float (w/ digits left of ".") - [.]\d+(?:[eE][-+]?\d+)?[jJ]? | # float (no digits left of ".") - \d+ (?:[eE][-+]?\d+) [jJ]? | # float (no ".", exponent only) - \d [jJ] | # float (no ".", imaginary only) - 0[xX]\d+[lL]? | # hexint - 0[0-7]*[lL]? | # octint or zero - \d+[lL]? ) # decint - ''', re.VERBOSE) - -def _normalize_numbers(want, got): - """ - If all the numbers in `want` and `got` match (one-for-one), then - return a new version of `got` with the exact number strings from - `want` spliced in. Two numbers match if `str` of their float - values are equal. (I.e., `x` matches `y` if - `str(float(x))==str(float(y))`). - """ - want_pieces = _NUMBER_LITERAL.split(want) - got_pieces = _NUMBER_LITERAL.split(got) - - # If they don't have the same number of numbers, fail immediately. - if len(want_pieces) != len(got_pieces): - return got - - # If any individual numbers don't match, then fail. - for i in range(1, len(got_pieces), 2): - w, g = eval(want_pieces[i]), eval(got_pieces[i]) - if not _numbers_match(w, g): - return got - - # Success; replace numbers in got w/ numbers from want. - for i in range(1, len(got_pieces), 2): - got_pieces[i] = want_pieces[i] - return ''.join(got_pieces) - -def _numbers_match(x, y): - """ - A helper function for _normalize_numbers, that returns true if the - numbers `x` and `y` are close enough to match for NORMALIZE_NUMBERS. - """ - # Equal numbers match. - if x == y: - return True - # Split up complex numbers into real & imag. - if isinstance(x, complex): - return (isinstance(y, complex) and - _numbers_match(x.real, y.real) and - _numbers_match(x.imag, y.imag)) - # If the signs are different, they don't match. - if x*y < 0: - return False - # If one is zero and the other isn't, they don't match. - if x==0 or y==0: - return False - # They're not exactly equal, but are they close enough? - threshold = 10**-_NORMALIZE_NUMBERS_PRECISION_THRESHOLD - return (abs(x-y) / min(abs(x), abs(y))) < threshold - # Worst-case linear-time ellipsis matching. def _ellipsis_match(want, got): """ @@ -1572,13 +1503,6 @@ if got == want: return True - # This flag causes doctest to treat numbers that are within a - # small threshold as if they are equal. - if optionflags & NORMALIZE_NUMBERS: - got = _normalize_numbers(want, got) - if got == want: - return True - # The ELLIPSIS flag says to let the sequence "..." in `want` # match any substring in `got`. if optionflags & ELLIPSIS: @@ -1859,7 +1783,6 @@ NORMALIZE_WHITESPACE ELLIPSIS IGNORE_EXCEPTION_DETAIL - NORMALIZE_NUMBERS REPORT_UDIFF REPORT_CDIFF REPORT_NDIFF @@ -1982,7 +1905,6 @@ NORMALIZE_WHITESPACE ELLIPSIS IGNORE_EXCEPTION_DETAIL - NORMALIZE_NUMBERS REPORT_UDIFF REPORT_CDIFF REPORT_NDIFF From edloper at users.sourceforge.net Tue Sep 28 07:51:00 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Tue Sep 28 07:51:09 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14073/Doc/lib Modified Files: libdoctest.tex Log Message: Reverted the addition of a NORMALIZE_NUMBERS option, per Tim Peter's request. Tim says that "correct 'fuzzy' comparison of floats cannot be automated." (The motivation behind adding the new option was verifying interactive examples in Python's latex documentation; several such examples use numbers that don't print consistently on different platforms.) Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.62 retrieving revision 1.63 diff -u -d -r1.62 -r1.63 --- libdoctest.tex 28 Sep 2004 04:29:57 -0000 1.62 +++ libdoctest.tex 28 Sep 2004 05:50:57 -0000 1.63 @@ -581,17 +581,6 @@ \end{datadesc} -\begin{datadesc}{NORMALIZE_NUMBERS} - When specified, number literals in the expected output will match - corresponding number literals in the actual output if their values - are equal (to ten digits of precision). For example, \code{1.1} - will match \code{1.1000000000000001}; and \code{1L} will match - \code{1} and \code{1.0}. Currently, \constant{NORMALIZE_NUMBERS} - can fail to normalize numbers when used in conjunction with - ellipsis. In particular, if an ellipsis marker matches one or - more numbers, then number normalization is not supported. -\end{datadesc} - \begin{datadesc}{COMPARISON_FLAGS} A bitmask or'ing together all the comparison flags above. \end{datadesc} @@ -713,7 +702,7 @@ \versionchanged[Constants \constant{DONT_ACCEPT_BLANKLINE}, \constant{NORMALIZE_WHITESPACE}, \constant{ELLIPSIS}, - \constant{IGNORE_EXCEPTION_DETAIL}, \constant{NORMALIZE_NUMBERS}, + \constant{IGNORE_EXCEPTION_DETAIL}, \constant{REPORT_UDIFF}, \constant{REPORT_CDIFF}, \constant{REPORT_NDIFF}, \constant{REPORT_ONLY_FIRST_FAILURE}, \constant{COMPARISON_FLAGS} and \constant{REPORTING_FLAGS} @@ -751,7 +740,6 @@ % Hey! What happened to Monty Python examples? % Tim: ask Guido -- it's his example! -% doctest: ignore \begin{verbatim} >>> foo() {"Hermione": "hippogryph", "Harry": "broomstick"} @@ -759,7 +747,6 @@ is vulnerable! One workaround is to do -% doctest: ignore \begin{verbatim} >>> foo() == {"Hermione": "hippogryph", "Harry": "broomstick"} True @@ -767,7 +754,6 @@ instead. Another is to do -% doctest: ignore \begin{verbatim} >>> d = foo().items() >>> d.sort() @@ -779,7 +765,6 @@ Another bad idea is to print things that embed an object address, like -% doctest: ignore \begin{verbatim} >>> id(1.0) # certain to fail some of the time 7948648 @@ -791,7 +776,6 @@ The \constant{ELLIPSIS} directive gives a nice approach for the last example: -% doctest: ignore \begin{verbatim} >>> C() #doctest: +ELLIPSIS <__main__.C instance at 0x...> @@ -801,7 +785,6 @@ platforms, because Python defers to the platform C library for float formatting, and C libraries vary widely in quality here. -% doctest: ignore \begin{verbatim} >>> 1./7 # risky 0.14285714285714285 @@ -1635,7 +1618,6 @@ Then an interactive Python session may look like this: -% doctest: ignore \begin{verbatim} >>> import a, doctest >>> doctest.testmod(a) From goodger at users.sourceforge.net Tue Sep 28 14:39:03 2004 From: goodger at users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue Sep 28 14:39:07 2004 Subject: [Python-checkins] python/nondist/peps pep-0302.txt,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28245 Modified Files: pep-0302.txt Log Message: not complete; I stand corrected ;-) Index: pep-0302.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0302.txt,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- pep-0302.txt 28 Sep 2004 01:11:15 -0000 1.16 +++ pep-0302.txt 28 Sep 2004 12:39:00 -0000 1.17 @@ -526,10 +526,10 @@ Implementation - The PEP 302 implementation is complete and has been integrated - with Python as of 2.3a1. An earlier version is available as - SourceForge patch #652586, but more interestingly, the SF item - contains a fairly detailed history of the development and design. + The PEP 302 implementation has been integrated with Python as of + 2.3a1. An earlier version is available as SourceForge patch + #652586, but more interestingly, the SF item contains a fairly + detailed history of the development and design. http://www.python.org/sf/652586 PEP 273 has been implemented using PEP 302's import hooks. From tim_one at users.sourceforge.net Tue Sep 28 18:12:55 2004 From: tim_one at users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue Sep 28 18:12:58 2004 Subject: [Python-checkins] python/dist/src/Doc/tut tut.tex,1.252,1.253 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9941/Doc/tut Modified Files: tut.tex Log Message: A number of list examples used 66.6, but I doubt there's any box on which repr(66.6) == "66.6", so doubt that the claimed output has ever been seen. Changed it to 66.25 everywhere, and manually verified that the new claimed output is correct. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.252 retrieving revision 1.253 diff -u -d -r1.252 -r1.253 --- tut.tex 25 Sep 2004 00:55:38 -0000 1.252 +++ tut.tex 28 Sep 2004 16:12:50 -0000 1.253 @@ -1749,24 +1749,24 @@ An example that uses most of the list methods: \begin{verbatim} ->>> a = [66.6, 333, 333, 1, 1234.5] ->>> print a.count(333), a.count(66.6), a.count('x') +>>> a = [66.25, 333, 333, 1, 1234.5] +>>> print a.count(333), a.count(66.25), a.count('x') 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a -[66.6, 333, -1, 333, 1, 1234.5, 333] +[66.25, 333, -1, 333, 1, 1234.5, 333] >>> a.index(333) 1 >>> a.remove(333) >>> a -[66.6, -1, 333, 1, 1234.5, 333] +[66.25, -1, 333, 1, 1234.5, 333] >>> a.reverse() >>> a -[333, 1234.5, 1, 333, -1, 66.6] +[333, 1234.5, 1, 333, -1, 66.25] >>> a.sort() >>> a -[-1, 1, 66.6, 333, 333, 1234.5] +[-1, 1, 66.25, 333, 333, 1234.5] \end{verbatim} @@ -1958,13 +1958,13 @@ empty list to the slice). For example: \begin{verbatim} ->>> a = [-1, 1, 66.6, 333, 333, 1234.5] +>>> a = [-1, 1, 66.25, 333, 333, 1234.5] >>> del a[0] >>> a -[1, 66.6, 333, 333, 1234.5] +[1, 66.25, 333, 333, 1234.5] >>> del a[2:4] >>> a -[1, 66.6, 1234.5] +[1, 66.25, 1234.5] \end{verbatim} \keyword{del} can also be used to delete entire variables: From rhettinger at users.sourceforge.net Tue Sep 28 19:22:15 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue Sep 28 19:22:20 2004 Subject: [Python-checkins] python/dist/src/Python compile.c,2.327,2.328 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27403 Modified Files: compile.c Log Message: Replaced a test with an assertion. (Suggested by Michael Hudson.) Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.327 retrieving revision 2.328 diff -u -d -r2.327 -r2.328 --- compile.c 22 Sep 2004 18:44:20 -0000 2.327 +++ compile.c 28 Sep 2004 17:22:12 -0000 2.328 @@ -509,10 +509,8 @@ if (memchr(lineno, 255, tabsiz) != NULL) goto exitUnchanged; - if (!PyString_Check(code)) - goto exitUnchanged; - /* Avoid situations where jump retargeting could overflow */ + assert(PyString_Check(code)); codelen = PyString_Size(code); if (codelen > 32700) goto exitUnchanged; From montanaro at users.sourceforge.net Tue Sep 28 20:30:06 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue Sep 28 20:30:10 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libtime.tex,1.66,1.67 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11362 Modified Files: libtime.tex Log Message: typo Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.66 retrieving revision 1.67 diff -u -d -r1.66 -r1.67 --- libtime.tex 13 Aug 2004 02:34:06 -0000 1.66 +++ libtime.tex 28 Sep 2004 18:30:03 -0000 1.67 @@ -308,7 +308,7 @@ according to \var{format}, \exception{ValueError} is raised. If the string to be parsed has excess data after parsing, \exception{ValueError} is raised. The default values used to fill in -any missing data is \code{(1900, 1, 1, 0, 0, 0, 0, 1, -1)} . +any missing data are \code{(1900, 1, 1, 0, 0, 0, 0, 1, -1)} . Support for the \code{\%Z} directive is based on the values contained in \code{tzname} and whether \code{daylight} is true. Because of this, From montanaro at users.sourceforge.net Tue Sep 28 20:40:44 2004 From: montanaro at users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue Sep 28 20:40:56 2004 Subject: [Python-checkins] python/dist/src/Doc/lib xmldomminidom.tex, 1.9, 1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13555 Modified Files: xmldomminidom.tex Log Message: minor doc tweaks for writexml Index: xmldomminidom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmldomminidom.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- xmldomminidom.tex 25 Mar 2004 16:39:46 -0000 1.9 +++ xmldomminidom.tex 28 Sep 2004 18:40:42 -0000 1.10 @@ -137,16 +137,20 @@ children of that node. \end{methoddesc} -\begin{methoddesc}[Node]{writexml}{writer} +\begin{methoddesc}[Node]{writexml}{writer\optional{,indent=""\optional{,addindent=""\optional{,newl=""}}}} Write XML to the writer object. The writer should have a \method{write()} method which matches that of the file object -interface. +interface. The \var{indent} parameter is the indentation of the current +node. The \var{addindent} parameter is the incremental indentation to use +for subnodes of the current one. The \var{newl} parameter specifies the +string to use to terminate newlines. -\versionchanged[To support pretty output, new keyword parameters -\var{indent}, \var{addindent}, and \var{newl} have been added]{2.1} +\versionchanged[The optional keyword parameters +\var{indent}, \var{addindent}, and \var{newl} were added to support pretty +output]{2.1} \versionchanged[For the \class{Document} node, an additional keyword -argument encoding can be used to specify the encoding field of the XML +argument \var{encoding} can be used to specify the encoding field of the XML header]{2.3} \end{methoddesc} From rhettinger at users.sourceforge.net Wed Sep 29 10:03:20 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 29 10:03:23 2004 Subject: [Python-checkins] python/dist/src/Lib/test list_tests.py, 1.3, 1.4 test_list.py, 1.2, 1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3516 Modified Files: list_tests.py test_list.py Log Message: Improve test coverage. Index: list_tests.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/list_tests.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- list_tests.py 13 Aug 2004 03:18:29 -0000 1.3 +++ list_tests.py 29 Sep 2004 08:03:17 -0000 1.4 @@ -3,12 +3,40 @@ """ import sys +import os import unittest from test import test_support, seq_tests class CommonTest(seq_tests.CommonTest): + def test_init(self): + # Iterable arg is optional + self.assertEqual(self.type2test([]), self.type2test()) + + # Init clears previous values + a = self.type2test([1, 2, 3]) + a.__init__() + self.assertEqual(a, self.type2test([])) + + # Init overwrites previous values + a = self.type2test([1, 2, 3]) + a.__init__([4, 5, 6]) + self.assertEqual(a, self.type2test([4, 5, 6])) + + # Mutables always return a new object + b = self.type2test(a) + self.assertNotEqual(id(a), id(b)) + self.assertEqual(a, b) + + def test_mul(self): + for m in xrange(4): + s = tuple(range(m)) + for n in xrange(-3, 5): + self.assertEqual(self.type2test(s*n), self.type2test(s)*n) + self.assertEqual(self.type2test(s)*(-4), self.type2test([])) + self.assertEqual(id(s), id(s*1)) + def test_repr(self): l0 = [] l2 = [0, 1, 2] @@ -21,6 +49,71 @@ self.assertEqual(str(a2), "[0, 1, 2]") self.assertEqual(repr(a2), "[0, 1, 2]") + a2.append(a2) + a2.append(3) + self.assertEqual(str(a2), "[0, 1, 2, [...], 3]") + self.assertEqual(repr(a2), "[0, 1, 2, [...], 3]") + + def test_print(self): + d = self.type2test(xrange(200)) + d.append(d) + d.extend(xrange(200,400)) + d.append(d) + d.append(400) + try: + fo = open(test_support.TESTFN, "wb") + print >> fo, d, + fo.close() + fo = open(test_support.TESTFN, "rb") + self.assertEqual(fo.read(), repr(d)) + finally: + fo.close() + os.remove(test_support.TESTFN) + + def test_getitem(self): + a = self.type2test([10, 11]) + self.assertEqual(a[0], 10) + self.assertEqual(a[1], 11) + self.assertEqual(a[-2], 10) + self.assertEqual(a[-1], 11) + self.assertRaises(IndexError, a.__getitem__, -3) + self.assertRaises(IndexError, a.__getitem__, 3) + + def test_subscript(self): + a = self.type2test([10, 11]) + self.assertEqual(a.__getitem__(0L), 10) + self.assertEqual(a.__getitem__(1L), 11) + self.assertEqual(a.__getitem__(-2L), 10) + self.assertEqual(a.__getitem__(-1L), 11) + self.assertRaises(IndexError, a.__getitem__, -3) + self.assertRaises(IndexError, a.__getitem__, 3) + self.assertEqual(a.__getitem__(slice(0,1)), self.type2test([10])) + self.assertEqual(a.__getitem__(slice(1,2)), self.type2test([11])) + self.assertEqual(a.__getitem__(slice(0,2)), self.type2test([10, 11])) + self.assertEqual(a.__getitem__(slice(0,3)), self.type2test([10, 11])) + self.assertEqual(a.__getitem__(slice(3,5)), self.type2test([])) + self.assertRaises(ValueError, a.__getitem__, slice(0, 10, 0)) + self.assertRaises(TypeError, a.__getitem__, 'x') + + def test_set_subscript(self): + a = self.type2test(range(20)) + self.assertRaises(ValueError, a.__setitem__, slice(0, 10, 0), [1,2,3]) + self.assertRaises(TypeError, a.__setitem__, slice(0, 10), 1) + self.assertRaises(ValueError, a.__setitem__, slice(0, 10, 2), [1,2]) + self.assertRaises(TypeError, a.__getitem__, 'x', 1) + a[slice(2,10,3)] = [1,2,3] + self.assertEqual(a, self.type2test([0, 1, 1, 3, 4, 2, 6, 7, 3, + 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19])) + + def test_reversed(self): + a = self.type2test(range(20)) + r = reversed(a) + self.assertEqual(list(r), self.type2test(range(19, -1, -1))) + self.assertRaises(StopIteration, r.next) + self.assertEqual(list(reversed(self.type2test())), + self.type2test()) + def test_setitem(self): a = self.type2test([0, 1]) a[0] = 0 @@ -36,7 +129,6 @@ a = self.type2test([]) self.assertRaises(IndexError, a.__setitem__, 0, 200) self.assertRaises(IndexError, a.__setitem__, -1, 200) - self.assertRaises(TypeError, a.__setitem__) a = self.type2test([0,1,2,3,4]) @@ -210,6 +302,7 @@ self.assertRaises(TypeError, a.insert) def test_pop(self): + from decimal import Decimal a = self.type2test([-1, 0, 1]) a.pop() self.assertEqual(a, [-1, 0]) @@ -219,8 +312,10 @@ a.pop(0) self.assertEqual(a, []) self.assertRaises(IndexError, a.pop) - self.assertRaises(TypeError, a.pop, 42, 42) + a = self.type2test([0, 10, 20, 30, 40]) + self.assertEqual(a.pop(Decimal(2)), 20) + self.assertRaises(IndexError, a.pop, Decimal(25)) def test_remove(self): a = self.type2test([0, 0, 1]) @@ -390,6 +485,10 @@ self.assertEqual(u, self.type2test([0, 1, 0, 1, 0, 1])) u *= 0 self.assertEqual(u, self.type2test([])) + s = self.type2test([]) + oldid = id(s) + s *= 10 + self.assertEqual(id(s), oldid) def test_extendedslicing(self): # subscript Index: test_list.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_list.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- test_list.py 18 Jan 2004 21:03:23 -0000 1.2 +++ test_list.py 29 Sep 2004 08:03:17 -0000 1.3 @@ -18,8 +18,20 @@ self.assertEqual(len([0]), 1) self.assertEqual(len([0, 1, 2]), 3) -def test_main(): +def test_main(verbose=None): test_support.run_unittest(ListTest) -if __name__=="__main__": - test_main() + # verify reference counting + import sys + if verbose and hasattr(sys, "gettotalrefcount"): + import gc + counts = [None] * 5 + for i in xrange(len(counts)): + test_support.run_unittest(ListTest) + gc.collect() + counts[i] = sys.gettotalrefcount() + print counts + + +if __name__ == "__main__": + test_main(verbose=True) From rhettinger at users.sourceforge.net Wed Sep 29 13:40:53 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 29 13:40:56 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_itertools.py, 1.34, 1.35 test_enumerate.py, 1.13, 1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10714 Modified Files: test_itertools.py test_enumerate.py Log Message: Improve test coverage. Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_itertools.py,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- test_itertools.py 28 Sep 2004 04:45:28 -0000 1.34 +++ test_itertools.py 29 Sep 2004 11:40:50 -0000 1.35 @@ -420,6 +420,14 @@ a = [] self.makecycle(cycle([a]*2), a) + def test_dropwhile(self): + a = [] + self.makecycle(dropwhile(bool, [0, a, a]), a) + + def test_groupby(self): + a = [] + self.makecycle(groupby([a]*2, lambda x:x), a) + def test_ifilter(self): a = [] self.makecycle(ifilter(lambda x:True, [a]*2), a) @@ -440,10 +448,18 @@ a = [] self.makecycle(islice([a]*2, None), a) + def test_repeat(self): + a = [] + self.makecycle(repeat(a), a) + def test_starmap(self): a = [] self.makecycle(starmap(lambda *t: t, [(a,a)]*2), a) + def test_takewhile(self): + a = [] + self.makecycle(takewhile(bool, [1, 0, a, a]), a) + def R(seqn): 'Regular generator' for i in seqn: Index: test_enumerate.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_enumerate.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- test_enumerate.py 27 Sep 2004 15:29:04 -0000 1.13 +++ test_enumerate.py 29 Sep 2004 11:40:50 -0000 1.14 @@ -145,6 +145,35 @@ # This is an implementation detail, not an interface requirement for s in ('hello', tuple('hello'), list('hello'), xrange(5)): self.assertEqual(len(reversed(s)), len(s)) + r = reversed(s) + list(r) + self.assertEqual(len(r), 0) + class SeqWithWeirdLen: + called = False + def __len__(self): + if not self.called: + self.called = True + return 10 + raise ZeroDivisionError + def __getitem__(self, index): + return index + r = reversed(SeqWithWeirdLen()) + self.assertRaises(ZeroDivisionError, len, r) + + + def test_gc(self): + class Seq: + def __len__(self): + return 10 + def __getitem__(self, index): + return index + s = Seq() + r = reversed(s) + s.r = r + + def test_args(self): + self.assertRaises(TypeError, reversed) + self.assertRaises(TypeError, reversed, [], 'extra') def test_main(verbose=None): testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig, From mondragon at users.sourceforge.net Wed Sep 29 23:39:33 2004 From: mondragon at users.sourceforge.net (mondragon@users.sourceforge.net) Date: Wed Sep 29 23:39:40 2004 Subject: [Python-checkins] python/dist/src/Doc/api concrete.tex,1.56,1.57 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7126 Modified Files: concrete.tex Log Message: Fix typo in PyDict_Items doc Index: concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.56 retrieving revision 1.57 diff -u -d -r1.56 -r1.57 --- concrete.tex 7 Sep 2004 20:24:04 -0000 1.56 +++ concrete.tex 29 Sep 2004 21:39:26 -0000 1.57 @@ -1948,7 +1948,7 @@ \begin{cfuncdesc}{PyObject*}{PyDict_Items}{PyObject *p} Returns a \ctype{PyListObject} containing all the items from the - dictionary, as in the dictinoary method \method{items()} (see the + dictionary, as in the dictionary method \method{items()} (see the \citetitle[../lib/lib.html]{Python Library Reference}). \end{cfuncdesc} From rhettinger at users.sourceforge.net Wed Sep 29 23:47:13 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed Sep 29 23:47:17 2004 Subject: [Python-checkins] python/dist/src/Python compile.c,2.328,2.329 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9236 Modified Files: compile.c Log Message: Fix two erroneous error messages. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.328 retrieving revision 2.329 diff -u -d -r2.328 -r2.329 --- compile.c 28 Sep 2004 17:22:12 -0000 2.328 +++ compile.c 29 Sep 2004 21:47:10 -0000 2.329 @@ -3203,13 +3203,13 @@ case testlist_gexp: if (NCH(n) > 1) { if (TYPE(CHILD(n, 1)) == gen_for) { - com_error(c, PyExc_SystemError, + com_error(c, PyExc_SyntaxError, "assign to generator expression not possible"); return; } if (assigning > OP_APPLY) { com_error(c, PyExc_SyntaxError, - "augmented assign to tuple not possible"); + "augmented assign to generator expression not possible"); return; } com_assign_sequence(c, n, assigning); From rhettinger at users.sourceforge.net Thu Sep 30 01:54:11 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 30 01:54:14 2004 Subject: [Python-checkins] python/dist/src/Python compile.c,2.329,2.330 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3685 Modified Files: compile.c Log Message: Improve error message for augmented assignments to genexps or listcomps. Rather than introduce new logic, took the approach of making the message itself more general. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.329 retrieving revision 2.330 diff -u -d -r2.329 -r2.330 --- compile.c 29 Sep 2004 21:47:10 -0000 2.329 +++ compile.c 29 Sep 2004 23:54:08 -0000 2.330 @@ -3274,7 +3274,7 @@ } if (assigning > OP_APPLY) { com_error(c, PyExc_SyntaxError, - "augmented assign to tuple literal not possible"); + "augmented assign to tuple literal or generator expression not possible"); return; } break; @@ -3287,7 +3287,7 @@ } if (assigning > OP_APPLY) { com_error(c, PyExc_SyntaxError, - "augmented assign to list literal not possible"); + "augmented assign to list literal or comprehension not possible"); return; } if (NCH(n) > 1 From rhettinger at users.sourceforge.net Thu Sep 30 02:59:11 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 30 02:59:14 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libfuncs.tex,1.174,1.175 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14800 Modified Files: libfuncs.tex Log Message: SF bug #1035279: hex() and oct() documentation is incorrect * Updated docs to reflected signed return values. * Fixed a doubled word typo. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.174 retrieving revision 1.175 diff -u -d -r1.174 -r1.175 --- libfuncs.tex 25 Aug 2004 10:42:39 -0000 1.174 +++ libfuncs.tex 30 Sep 2004 00:59:08 -0000 1.175 @@ -506,12 +506,8 @@ \begin{funcdesc}{hex}{x} Convert an integer number (of any size) to a hexadecimal string. - The result is a valid Python expression. Note: this always yields - an unsigned literal. For example, on a 32-bit machine, - \code{hex(-1)} yields \code{'0xffffffff'}. When evaluated on a - machine with the same word size, this literal is evaluated as -1; at - a different word size, it may turn up as a large positive number or - raise an \exception{OverflowError} exception. + The result is a valid Python expression. + \versionchanged[Formerly only returned an unsigned literal.]{2.4} \end{funcdesc} \begin{funcdesc}{id}{object} @@ -670,12 +666,8 @@ \begin{funcdesc}{oct}{x} Convert an integer number (of any size) to an octal string. The - result is a valid Python expression. Note: this always yields an - unsigned literal. For example, on a 32-bit machine, \code{oct(-1)} - yields \code{'037777777777'}. When evaluated on a machine with the - same word size, this literal is evaluated as -1; at a different word - size, it may turn up as a large positive number or raise an - \exception{OverflowError} exception. + result is a valid Python expression. + \versionchanged[Formerly only returned an unsigned literal.]{2.4} \end{funcdesc} \begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}} @@ -1111,7 +1103,7 @@ Implementations may impose restrictions to achieve this. The C implementation of Python restricts all arguments to native C longs ("short" Python integers), and also requires - that that number of elements fit in a native C long.} + that the number of elements fit in a native C long.} \end{funcdesc} \begin{funcdesc}{zip}{\optional{seq1, \moreargs}} From rhettinger at users.sourceforge.net Thu Sep 30 09:47:24 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 30 09:47:27 2004 Subject: [Python-checkins] python/dist/src/Lib/test list_tests.py, 1.4, 1.5 seq_tests.py, 1.2, 1.3 test_builtin.py, 1.35, 1.36 test_genexps.py, 1.5, 1.6 test_tuple.py, 1.4, 1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20201 Modified Files: list_tests.py seq_tests.py test_builtin.py test_genexps.py test_tuple.py Log Message: Improve test coverage. Index: list_tests.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/list_tests.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- list_tests.py 29 Sep 2004 08:03:17 -0000 1.4 +++ list_tests.py 30 Sep 2004 07:47:20 -0000 1.5 @@ -29,14 +29,6 @@ self.assertNotEqual(id(a), id(b)) self.assertEqual(a, b) - def test_mul(self): - for m in xrange(4): - s = tuple(range(m)) - for n in xrange(-3, 5): - self.assertEqual(self.type2test(s*n), self.type2test(s)*n) - self.assertEqual(self.type2test(s)*(-4), self.type2test([])) - self.assertEqual(id(s), id(s*1)) - def test_repr(self): l0 = [] l2 = [0, 1, 2] @@ -70,31 +62,6 @@ fo.close() os.remove(test_support.TESTFN) - def test_getitem(self): - a = self.type2test([10, 11]) - self.assertEqual(a[0], 10) - self.assertEqual(a[1], 11) - self.assertEqual(a[-2], 10) - self.assertEqual(a[-1], 11) - self.assertRaises(IndexError, a.__getitem__, -3) - self.assertRaises(IndexError, a.__getitem__, 3) - - def test_subscript(self): - a = self.type2test([10, 11]) - self.assertEqual(a.__getitem__(0L), 10) - self.assertEqual(a.__getitem__(1L), 11) - self.assertEqual(a.__getitem__(-2L), 10) - self.assertEqual(a.__getitem__(-1L), 11) - self.assertRaises(IndexError, a.__getitem__, -3) - self.assertRaises(IndexError, a.__getitem__, 3) - self.assertEqual(a.__getitem__(slice(0,1)), self.type2test([10])) - self.assertEqual(a.__getitem__(slice(1,2)), self.type2test([11])) - self.assertEqual(a.__getitem__(slice(0,2)), self.type2test([10, 11])) - self.assertEqual(a.__getitem__(slice(0,3)), self.type2test([10, 11])) - self.assertEqual(a.__getitem__(slice(3,5)), self.type2test([])) - self.assertRaises(ValueError, a.__getitem__, slice(0, 10, 0)) - self.assertRaises(TypeError, a.__getitem__, 'x') - def test_set_subscript(self): a = self.type2test(range(20)) self.assertRaises(ValueError, a.__setitem__, slice(0, 10, 0), [1,2,3]) Index: seq_tests.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/seq_tests.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- seq_tests.py 18 Jan 2004 21:03:23 -0000 1.2 +++ seq_tests.py 30 Sep 2004 07:47:20 -0000 1.3 @@ -48,10 +48,13 @@ u = self.type2test([0, 1, 2, 3, 4]) for i in xrange(len(u)): self.assertEqual(u[i], i) + self.assertEqual(u[long(i)], i) for i in xrange(-len(u), -1): self.assertEqual(u[i], len(u)+i) + self.assertEqual(u[long(i)], len(u)+i) self.assertRaises(IndexError, u.__getitem__, -len(u)-1) self.assertRaises(IndexError, u.__getitem__, len(u)) + self.assertRaises(ValueError, u.__getitem__, slice(0,10,0)) u = self.type2test() self.assertRaises(IndexError, u.__getitem__, 0) @@ -59,6 +62,14 @@ self.assertRaises(TypeError, u.__getitem__) + a = self.type2test([10, 11]) + self.assertEqual(a[0], 10) + self.assertEqual(a[1], 11) + self.assertEqual(a[-2], 10) + self.assertEqual(a[-1], 11) + self.assertRaises(IndexError, a.__getitem__, -3) + self.assertRaises(IndexError, a.__getitem__, 3) + def test_getslice(self): l = [0, 1, 2, 3, 4] u = self.type2test(l) @@ -169,3 +180,27 @@ def __getitem__(self, key): return str(key) + '!!!' self.assertEqual(iter(T((1,2))).next(), 1) + + def test_repeat(self): + for m in xrange(4): + s = tuple(range(m)) + for n in xrange(-3, 5): + self.assertEqual(self.type2test(s*n), self.type2test(s)*n) + self.assertEqual(self.type2test(s)*(-4), self.type2test([])) + self.assertEqual(id(s), id(s*1)) + + def test_subscript(self): + a = self.type2test([10, 11]) + self.assertEqual(a.__getitem__(0L), 10) + self.assertEqual(a.__getitem__(1L), 11) + self.assertEqual(a.__getitem__(-2L), 10) + self.assertEqual(a.__getitem__(-1L), 11) + self.assertRaises(IndexError, a.__getitem__, -3) + self.assertRaises(IndexError, a.__getitem__, 3) + self.assertEqual(a.__getitem__(slice(0,1)), self.type2test([10])) + self.assertEqual(a.__getitem__(slice(1,2)), self.type2test([11])) + self.assertEqual(a.__getitem__(slice(0,2)), self.type2test([10, 11])) + self.assertEqual(a.__getitem__(slice(0,3)), self.type2test([10, 11])) + self.assertEqual(a.__getitem__(slice(3,5)), self.type2test([])) + self.assertRaises(ValueError, a.__getitem__, slice(0, 10, 0)) + self.assertRaises(TypeError, a.__getitem__, 'x') Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.35 retrieving revision 1.36 diff -u -d -r1.35 -r1.36 --- test_builtin.py 26 Sep 2004 19:24:19 -0000 1.35 +++ test_builtin.py 30 Sep 2004 07:47:20 -0000 1.36 @@ -229,6 +229,9 @@ self.assertEqual(divmod(12L, -7), (-2L, -2)) self.assertEqual(divmod(-12L, -7), (1L, -5)) + self.assertEqual(divmod(-sys.maxint-1, -1), + (sys.maxint+1, 0)) + self.assert_(not fcmp(divmod(3.25, 1.0), (3.0, 0.25))) self.assert_(not fcmp(divmod(-3.25, 1.0), (-4.0, 0.75))) self.assert_(not fcmp(divmod(3.25, -1.0), (-4.0, -0.75))) Index: test_genexps.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_genexps.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- test_genexps.py 16 Aug 2004 01:45:34 -0000 1.5 +++ test_genexps.py 30 Sep 2004 07:47:20 -0000 1.6 @@ -121,7 +121,6 @@ 0 - ########### Tests borrowed from or inspired by test_generators.py ############ Make a generator that acts like range() Index: test_tuple.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_tuple.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- test_tuple.py 1 Jun 2004 18:58:04 -0000 1.4 +++ test_tuple.py 30 Sep 2004 07:47:20 -0000 1.5 @@ -65,6 +65,17 @@ collisions = len(inps) - len(set(map(hash, inps))) self.assert_(collisions <= 15) + def test_repr(self): + l0 = tuple() + l2 = (0, 1, 2) + a0 = self.type2test(l0) + a2 = self.type2test(l2) + + self.assertEqual(str(a0), repr(l0)) + self.assertEqual(str(a2), repr(l2)) + self.assertEqual(repr(a0), "()") + self.assertEqual(repr(a2), "(0, 1, 2)") + def test_main(): test_support.run_unittest(TupleTest) From doerwalter at users.sourceforge.net Thu Sep 30 15:46:02 2004 From: doerwalter at users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Thu Sep 30 15:46:05 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_dict.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32434/Lib/test Added Files: test_dict.py Log Message: Add missing test_dict.py from patch #736962. --- NEW FILE: test_dict.py --- import unittest from test import test_support import sys, UserDict, cStringIO class DictTest(unittest.TestCase): def test_constructor(self): # calling built-in types without argument must return empty self.assertEqual(dict(), {}) self.assert_(dict() is not {}) def test_bool(self): self.assert_(not {}) self.assert_({1: 2}) self.assert_(bool({}) is False) self.assert_(bool({1: 2}) is True) def test_keys(self): d = {} self.assertEqual(d.keys(), []) d = {'a': 1, 'b': 2} k = d.keys() self.assert_(d.has_key('a')) self.assert_(d.has_key('b')) self.assertRaises(TypeError, d.keys, None) def test_values(self): d = {} self.assertEqual(d.values(), []) d = {1:2} self.assertEqual(d.values(), [2]) self.assertRaises(TypeError, d.values, None) def test_items(self): d = {} self.assertEqual(d.items(), []) d = {1:2} self.assertEqual(d.items(), [(1, 2)]) self.assertRaises(TypeError, d.items, None) def test_has_key(self): d = {} self.assert_(not d.has_key('a')) d = {'a': 1, 'b': 2} k = d.keys() k.sort() self.assertEqual(k, ['a', 'b']) self.assertRaises(TypeError, d.has_key) def test_contains(self): d = {} self.assert_(not ('a' in d)) self.assert_('a' not in d) d = {'a': 1, 'b': 2} self.assert_('a' in d) self.assert_('b' in d) self.assert_('c' not in d) self.assertRaises(TypeError, d.__contains__) def test_len(self): d = {} self.assertEqual(len(d), 0) d = {'a': 1, 'b': 2} self.assertEqual(len(d), 2) def test_getitem(self): d = {'a': 1, 'b': 2} self.assertEqual(d['a'], 1) self.assertEqual(d['b'], 2) d['c'] = 3 d['a'] = 4 self.assertEqual(d['c'], 3) self.assertEqual(d['a'], 4) del d['b'] self.assertEqual(d, {'a': 4, 'c': 3}) self.assertRaises(TypeError, d.__getitem__) class BadEq(object): def __eq__(self, other): raise Exc() d = {} d[BadEq()] = 42 self.assertRaises(KeyError, d.__getitem__, 23) class Exc(Exception): pass class BadHash(object): fail = False def __hash__(self): if self.fail: raise Exc() else: return 42 x = BadHash() d[x] = 42 x.fail = True self.assertRaises(Exc, d.__getitem__, x) def test_clear(self): d = {1:1, 2:2, 3:3} d.clear() self.assertEqual(d, {}) self.assertRaises(TypeError, d.clear, None) def test_update(self): d = {} d.update({1:100}) d.update({2:20}) d.update({1:1, 2:2, 3:3}) self.assertEqual(d, {1:1, 2:2, 3:3}) d.update() self.assertEqual(d, {1:1, 2:2, 3:3}) self.assertRaises((TypeError, AttributeError), d.update, None) class SimpleUserDict: def __init__(self): self.d = {1:1, 2:2, 3:3} def keys(self): return self.d.keys() def __getitem__(self, i): return self.d[i] d.clear() d.update(SimpleUserDict()) self.assertEqual(d, {1:1, 2:2, 3:3}) class Exc(Exception): pass d.clear() class FailingUserDict: def keys(self): raise Exc self.assertRaises(Exc, d.update, FailingUserDict()) class FailingUserDict: def keys(self): class BogonIter: def __init__(self): self.i = 1 def __iter__(self): return self def next(self): if self.i: self.i = 0 return 'a' raise Exc return BogonIter() def __getitem__(self, key): return key self.assertRaises(Exc, d.update, FailingUserDict()) class FailingUserDict: def keys(self): class BogonIter: def __init__(self): self.i = ord('a') def __iter__(self): return self def next(self): if self.i <= ord('z'): rtn = chr(self.i) self.i += 1 return rtn raise StopIteration return BogonIter() def __getitem__(self, key): raise Exc self.assertRaises(Exc, d.update, FailingUserDict()) class badseq(object): def __iter__(self): return self def next(self): raise Exc() self.assertRaises(Exc, {}.update, badseq()) self.assertRaises(ValueError, {}.update, [(1, 2, 3)]) def test_fromkeys(self): self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) d = {} self.assert_(not(d.fromkeys('abc') is d)) self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0}) self.assertEqual(d.fromkeys([]), {}) def g(): yield 1 self.assertEqual(d.fromkeys(g()), {1:None}) self.assertRaises(TypeError, {}.fromkeys, 3) class dictlike(dict): pass self.assertEqual(dictlike.fromkeys('a'), {'a':None}) self.assertEqual(dictlike().fromkeys('a'), {'a':None}) self.assert_(type(dictlike.fromkeys('a')) is dictlike) self.assert_(type(dictlike().fromkeys('a')) is dictlike) class mydict(dict): def __new__(cls): return UserDict.UserDict() ud = mydict.fromkeys('ab') self.assertEqual(ud, {'a':None, 'b':None}) self.assert_(isinstance(ud, UserDict.UserDict)) self.assertRaises(TypeError, dict.fromkeys) class Exc(Exception): pass class baddict1(dict): def __init__(self): raise Exc() self.assertRaises(Exc, baddict1.fromkeys, [1]) class BadSeq(object): def __iter__(self): return self def next(self): raise Exc() self.assertRaises(Exc, dict.fromkeys, BadSeq()) class baddict2(dict): def __setitem__(self, key, value): raise Exc() self.assertRaises(Exc, baddict2.fromkeys, [1]) def test_copy(self): d = {1:1, 2:2, 3:3} self.assertEqual(d.copy(), {1:1, 2:2, 3:3}) self.assertEqual({}.copy(), {}) self.assertRaises(TypeError, d.copy, None) def test_get(self): d = {} self.assert_(d.get('c') is None) self.assertEqual(d.get('c', 3), 3) d = {'a' : 1, 'b' : 2} self.assert_(d.get('c') is None) self.assertEqual(d.get('c', 3), 3) self.assertEqual(d.get('a'), 1) self.assertEqual(d.get('a', 3), 1) self.assertRaises(TypeError, d.get) self.assertRaises(TypeError, d.get, None, None, None) def test_setdefault(self): # dict.setdefault() d = {} self.assert_(d.setdefault('key0') is None) d.setdefault('key0', []) self.assert_(d.setdefault('key0') is None) d.setdefault('key', []).append(3) self.assertEqual(d['key'][0], 3) d.setdefault('key', []).append(4) self.assertEqual(len(d['key']), 2) self.assertRaises(TypeError, d.setdefault) class Exc(Exception): pass class BadHash(object): fail = False def __hash__(self): if self.fail: raise Exc() else: return 42 x = BadHash() d[x] = 42 x.fail = True self.assertRaises(Exc, d.setdefault, x, []) def test_popitem(self): # dict.popitem() for copymode in -1, +1: # -1: b has same structure as a # +1: b is a.copy() for log2size in range(12): size = 2**log2size a = {} b = {} for i in range(size): a[repr(i)] = i if copymode < 0: b[repr(i)] = i if copymode > 0: b = a.copy() for i in range(size): ka, va = ta = a.popitem() self.assertEqual(va, int(ka)) kb, vb = tb = b.popitem() self.assertEqual(vb, int(kb)) self.assert_(not(copymode < 0 and ta != tb)) self.assert_(not a) self.assert_(not b) d = {} self.assertRaises(KeyError, d.popitem) def test_pop(self): # Tests for pop with specified key d = {} k, v = 'abc', 'def' d[k] = v self.assertRaises(KeyError, d.pop, 'ghi') self.assertEqual(d.pop(k), v) self.assertEqual(len(d), 0) self.assertRaises(KeyError, d.pop, k) # verify longs/ints get same value when key > 32 bits (for 64-bit archs) # see SF bug #689659 x = 4503599627370496L y = 4503599627370496 h = {x: 'anything', y: 'something else'} self.assertEqual(h[x], h[y]) self.assertEqual(d.pop(k, v), v) d[k] = v self.assertEqual(d.pop(k, 1), v) self.assertRaises(TypeError, d.pop) class Exc(Exception): pass class BadHash(object): fail = False def __hash__(self): if self.fail: raise Exc() else: return 42 x = BadHash() d[x] = 42 x.fail = True self.assertRaises(Exc, d.pop, x) def test_mutatingiteration(self): d = {} d[1] = 1 try: for i in d: d[i+1] = 1 except RuntimeError: pass else: self.fail("changing dict size during iteration doesn't raise Error") def test_repr(self): d = {} self.assertEqual(repr(d), '{}') d[1] = 2 self.assertEqual(repr(d), '{1: 2}') d = {} d[1] = d self.assertEqual(repr(d), '{1: {...}}') class Exc(Exception): pass class BadRepr(object): def __repr__(self): raise Exc() d = {1: BadRepr()} self.assertRaises(Exc, repr, d) def test_le(self): self.assert_(not ({} < {})) self.assert_(not ({1: 2} < {1L: 2L})) class Exc(Exception): pass class BadCmp(object): def __eq__(self, other): raise Exc() d1 = {BadCmp(): 1} d2 = {1: 1} try: d1 < d2 except Exc: pass else: self.fail("< didn't raise Exc") def test_main(): test_support.run_unittest( DictTest, ) if __name__ == "__main__": test_main() From rhettinger at users.sourceforge.net Thu Sep 30 17:07:32 2004 From: rhettinger at users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu Sep 30 17:07:35 2004 Subject: [Python-checkins] python/dist/src/Lib/test test_dict.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16023 Modified Files: test_dict.py Log Message: Expand scope to include general mapping protocol tests. Many of these tests are redundant, but this will ensure that the mapping protocols all stay in sync. Also, added a test for dictionary subclasses. Index: test_dict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_dict.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- test_dict.py 30 Sep 2004 13:46:00 -0000 1.1 +++ test_dict.py 30 Sep 2004 15:07:29 -0000 1.2 @@ -395,9 +395,22 @@ else: self.fail("< didn't raise Exc") +import mapping_tests + +class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): + type2test = dict + +class Dict(dict): + pass + +class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): + type2test = Dict + def test_main(): test_support.run_unittest( DictTest, + GeneralMappingTests, + SubclassMappingTests, ) if __name__ == "__main__": From edloper at users.sourceforge.net Thu Sep 30 19:18:21 2004 From: edloper at users.sourceforge.net (edloper@users.sourceforge.net) Date: Thu Sep 30 19:18:23 2004 Subject: [Python-checkins] python/dist/src/Doc/lib libdoctest.tex,1.63,1.64 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10177/dist/src/Doc/lib Modified Files: libdoctest.tex Log Message: Added 2 notes about the complexities of testing SyntaxErrors. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.63 retrieving revision 1.64 diff -u -d -r1.63 -r1.64 --- libdoctest.tex 28 Sep 2004 05:50:57 -0000 1.63 +++ libdoctest.tex 30 Sep 2004 17:18:18 -0000 1.64 @@ -495,6 +495,37 @@ \item When the \constant{IGNORE_EXCEPTION_DETAIL} doctest option is is specified, everything following the leftmost colon is ignored. +\item The interactive shell omits the traceback header line for some + \exception{SyntaxError}s. But doctest uses the traceback header + line to distinguish exceptions from non-exceptions. So in the rare + case where you need to test a \exception{SyntaxError} that omits the + traceback header, you will need to manually add the traceback header + line to your test example. + +\item For some \exception{SyntaxError}s, Python displays the character + position of the syntax error, using a \code{\^} marker: + +\begin{verbatim} +>>> 1 1 + File "", line 1 + 1 1 + ^ +SyntaxError: invalid syntax +\end{verbatim} + + Since the lines showing the position of the error come before the + exception type and detail, they are not checked by doctest. For + example, the following test would pass, even though it puts the + \code{\^} marker in the wrong location: + +\begin{verbatim} +>>> 1 1 + File "", line 1 + 1 1 + ^ +SyntaxError: invalid syntax +\end{verbatim} + \end{itemize} \versionchanged[The ability to handle a multi-line exception detail,