From tim_one@users.sourceforge.net Wed Jan 1 02:14:14 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:14:14 -0800 Subject: [Python-checkins] python/dist/src/PCbuild python20.wse,1.112,1.113 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv17868/PCbuild Modified Files: python20.wse Log Message: Merging in changes from r23a1-branch. Doc/makefile had conflicts, which I leave to Fred to sort out. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.112 retrieving revision 1.113 diff -C2 -d -r1.112 -r1.113 *** python20.wse 16 Dec 2002 20:18:27 -0000 1.112 --- python20.wse 1 Jan 2003 02:14:12 -0000 1.113 *************** *** 1974,1977 **** --- 1974,1983 ---- Flags=0000000000000010 end + item: Install File + Source=..\lib\email\test\data\*.au + Destination=%MAINDIR%\Lib\email\test\data + Description=email test data + Flags=0000000000000010 + end item: Remark end From tim_one@users.sourceforge.net Wed Jan 1 02:14:14 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:14:14 -0800 Subject: [Python-checkins] python/dist/src/Doc/texinputs boilerplate.tex,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory sc8-pr-cvs1:/tmp/cvs-serv17868/Doc/texinputs Modified Files: boilerplate.tex Log Message: Merging in changes from r23a1-branch. Doc/makefile had conflicts, which I leave to Fred to sort out. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** boilerplate.tex 31 Dec 2002 20:25:56 -0000 1.74 --- boilerplate.tex 1 Jan 2003 02:14:11 -0000 1.75 *************** *** 6,10 **** } ! \date{\today} % XXX update before release! \release{2.3} % software release, not documentation \setreleaseinfo{a1+} % empty for final release --- 6,10 ---- } ! \date{December 31, 2002} % XXX update before release! \release{2.3} % software release, not documentation \setreleaseinfo{a1+} % empty for final release From goodger@users.sourceforge.net Wed Jan 1 02:32:22 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:32:22 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/readers/python - New directory Message-ID: Update of /cvsroot/python/python/nondist/peps/docutils/readers/python In directory sc8-pr-cvs1:/tmp/cvs-serv28070/readers/python Log Message: Directory /cvsroot/python/python/nondist/peps/docutils/readers/python added to the repository From goodger@users.sourceforge.net Wed Jan 1 02:36:01 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:01 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/parsers .cvsignore,1.1,NONE Message-ID: Update of /cvsroot/python/python/nondist/peps/docutils/parsers In directory sc8-pr-cvs1:/tmp/cvs-serv30174/parsers Removed Files: .cvsignore Log Message: update from latest Docutils code --- .cvsignore DELETED --- From goodger@users.sourceforge.net Wed Jan 1 02:36:02 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:02 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/parsers/rst/languages it.py,NONE,1.1 .cvsignore,1.1,NONE Message-ID: Update of /cvsroot/python/python/nondist/peps/docutils/parsers/rst/languages In directory sc8-pr-cvs1:/tmp/cvs-serv30174/parsers/rst/languages Added Files: it.py Removed Files: .cvsignore Log Message: update from latest Docutils code --- NEW FILE: it.py --- # Author: Nicola Larosa # Contact: docutils@tekNico.net # Revision: $Revision: 1.1 $ # Date: $Date: 2003/01/01 02:36:00 $ # Copyright: This module has been placed in the public domain. """ Italian-language mappings for language-dependent features of reStructuredText. """ __docformat__ = 'reStructuredText' directives = { 'attenzione': 'attention', 'cautela': 'caution', 'pericolo': 'danger', 'errore': 'error', 'suggerimento': 'hint', 'importante': 'important', 'nota': 'note', 'consiglio': 'tip', 'avvertenza': 'warning', 'argomento': 'topic', 'blocco di linee': 'line-block', 'parsed-literal': 'parsed-literal', #'questions': 'questions', #'qa': 'questions', #'faq': 'questions', 'meta': 'meta', #'imagemap': 'imagemap', 'immagine': 'image', 'figura': 'figure', 'includi': 'include', 'grezzo': 'raw', 'sostituisci': 'replace', 'indice': 'contents', 'seznum': 'sectnum', 'section-numbering': 'sectnum', 'target-notes': 'target-notes', #'footnotes': 'footnotes', #'citations': 'citations', 'restructuredtext-test-directive': 'restructuredtext-test-directive'} """English name to registered (in directives/__init__.py) directive name mapping.""" --- .cvsignore DELETED --- From goodger@users.sourceforge.net Wed Jan 1 02:36:02 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:02 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/readers __init__.py,1.1,1.2 pep.py,1.1,1.2 .cvsignore,1.1,NONE Message-ID: Update of /cvsroot/python/python/nondist/peps/docutils/readers In directory sc8-pr-cvs1:/tmp/cvs-serv30174/readers Modified Files: __init__.py pep.py Removed Files: .cvsignore Log Message: update from latest Docutils code Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/readers/__init__.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** __init__.py 8 Nov 2002 23:47:52 -0000 1.1 --- __init__.py 1 Jan 2003 02:36:00 -0000 1.2 *************** *** 62,67 **** self.parser = parser self.settings = settings ! # May modify self.parser, depending on input: ! self.input = self.source.read(self) self.parse() return self.document --- 62,66 ---- self.parser = parser self.settings = settings ! self.input = self.source.read() self.parse() return self.document Index: pep.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/readers/pep.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep.py 8 Nov 2002 23:47:52 -0000 1.1 --- pep.py 1 Jan 2003 02:36:00 -0000 1.2 *************** *** 21,24 **** --- 21,33 ---- + class Inliner(rst.states.Inliner): + + """ + Extend `rst.Inliner` to for local PEP references. + """ + + pep_url = rst.states.Inliner.pep_url_local + + class Reader(standalone.Reader): *************** *** 45,60 **** settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} def __init__(self, parser=None, parser_name=None): """`parser` should be ``None``.""" if parser is None: ! parser = rst.Parser(rfc2822=1, inliner=Inliner()) standalone.Reader.__init__(self, parser, '') - - - class Inliner(rst.states.Inliner): - - """ - Extend `rst.Inliner` to for local PEP references. - """ - - pep_url = rst.states.Inliner.pep_url_local --- 54,62 ---- settings_default_overrides = {'pep_references': 1, 'rfc_references': 1} + inliner_class = Inliner + def __init__(self, parser=None, parser_name=None): """`parser` should be ``None``.""" if parser is None: ! parser = rst.Parser(rfc2822=1, inliner=self.inliner_class()) standalone.Reader.__init__(self, parser, '') --- .cvsignore DELETED --- From goodger@users.sourceforge.net Wed Jan 1 02:36:00 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:00 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/languages it.py,NONE,1.1 .cvsignore,1.1,NONE Message-ID: Update of /cvsroot/python/python/nondist/peps/docutils/languages In directory sc8-pr-cvs1:/tmp/cvs-serv30174/languages Added Files: it.py Removed Files: .cvsignore Log Message: update from latest Docutils code --- NEW FILE: it.py --- # Author: Nicola Larosa # Contact: docutils@tekNico.net # Revision: $Revision: 1.1 $ # Date: $Date: 2003/01/01 02:35:58 $ # Copyright: This module has been placed in the public domain. """ Italian-language mappings for language-dependent features of Docutils. """ __docformat__ = 'reStructuredText' from docutils import nodes labels = { 'author': 'Autore', 'authors': 'Autori', 'organization': 'Organizzazione', 'address': 'Indirizzo', 'contact': 'Contatti', 'version': 'Versione', 'revision': 'Revisione', 'status': 'Status', 'date': 'Data', 'copyright': 'Copyright', 'dedication': 'Dedica', 'abstract': 'Riassunto', 'attention': 'Attenzione!', 'caution': 'Cautela!', 'danger': '!PERICOLO!', 'error': 'Errore', 'hint': 'Suggerimento', 'important': 'Importante', 'note': 'Nota', 'tip': 'Consiglio', 'warning': 'Avvertenza', 'contents': 'Indice'} """Mapping of node class name to label text.""" bibliographic_fields = { 'autore': nodes.author, 'autori': nodes.authors, 'organizzazione': nodes.organization, 'indirizzo': nodes.address, 'contatti': nodes.contact, 'versione': nodes.version, 'revisione': nodes.revision, 'status': nodes.status, 'data': nodes.date, 'copyright': nodes.copyright, 'dedica': nodes.topic, 'riassunto': nodes.topic} """Field name (lowcased) to node class name mapping for bibliographic fields (field_list).""" author_separators = [';', ','] """List of separator strings for the 'Authors' bibliographic field. Tried in order.""" --- .cvsignore DELETED --- From goodger@users.sourceforge.net Wed Jan 1 02:36:03 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:03 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/transforms misc.py,NONE,1.1 peps.py,1.2,1.3 .cvsignore,1.1,NONE Message-ID: Update of /cvsroot/python/python/nondist/peps/docutils/transforms In directory sc8-pr-cvs1:/tmp/cvs-serv30174/transforms Modified Files: peps.py Added Files: misc.py Removed Files: .cvsignore Log Message: update from latest Docutils code --- NEW FILE: misc.py --- # Author: David Goodger # Contact: goodger@users.sourceforge.net # Revision: $Revision: 1.1 $ # Date: $Date: 2003/01/01 02:36:01 $ # Copyright: This module has been placed in the public domain. """ Miscellaneous transforms. """ __docformat__ = 'reStructuredText' from docutils.transforms import Transform, TransformError class CallBack(Transform): """ Inserts a callback into a document. The callback is called when the transform is applied, which is determined by its priority. For use with `nodes.pending` elements. Requires a ``details['callback']`` entry, a bound method or function which takes one parameter: the pending node. Other data can be stored in the ``details`` attribute or in the object hosting the callback method. """ default_priority = 990 def apply(self): pending = self.startnode pending.details['callback'](pending) pending.parent.remove(pending) Index: peps.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/transforms/peps.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** peps.py 17 Nov 2002 00:09:20 -0000 1.2 --- peps.py 1 Jan 2003 02:36:01 -0000 1.3 *************** *** 23,27 **** from docutils import ApplicationError, DataError from docutils.transforms import Transform, TransformError ! from docutils.transforms import parts, references --- 23,27 ---- from docutils import ApplicationError, DataError from docutils.transforms import Transform, TransformError ! from docutils.transforms import parts, references, misc *************** *** 43,46 **** --- 43,47 ---- def apply(self): if not len(self.document): + # @@@ replace these DataErrors with proper system messages raise DataError('Document tree is empty.') header = self.document[0] *************** *** 49,53 **** raise DataError('Document does not begin with an RFC-2822 ' 'header; it is not a PEP.') ! pep = title = None for field in header: if field[0].astext().lower() == 'pep': # should be the first field --- 50,54 ---- raise DataError('Document does not begin with an RFC-2822 ' 'header; it is not a PEP.') ! pep = None for field in header: if field[0].astext().lower() == 'pep': # should be the first field *************** *** 80,83 **** --- 81,86 ---- self.document.insert(1, pending) self.document.note_pending(pending) + if len(header) < 2 or header[1][0].astext().lower() != 'title': + raise DataError('No title!') for field in header: name = field[0].astext().lower() *************** *** 151,155 **** """ Locate the "References" section, insert a placeholder for an external ! target footnote insertion transform at the end, and run the transform. """ --- 154,159 ---- """ Locate the "References" section, insert a placeholder for an external ! target footnote insertion transform at the end, and schedule the ! transform to run immediately. """ *************** *** 181,184 **** --- 185,201 ---- refsect.append(pending) self.document.note_pending(pending, 0) + pending = nodes.pending(misc.CallBack, + details={'callback': self.cleanup_callback}) + refsect.append(pending) + self.document.note_pending(pending, 1) + + def cleanup_callback(self, pending): + """ + Remove an empty "References" section. + + Called after the `references.TargetNotes` transform is complete. + """ + if len(pending.parent) == 2: # and <pending> + pending.parent.parent.remove(pending.parent) --- .cvsignore DELETED --- From goodger@users.sourceforge.net Wed Jan 1 02:36:04 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:04 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/writers docutils_xml.py,1.1,1.2 html4css1.py,1.2,1.3 .cvsignore,1.1,NONE Message-ID: <E18TYjk-0007sb-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils/writers In directory sc8-pr-cvs1:/tmp/cvs-serv30174/writers Modified Files: docutils_xml.py html4css1.py Removed Files: .cvsignore Log Message: update from latest Docutils code Index: docutils_xml.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/writers/docutils_xml.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** docutils_xml.py 8 Nov 2002 23:47:53 -0000 1.1 --- docutils_xml.py 1 Jan 2003 02:36:01 -0000 1.2 *************** *** 23,32 **** settings_spec = ( '"Docutils XML" Writer Options', ! 'Warning: these options may adversely affect whitespace; use them ' ! 'only for reading convenience.', (('Generate XML with newlines before and after tags.', ['--newlines'], {'action': 'store_true'}), ('Generate XML with indents and newlines.', ! ['--indents'], {'action': 'store_true'}),),) output = None --- 23,38 ---- settings_spec = ( '"Docutils XML" Writer Options', ! 'Warning: the --newlines and --indents options may adversely affect ' ! 'whitespace; use them only for reading convenience.', (('Generate XML with newlines before and after tags.', ['--newlines'], {'action': 'store_true'}), ('Generate XML with indents and newlines.', ! ['--indents'], {'action': 'store_true'}), ! ('Omit the XML declaration. Use with caution.', ! ['--no-xml-declaration'], {'dest': 'xml_declaration', 'default': 1, ! 'action': 'store_false'}), ! ('Omit the DOCTYPE declaration.', ! ['--no-doctype'], {'dest': 'doctype_declaration', 'default': 1, ! 'action': 'store_false'}),)) output = None *************** *** 49,55 **** newline = '\n' indent = ' ' ! output_prefix = [self.xml_declaration % settings.output_encoding, ! self.doctype, ! self.generator % docutils.__version__] docnode = self.document.asdom().childNodes[0] self.output = (''.join(output_prefix) --- 55,65 ---- newline = '\n' indent = ' ' ! output_prefix = [] ! if settings.xml_declaration: ! output_prefix.append( ! self.xml_declaration % settings.output_encoding) ! if settings.doctype_declaration: ! output_prefix.append(self.doctype) ! output_prefix.append(self.generator % docutils.__version__) docnode = self.document.asdom().childNodes[0] self.output = (''.join(output_prefix) Index: html4css1.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/writers/html4css1.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** html4css1.py 17 Nov 2002 00:09:20 -0000 1.2 --- html4css1.py 1 Jan 2003 02:36:01 -0000 1.3 *************** *** 126,133 **** are allowed a label first). ! - Regardless of the above, in definitions, table cells, field ! bodies, option descriptions, and list items, mark the first ! child with 'class="first"' if it is a paragraph. The stylesheet ! sets the top margin to 0 for these paragraphs. The ``no_compact_lists`` setting (``--no-compact-lists`` command-line --- 126,133 ---- are allowed a label first). ! - Regardless of the above, in definitions, table cells, field bodies, ! option descriptions, and list items, mark the first child with ! 'class="first"' and the last child with 'class="last"'. The stylesheet ! sets the margins (top & bottom respecively) to 0 for these elements. The ``no_compact_lists`` setting (``--no-compact-lists`` command-line *************** *** 781,785 **** def visit_meta(self, node): ! self.head.append(self.starttag(node, 'meta', **node.attributes)) def depart_meta(self, node): --- 781,785 ---- def visit_meta(self, node): ! self.head.append(self.emptytag(node, 'meta', **node.attributes)) def depart_meta(self, node): --- .cvsignore DELETED --- From goodger@users.sourceforge.net Wed Jan 1 02:36:03 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:03 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/readers/python __init__.py,NONE,1.1 moduleparser.py,NONE,1.1 Message-ID: <E18TYjj-0007sN-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils/readers/python In directory sc8-pr-cvs1:/tmp/cvs-serv30174/readers/python Added Files: __init__.py moduleparser.py Log Message: update from latest Docutils code --- NEW FILE: __init__.py --- # Author: David Goodger # Contact: goodger@users.sourceforge.net # Revision: $Revision: 1.1 $ # Date: $Date: 2003/01/01 02:36:00 $ # Copyright: This module has been placed in the public domain. """ This package contains the Python Source Reader modules. """ __docformat__ = 'reStructuredText' import sys import docutils.readers class Reader(docutils.readers.Reader): pass --- NEW FILE: moduleparser.py --- # Author: David Goodger # Contact: goodger@users.sourceforge.net # Revision: $Revision: 1.1 $ # Date: $Date: 2003/01/01 02:36:00 $ # Copyright: This module has been placed in the public domain. """ Parser for Python modules. The `parse_module()` function takes a module's text and file name, runs it through the module parser (using compiler.py and tokenize.py) and produces a "module documentation tree": a high-level AST full of nodes that are interesting from an auto-documentation standpoint. For example, given this module (x.py):: # comment '''Docstring''' '''Additional docstring''' __docformat__ = 'reStructuredText' a = 1 '''Attribute docstring''' class C(Super): '''C's docstring''' class_attribute = 1 '''class_attribute's docstring''' def __init__(self, text=None): '''__init__'s docstring''' self.instance_attribute = (text * 7 + ' whaddyaknow') '''instance_attribute's docstring''' def f(x, # parameter x y=a*5, # parameter y *args): # parameter args '''f's docstring''' return [x + item for item in args] f.function_attribute = 1 '''f.function_attribute's docstring''' The module parser will produce this module documentation tree:: <Module filename="test data"> <Comment lineno=1> comment <Docstring> Docstring <Docstring lineno="5"> Additional docstring <Attribute lineno="7" name="__docformat__"> <Expression lineno="7"> 'reStructuredText' <Attribute lineno="9" name="a"> <Expression lineno="9"> 1 <Docstring lineno="10"> Attribute docstring <Class bases="Super" lineno="12" name="C"> <Docstring lineno="12"> C's docstring <Attribute lineno="16" name="class_attribute"> <Expression lineno="16"> 1 <Docstring lineno="17"> class_attribute's docstring <Method lineno="19" name="__init__"> <Docstring lineno="19"> __init__'s docstring <ParameterList lineno="19"> <Parameter lineno="19" name="self"> <Parameter lineno="19" name="text"> <Default lineno="19"> None <Attribute lineno="22" name="self.instance_attribute"> <Expression lineno="22"> (text * 7 + ' whaddyaknow') <Docstring lineno="24"> instance_attribute's docstring <Function lineno="27" name="f"> <Docstring lineno="27"> f's docstring <ParameterList lineno="27"> <Parameter lineno="27" name="x"> <Comment> # parameter x <Parameter lineno="27" name="y"> <Default lineno="27"> a * 5 <Comment> # parameter y <ExcessPositionalArguments lineno="27" name="args"> <Comment> # parameter args <Attribute lineno="33" name="f.function_attribute"> <Expression lineno="33"> 1 <Docstring lineno="34"> f.function_attribute's docstring (Comments are not implemented yet.) compiler.parse() provides most of what's needed for this doctree, and "tokenize" can be used to get the rest. We can determine the line number from the compiler.parse() AST, and the TokenParser.rhs(lineno) method provides the rest. The Docutils Python reader component will transform this module doctree into a Python-specific Docutils doctree, and then a `stylist transform`_ will further transform it into a generic doctree. Namespaces will have to be compiled for each of the scopes, but I'm not certain at what stage of processing. It's very important to keep all docstring processing out of this, so that it's a completely generic and not tool-specific. > Why perform all of those transformations? Why not go from the AST to a > generic doctree? Or, even from the AST to the final output? I want the docutils.readers.python.moduleparser.parse_module() function to produce a standard documentation-oriented tree that can be used by any tool. We can develop it together without having to compromise on the rest of our design (i.e., HappyDoc doesn't have to be made to work like Docutils, and vice-versa). It would be a higher-level version of what compiler.py provides. The Python reader component transforms this generic AST into a Python-specific doctree (it knows about modules, classes, functions, etc.), but this is specific to Docutils and cannot be used by HappyDoc or others. The stylist transform does the final layout, converting Python-specific structures ("class" sections, etc.) into a generic doctree using primitives (tables, sections, lists, etc.). This generic doctree does *not* know about Python structures any more. The advantage is that this doctree can be handed off to any of the output writers to create any output format we like. The latter two transforms are separate because I want to be able to have multiple independent layout styles (multiple runtime-selectable "stylist transforms"). Each of the existing tools (HappyDoc, pydoc, epydoc, Crystal, etc.) has its own fixed format. I personally don't like the tables-based format produced by these tools, and I'd like to be able to customize the format easily. That's the goal of stylist transforms, which are independent from the Reader component itself. One stylist transform could produce HappyDoc-like output, another could produce output similar to module docs in the Python library reference manual, and so on. It's for exactly this reason: >> It's very important to keep all docstring processing out of this, so that >> it's a completely generic and not tool-specific. ... but it goes past docstring processing. It's also important to keep style decisions and tool-specific data transforms out of this module parser. Issues ====== * At what point should namespaces be computed? Should they be part of the basic AST produced by the ASTVisitor walk, or generated by another tree traversal? * At what point should a distinction be made between local variables & instance attributes in __init__ methods? * Docstrings are getting their lineno from their parents. Should the TokenParser find the real line no's? * Comments: include them? How and when? Only full-line comments, or parameter comments too? (See function "f" above for an example.) * Module could use more docstrings & refactoring in places. """ __docformat__ = 'reStructuredText' import sys import compiler import compiler.ast import tokenize import token from compiler.consts import OP_ASSIGN from compiler.visitor import ASTVisitor from types import StringType, UnicodeType, TupleType def parse_module(module_text, filename): """Return a module documentation tree from `module_text`.""" ast = compiler.parse(module_text) token_parser = TokenParser(module_text) visitor = ModuleVisitor(filename, token_parser) compiler.walk(ast, visitor, walker=visitor) return visitor.module class Node: def __init__(self, node): self.children = [] """List of child nodes.""" self.lineno = node.lineno """Line number of this node (or ``None``).""" def __str__(self, indent=' ', level=0): return ''.join(['%s%s\n' % (indent * level, repr(self))] + [child.__str__(indent, level+1) for child in self.children]) def __repr__(self): parts = [self.__class__.__name__] for name, value in self.attlist(): parts.append('%s="%s"' % (name, value)) return '<%s>' % ' '.join(parts) def attlist(self, **atts): if self.lineno is not None: atts['lineno'] = self.lineno attlist = atts.items() attlist.sort() return attlist def append(self, node): self.children.append(node) def extend(self, node_list): self.children.extend(node_list) class TextNode(Node): def __init__(self, node, text): Node.__init__(self, node) self.text = trim_docstring(text) def __str__(self, indent=' ', level=0): prefix = indent * (level + 1) text = '\n'.join([prefix + line for line in self.text.splitlines()]) return Node.__str__(self, indent, level) + text + '\n' class Module(Node): def __init__(self, node, filename): Node.__init__(self, node) self.filename = filename def attlist(self): return Node.attlist(self, filename=self.filename) class Docstring(TextNode): pass class Comment(TextNode): pass class Import(Node): def __init__(self, node, names, from_name=None): Node.__init__(self, node) self.names = names self.from_name = from_name def __str__(self, indent=' ', level=0): prefix = indent * (level + 1) lines = [] for name, as in self.names: if as: lines.append('%s%s as %s' % (prefix, name, as)) else: lines.append('%s%s' % (prefix, name)) text = '\n'.join(lines) return Node.__str__(self, indent, level) + text + '\n' def attlist(self): if self.from_name: atts = {'from': self.from_name} else: atts = {} return Node.attlist(self, **atts) class Attribute(Node): def __init__(self, node, name): Node.__init__(self, node) self.name = name def attlist(self): return Node.attlist(self, name=self.name) class AttributeTuple(Node): def __init__(self, node, names): Node.__init__(self, node) self.names = names def attlist(self): return Node.attlist(self, names=' '.join(self.names)) class Expression(TextNode): def __str__(self, indent=' ', level=0): prefix = indent * (level + 1) return '%s%s%s\n' % (Node.__str__(self, indent, level), prefix, self.text.encode('unicode-escape')) class Function(Attribute): pass class ParameterList(Node): pass class Parameter(Attribute): pass class ParameterTuple(AttributeTuple): def attlist(self): return Node.attlist(self, names=normalize_parameter_name(self.names)) class ExcessPositionalArguments(Parameter): pass class ExcessKeywordArguments(Parameter): pass class Default(Expression): pass class Class(Node): def __init__(self, node, name, bases=None): Node.__init__(self, node) self.name = name self.bases = bases or [] def attlist(self): atts = {'name': self.name} if self.bases: atts['bases'] = ' '.join(self.bases) return Node.attlist(self, **atts) class Method(Function): pass class BaseVisitor(ASTVisitor): def __init__(self, token_parser): ASTVisitor.__init__(self) self.token_parser = token_parser self.context = [] self.documentable = None def default(self, node, *args): self.documentable = None #print 'in default (%s)' % node.__class__.__name__ #ASTVisitor.default(self, node, *args) def default_visit(self, node, *args): #print 'in default_visit (%s)' % node.__class__.__name__ ASTVisitor.default(self, node, *args) class DocstringVisitor(BaseVisitor): def visitDiscard(self, node): if self.documentable: self.visit(node.expr) def visitConst(self, node): if self.documentable: if type(node.value) in (StringType, UnicodeType): self.documentable.append(Docstring(node, node.value)) else: self.documentable = None def visitStmt(self, node): self.default_visit(node) class AssignmentVisitor(DocstringVisitor): def visitAssign(self, node): visitor = AttributeVisitor(self.token_parser) compiler.walk(node, visitor, walker=visitor) if visitor.attributes: self.context[-1].extend(visitor.attributes) if len(visitor.attributes) == 1: self.documentable = visitor.attributes[0] else: self.documentable = None class ModuleVisitor(AssignmentVisitor): def __init__(self, filename, token_parser): AssignmentVisitor.__init__(self, token_parser) self.filename = filename self.module = None def visitModule(self, node): self.module = module = Module(node, self.filename) if node.doc is not None: module.append(Docstring(node, node.doc)) self.context.append(module) self.documentable = module self.visit(node.node) self.context.pop() def visitImport(self, node): self.context[-1].append(Import(node, node.names)) self.documentable = None def visitFrom(self, node): self.context[-1].append( Import(node, node.names, from_name=node.modname)) self.documentable = None def visitFunction(self, node): visitor = FunctionVisitor(self.token_parser) compiler.walk(node, visitor, walker=visitor) self.context[-1].append(visitor.function) def visitClass(self, node): visitor = ClassVisitor(self.token_parser) compiler.walk(node, visitor, walker=visitor) self.context[-1].append(visitor.klass) class AttributeVisitor(BaseVisitor): def __init__(self, token_parser): BaseVisitor.__init__(self, token_parser) self.attributes = [] def visitAssign(self, node): # Don't visit the expression itself, just the attribute nodes: for child in node.nodes: self.dispatch(child) expression_text = self.token_parser.rhs(node.lineno) expression = Expression(node, expression_text) for attribute in self.attributes: attribute.append(expression) def visitAssName(self, node): self.attributes.append(Attribute(node, node.name)) def visitAssTuple(self, node): attributes = self.attributes self.attributes = [] self.default_visit(node) names = [attribute.name for attribute in self.attributes] att_tuple = AttributeTuple(node, names) att_tuple.lineno = self.attributes[0].lineno self.attributes = attributes self.attributes.append(att_tuple) def visitAssAttr(self, node): self.default_visit(node, node.attrname) def visitGetattr(self, node, suffix): self.default_visit(node, node.attrname + '.' + suffix) def visitName(self, node, suffix): self.attributes.append(Attribute(node, node.name + '.' + suffix)) class FunctionVisitor(DocstringVisitor): in_function = 0 function_class = Function def visitFunction(self, node): if self.in_function: self.documentable = None # Don't bother with nested function definitions. return self.in_function = 1 self.function = function = self.function_class(node, node.name) if node.doc is not None: function.append(Docstring(node, node.doc)) self.context.append(function) self.documentable = function self.parse_parameter_list(node) self.visit(node.code) self.context.pop() def parse_parameter_list(self, node): parameters = [] special = [] argnames = list(node.argnames) if node.kwargs: special.append(ExcessKeywordArguments(node, argnames[-1])) argnames.pop() if node.varargs: special.append(ExcessPositionalArguments(node, argnames[-1])) argnames.pop() defaults = list(node.defaults) defaults = [None] * (len(argnames) - len(defaults)) + defaults function_parameters = self.token_parser.function_parameters( node.lineno) #print >>sys.stderr, function_parameters for argname, default in zip(argnames, defaults): if type(argname) is TupleType: parameter = ParameterTuple(node, argname) argname = normalize_parameter_name(argname) else: parameter = Parameter(node, argname) if default: parameter.append(Default(node, function_parameters[argname])) parameters.append(parameter) if parameters or special: special.reverse() parameters.extend(special) parameter_list = ParameterList(node) parameter_list.extend(parameters) self.function.append(parameter_list) class ClassVisitor(AssignmentVisitor): in_class = 0 def __init__(self, token_parser): AssignmentVisitor.__init__(self, token_parser) self.bases = [] def visitClass(self, node): if self.in_class: self.documentable = None # Don't bother with nested class definitions. return self.in_class = 1 #import mypdb as pdb #pdb.set_trace() for base in node.bases: self.visit(base) self.klass = klass = Class(node, node.name, self.bases) if node.doc is not None: klass.append(Docstring(node, node.doc)) self.context.append(klass) self.documentable = klass self.visit(node.code) self.context.pop() def visitGetattr(self, node, suffix=None): if suffix: name = node.attrname + '.' + suffix else: name = node.attrname self.default_visit(node, name) def visitName(self, node, suffix=None): if suffix: name = node.name + '.' + suffix else: name = node.name self.bases.append(name) def visitFunction(self, node): if node.name == '__init__': visitor = InitMethodVisitor(self.token_parser) else: visitor = MethodVisitor(self.token_parser) compiler.walk(node, visitor, walker=visitor) self.context[-1].append(visitor.function) class MethodVisitor(FunctionVisitor): function_class = Method class InitMethodVisitor(MethodVisitor, AssignmentVisitor): pass class TokenParser: def __init__(self, text): self.text = text + '\n\n' self.lines = self.text.splitlines(1) self.generator = tokenize.generate_tokens(iter(self.lines).next) self.next() def __iter__(self): return self def next(self): self.token = self.generator.next() self.type, self.string, self.start, self.end, self.line = self.token return self.token def goto_line(self, lineno): while self.start[0] < lineno: self.next() return token def rhs(self, lineno): """ Return a whitespace-normalized expression string from the right-hand side of an assignment at line `lineno`. """ self.goto_line(lineno) while self.string != '=': self.next() self.stack = None while self.type != token.NEWLINE and self.string != ';': if self.string == '=' and not self.stack: self.tokens = [] self.stack = [] self._type = None self._string = None self._backquote = 0 else: self.note_token() self.next() self.next() text = ''.join(self.tokens) return text.strip() closers = {')': '(', ']': '[', '}': '{'} openers = {'(': 1, '[': 1, '{': 1} del_ws_prefix = {'.': 1, '=': 1, ')': 1, ']': 1, '}': 1, ':': 1, ',': 1} no_ws_suffix = {'.': 1, '=': 1, '(': 1, '[': 1, '{': 1} def note_token(self): if self.type == tokenize.NL: return del_ws = self.del_ws_prefix.has_key(self.string) append_ws = not self.no_ws_suffix.has_key(self.string) if self.openers.has_key(self.string): self.stack.append(self.string) if (self._type == token.NAME or self.closers.has_key(self._string)): del_ws = 1 elif self.closers.has_key(self.string): assert self.stack[-1] == self.closers[self.string] self.stack.pop() elif self.string == '`': if self._backquote: del_ws = 1 assert self.stack[-1] == '`' self.stack.pop() else: append_ws = 0 self.stack.append('`') self._backquote = not self._backquote if del_ws and self.tokens and self.tokens[-1] == ' ': del self.tokens[-1] self.tokens.append(self.string) self._type = self.type self._string = self.string if append_ws: self.tokens.append(' ') def function_parameters(self, lineno): """ Return a dictionary mapping parameters to defaults (whitespace-normalized strings). """ self.goto_line(lineno) while self.string != 'def': self.next() while self.string != '(': self.next() name = None default = None parameter_tuple = None self.tokens = [] parameters = {} self.stack = [self.string] self.next() while 1: if len(self.stack) == 1: if parameter_tuple: # Just encountered ")". #print >>sys.stderr, 'parameter_tuple: %r' % self.tokens name = ''.join(self.tokens).strip() self.tokens = [] parameter_tuple = None if self.string in (')', ','): if name: if self.tokens: default_text = ''.join(self.tokens).strip() else: default_text = None parameters[name] = default_text self.tokens = [] name = None default = None if self.string == ')': break elif self.type == token.NAME: if name and default: self.note_token() else: assert name is None, ( 'token=%r name=%r parameters=%r stack=%r' % (self.token, name, parameters, self.stack)) name = self.string #print >>sys.stderr, 'name=%r' % name elif self.string == '=': assert name is not None, 'token=%r' % (self.token,) assert default is None, 'token=%r' % (self.token,) assert self.tokens == [], 'token=%r' % (self.token,) default = 1 self._type = None self._string = None self._backquote = 0 elif name: self.note_token() elif self.string == '(': parameter_tuple = 1 self._type = None self._string = None self._backquote = 0 self.note_token() else: # ignore these tokens: assert (self.string in ('*', '**', '\n') or self.type == tokenize.COMMENT), ( 'token=%r' % (self.token,)) else: self.note_token() self.next() return parameters def trim_docstring(text): """ Trim indentation and blank lines from docstring text & return it. See PEP 257. """ if not text: return text # Convert tabs to spaces (following the normal Python rules) # and split into a list of lines: lines = text.expandtabs().splitlines() # Determine minimum indentation (first line doesn't count): indent = sys.maxint for line in lines[1:]: stripped = line.lstrip() if stripped: indent = min(indent, len(line) - len(stripped)) # Remove indentation (first line is special): trimmed = [lines[0].strip()] if indent < sys.maxint: for line in lines[1:]: trimmed.append(line[indent:].rstrip()) # Strip off trailing and leading blank lines: while trimmed and not trimmed[-1]: trimmed.pop() while trimmed and not trimmed[0]: trimmed.pop(0) # Return a single string: return '\n'.join(trimmed) def normalize_parameter_name(name): """ Converts a tuple like ``('a', ('b', 'c'), 'd')`` into ``'(a, (b, c), d)'`` """ if type(name) is TupleType: return '(%s)' % ', '.join([normalize_parameter_name(n) for n in name]) else: return name From goodger@users.sourceforge.net Wed Jan 1 02:36:30 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:30 -0800 Subject: [Python-checkins] python/nondist/peps/docutils core.py,1.1,1.2 frontend.py,1.1,1.2 io.py,1.1,1.2 utils.py,1.1,1.2 .cvsignore,1.1,NONE Message-ID: <E18TYkA-0007rG-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils In directory sc8-pr-cvs1:/tmp/cvs-serv30174 Modified Files: core.py frontend.py io.py utils.py Removed Files: .cvsignore Log Message: update from latest Docutils code Index: core.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/core.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** core.py 8 Nov 2002 23:47:51 -0000 1.1 --- core.py 1 Jan 2003 02:35:57 -0000 1.2 *************** *** 138,143 **** else: self.settings._source = source_path ! self.source = self.source_class(self.settings, source=source, ! source_path=source_path) def set_destination(self, destination=None, destination_path=None): --- 138,144 ---- else: self.settings._source = source_path ! self.source = self.source_class( ! source=source, source_path=source_path, ! encoding=self.settings.input_encoding) def set_destination(self, destination=None, destination_path=None): *************** *** 147,152 **** self.settings._destination = destination_path self.destination = self.destination_class( ! self.settings, destination=destination, ! destination_path=destination_path) def apply_transforms(self, document): --- 148,153 ---- self.settings._destination = destination_path self.destination = self.destination_class( ! destination=destination, destination_path=destination_path, ! encoding=self.settings.output_encoding) def apply_transforms(self, document): Index: frontend.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/frontend.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** frontend.py 8 Nov 2002 23:47:51 -0000 1.1 --- frontend.py 1 Jan 2003 02:35:57 -0000 1.2 *************** *** 304,335 **** The section DEFAULT is special. """ ! try: ! sectdict = self._ConfigParser__sections[section].copy() ! except KeyError: ! sectdict = {} ! d = self._ConfigParser__defaults.copy() ! d.update(sectdict) ! # Update with the entry specific variables ! if vars: ! d.update(vars) ! if raw: ! return sectdict ! # do the string interpolation ! for option in sectdict.keys(): ! rawval = sectdict[option] ! value = rawval # Make it a pretty variable name ! depth = 0 ! while depth < 10: # Loop through this until it's done ! depth += 1 ! if value.find("%(") >= 0: ! try: ! value = value % d ! except KeyError, key: ! raise CP.InterpolationError(key, option, section, ! rawval) ! else: ! break ! if value.find("%(") >= 0: ! raise CP.InterpolationDepthError(option, section, rawval) ! sectdict[option] = value ! return sectdict --- 304,310 ---- The section DEFAULT is special. """ ! section_dict = {} ! if self.has_section(section): ! for option in self.options(section): ! section_dict[option] = self.get(section, option, raw, vars) ! return section_dict Index: io.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/io.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** io.py 8 Nov 2002 23:47:51 -0000 1.1 --- io.py 1 Jan 2003 02:35:57 -0000 1.2 *************** *** 27,34 **** default_source_path = None ! def __init__(self, settings, source=None, source_path=None): ! self.settings = settings ! """A settings object with "input_encoding" and "output_encoding" ! attributes (typically a `docutils.optik.Values` object).""" self.source = source --- 27,44 ---- default_source_path = None ! def __init__(self, settings=None, source=None, source_path=None, ! encoding=None): ! self.encoding = encoding ! """The character encoding for the input source.""" ! ! if settings: ! if not encoding: ! self.encoding = settings.input_encoding ! import warnings, traceback ! warnings.warn( ! 'Setting input encoding via a "settings" struct is ' ! 'deprecated; send encoding directly instead.\n%s' ! % ''.join(traceback.format_list(traceback.extract_stack() ! [-3:-1]))) self.source = source *************** *** 45,49 **** self.source_path) ! def read(self, reader): raise NotImplementedError --- 55,59 ---- self.source_path) ! def read(self): raise NotImplementedError *************** *** 58,65 **** locale.setlocale(locale.LC_ALL, '') """ ! if self.settings.input_encoding \ ! and self.settings.input_encoding.lower() == 'unicode': return unicode(data) ! encodings = [self.settings.input_encoding, 'utf-8'] try: encodings.append(locale.nl_langinfo(locale.CODESET)) --- 68,74 ---- locale.setlocale(locale.LC_ALL, '') """ ! if self.encoding and self.encoding.lower() == 'unicode': return unicode(data) ! encodings = [self.encoding, 'utf-8'] try: encodings.append(locale.nl_langinfo(locale.CODESET)) *************** *** 98,105 **** default_destination_path = None ! def __init__(self, settings, destination=None, destination_path=None): ! self.settings = settings ! """A settings object with "input_encoding" and "output_encoding" ! attributes (typically a `docutils.optik.Values` object).""" self.destination = destination --- 107,124 ---- default_destination_path = None ! def __init__(self, settings=None, destination=None, destination_path=None, ! encoding=None): ! self.encoding = encoding ! """The character encoding for the output destination.""" ! ! if settings: ! if not encoding: ! self.encoding = settings.output_encoding ! import warnings, traceback ! warnings.warn( ! 'Setting output encoding via a "settings" struct is ' ! 'deprecated; send encoding directly instead.\n%s' ! % ''.join(traceback.format_list(traceback.extract_stack() ! [-3:-1]))) self.destination = destination *************** *** 120,128 **** def encode(self, data): ! if self.settings.output_encoding \ ! and self.settings.output_encoding.lower() == 'unicode': return data else: ! return data.encode(self.settings.output_encoding or '') --- 139,146 ---- def encode(self, data): ! if self.encoding and self.encoding.lower() == 'unicode': return data else: ! return data.encode(self.encoding or '') *************** *** 133,137 **** """ ! def __init__(self, settings, source=None, source_path=None, autoclose=1): """ :Parameters: --- 151,156 ---- """ ! def __init__(self, settings=None, source=None, source_path=None, ! encoding=None, autoclose=1): """ :Parameters: *************** *** 142,146 **** false if `sys.stdin` is the source. """ ! Input.__init__(self, settings, source, source_path) self.autoclose = autoclose if source is None: --- 161,165 ---- false if `sys.stdin` is the source. """ ! Input.__init__(self, settings, source, source_path, encoding) self.autoclose = autoclose if source is None: *************** *** 156,160 **** pass ! def read(self, reader): """Read and decode a single file and return the data.""" data = self.source.read() --- 175,179 ---- pass ! def read(self): """Read and decode a single file and return the data.""" data = self.source.read() *************** *** 173,178 **** """ ! def __init__(self, settings, destination=None, destination_path=None, ! autoclose=1): """ :Parameters: --- 192,197 ---- """ ! def __init__(self, settings=None, destination=None, destination_path=None, ! encoding=None, autoclose=1): """ :Parameters: *************** *** 185,189 **** false if `sys.stdout` is the destination. """ ! Output.__init__(self, settings, destination, destination_path) self.opened = 1 self.autoclose = autoclose --- 204,209 ---- false if `sys.stdout` is the destination. """ ! Output.__init__(self, settings, destination, destination_path, ! encoding) self.opened = 1 self.autoclose = autoclose *************** *** 227,231 **** default_source_path = '<string>' ! def read(self, reader): """Decode and return the source string.""" return self.decode(self.source) --- 247,251 ---- default_source_path = '<string>' ! def read(self): """Decode and return the source string.""" return self.decode(self.source) *************** *** 254,258 **** default_source_path = 'null input' ! def read(self, reader): """Return a null string.""" return u'' --- 274,278 ---- default_source_path = 'null input' ! def read(self): """Return a null string.""" return u'' Index: utils.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/utils.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** utils.py 8 Nov 2002 23:47:51 -0000 1.1 --- utils.py 1 Jan 2003 02:35:57 -0000 1.2 *************** *** 374,377 **** --- 374,386 ---- def new_document(source, settings=None): + """ + Return a new empty document object. + + :Parameters: + `source` : string + The path to or description of the source text of the document. + `settings` : optparse.Values object + Runtime settings. If none provided, a default set will be used. + """ if settings is None: settings = frontend.OptionParser().get_default_values() --- .cvsignore DELETED --- From goodger@users.sourceforge.net Wed Jan 1 02:36:32 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:32 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/parsers/rst/directives misc.py,1.1,1.2 .cvsignore,1.1,NONE Message-ID: <E18TYkC-0007rz-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils/parsers/rst/directives In directory sc8-pr-cvs1:/tmp/cvs-serv30174/parsers/rst/directives Modified Files: misc.py Removed Files: .cvsignore Log Message: update from latest Docutils code Index: misc.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/parsers/rst/directives/misc.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** misc.py 8 Nov 2002 23:47:52 -0000 1.1 --- misc.py 1 Jan 2003 02:35:59 -0000 1.2 *************** *** 12,16 **** import os.path from urllib2 import urlopen, URLError ! from docutils import nodes, statemachine, utils from docutils.parsers.rst import directives, states --- 12,16 ---- import os.path from urllib2 import urlopen, URLError ! from docutils import io, nodes, statemachine, utils from docutils.parsers.rst import directives, states *************** *** 19,24 **** content_offset, block_text, state, state_machine): """Include a reST file as part of the content of this reST file.""" ! source_dir = os.path.dirname( ! os.path.abspath(state.document.current_source)) path = ''.join(arguments[0].splitlines()) if path.find(' ') != -1: --- 19,25 ---- content_offset, block_text, state, state_machine): """Include a reST file as part of the content of this reST file.""" ! source = state_machine.input_lines.source( ! lineno - state_machine.input_offset - 1) ! source_dir = os.path.dirname(os.path.abspath(source)) path = ''.join(arguments[0].splitlines()) if path.find(' ') != -1: *************** *** 30,34 **** path = utils.relative_path(None, path) try: ! include_file = open(path) except IOError, error: severe = state_machine.reporter.severe( --- 31,36 ---- path = utils.relative_path(None, path) try: ! include_file = io.FileInput( ! source_path=path, encoding=state.document.settings.input_encoding) except IOError, error: severe = state_machine.reporter.severe( *************** *** 37,41 **** return [severe] include_text = include_file.read() - include_file.close() if options.has_key('literal'): literal_block = nodes.literal_block(include_text, include_text, --- 39,42 ---- --- .cvsignore DELETED --- From goodger@users.sourceforge.net Wed Jan 1 02:36:31 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 31 Dec 2002 18:36:31 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/parsers/rst __init__.py,1.1,1.2 states.py,1.2,1.3 .cvsignore,1.1,NONE Message-ID: <E18TYkB-0007rw-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils/parsers/rst In directory sc8-pr-cvs1:/tmp/cvs-serv30174/parsers/rst Modified Files: __init__.py states.py Removed Files: .cvsignore Log Message: update from latest Docutils code Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/parsers/rst/__init__.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** __init__.py 8 Nov 2002 23:47:52 -0000 1.1 --- __init__.py 1 Jan 2003 02:35:59 -0000 1.2 *************** *** 9,12 **** --- 9,13 ---- the reStructuredText parser. + Usage ===== *************** *** 14,21 **** 1. Create a parser:: ! parser = docutils.parsers.restructuredtext.Parser() Several optional arguments may be passed to modify the parser's behavior. ! Please see `docutils.parsers.Parser` for details. 2. Gather input (a multi-line string), by reading a file or the standard --- 15,22 ---- 1. Create a parser:: ! parser = docutils.parsers.rst.Parser() Several optional arguments may be passed to modify the parser's behavior. ! Please see `Customizing the Parser`_ below for details. 2. Gather input (a multi-line string), by reading a file or the standard *************** *** 26,30 **** 3. Create a new empty `docutils.nodes.document` tree:: ! document = docutils.utils.new_document(source) See `docutils.utils.new_document()` for parameter details. --- 27,31 ---- 3. Create a new empty `docutils.nodes.document` tree:: ! document = docutils.utils.new_document(source, settings) See `docutils.utils.new_document()` for parameter details. *************** *** 34,37 **** --- 35,39 ---- parser.parse(input, document) + Parser Overview =============== *************** *** 41,44 **** --- 43,71 ---- become familiar with the `docutils.statemachine` module, then see the `states` module. + + + Customizing the Parser + ---------------------- + + Anything that isn't already customizable is that way simply because that type + of customizability hasn't been implemented yet. Patches welcome! + + When instantiating an object of the `Parser` class, two parameters may be + passed: ``rfc2822`` and ``inliner``. Pass ``rfc2822=1`` to enable an initial + RFC-2822 style header block, parsed as a "field_list" element (with "class" + attribute set to "rfc2822"). Currently this is the only body-level element + which is customizable without subclassing. (Tip: subclass `Parser` and change + its "state_classes" and "initial_state" attributes to refer to new classes. + Contact the author if you need more details.) + + The ``inliner`` parameter takes an instance of `states.Inliner` or a subclass. + It handles inline markup recognition. A common extension is the addition of + further implicit hyperlinks, like "RFC 2822". This can be done by subclassing + `states.Inliner`, adding a new method for the implicit markup, and adding a + ``(pattern, method)`` pair to the "implicit_dispatch" attribute of the + subclass. See `states.Inliner.implicit_inline()` for details. Explicit + inline markup can be customized in a `states.Inliner` subclass via the + ``patterns.initial`` and ``dispatch`` attributes (and new methods as + appropriate). """ Index: states.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/parsers/rst/states.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** states.py 17 Nov 2002 00:09:19 -0000 1.2 --- states.py 1 Jan 2003 02:35:59 -0000 1.3 *************** *** 529,533 **** closers = '\'")]}>' start_string_prefix = (r'((?<=^)|(?<=[-/: \n%s]))' % re.escape(openers)) ! end_string_suffix = (r'((?=$)|(?=[-/:.,;!? \n%s]))' % re.escape(closers)) non_whitespace_before = r'(?<![ \n])' non_whitespace_escape_before = r'(?<![ \n\x00])' --- 529,533 ---- closers = '\'")]}>' start_string_prefix = (r'((?<=^)|(?<=[-/: \n%s]))' % re.escape(openers)) ! end_string_suffix = (r'((?=$)|(?=[-/:.,;!? \n\x00%s]))' % re.escape(closers)) non_whitespace_before = r'(?<![ \n])' non_whitespace_escape_before = r'(?<![ \n\x00])' *************** *** 1802,1806 **** arguments = [] options = {} - content = [] argument_spec = getattr(directive_fn, 'arguments', None) if argument_spec and argument_spec[:2] == (0, 0): --- 1802,1805 ---- *************** *** 2384,2394 **** """Section title.""" lineno = self.state_machine.abs_line_number() - if not self.state_machine.match_titles: - blocktext = context[0] + '\n' + self.state_machine.line - msg = self.reporter.severe( - 'Unexpected section title.', - nodes.literal_block(blocktext, blocktext), line=lineno) - self.parent += msg - return [], next_state, [] title = context[0].rstrip() underline = match.string.rstrip() --- 2383,2386 ---- *************** *** 2397,2405 **** if len(title) > len(underline): if len(underline) < 4: ! msg = self.reporter.info( ! 'Possible title underline, too short for the title.\n' ! "Treating it as ordinary text because it's so short.", ! line=lineno) ! self.parent += msg raise statemachine.TransitionCorrection('text') else: --- 2389,2398 ---- if len(title) > len(underline): if len(underline) < 4: ! if self.state_machine.match_titles: ! msg = self.reporter.info( ! 'Possible title underline, too short for the title.\n' ! "Treating it as ordinary text because it's so short.", ! line=lineno) ! self.parent += msg raise statemachine.TransitionCorrection('text') else: *************** *** 2409,2412 **** --- 2402,2413 ---- nodes.literal_block(blocktext, blocktext), line=lineno) messages.append(msg) + if not self.state_machine.match_titles: + blocktext = context[0] + '\n' + self.state_machine.line + msg = self.reporter.severe( + 'Unexpected section title.', + nodes.literal_block(blocktext, blocktext), line=lineno) + self.parent += messages + self.parent += msg + return [], next_state, [] style = underline[0] context[:] = [] --- .cvsignore DELETED --- From tim_one@users.sourceforge.net Wed Jan 1 04:12:04 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 31 Dec 2002 20:12:04 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.131,1.132 test_datetime.py,1.90,1.91 Message-ID: <E18TaEe-0002SH-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv7366 Modified Files: datetime.py test_datetime.py Log Message: The failure of the last-second addition to the timezone coversion test is understood now: it can't work. Added comments explaining why (it's "the usual"-- unrepresentable hours in local time --but in a slightly different guise). Added an optimization to astimezone(). This will pay off more in the C implementation (which is already optimized to work with offsets as C ints internally, instead of with timedelta objects; this will let it replace a datetimetz comparison call with a couple of int operations; in the Python implementation it trades away a datetimetz comparison call for a couple of timedelta operations). Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.131 retrieving revision 1.132 diff -C2 -d -r1.131 -r1.132 *** datetime.py 31 Dec 2002 15:56:31 -0000 1.131 --- datetime.py 1 Jan 2003 04:12:00 -0000 1.132 *************** *** 1639,1643 **** return other ! other += otoff - myoff # If tz is a fixed-offset class, we're done, but we can't know # whether it is. If it's a DST-aware class, and we're not near a --- 1639,1644 ---- return other ! total_added_to_other = otoff - myoff ! other += total_added_to_other # If tz is a fixed-offset class, we're done, but we can't know # whether it is. If it's a DST-aware class, and we're not near a *************** *** 1650,1654 **** self._inconsistent_utcoffset_error() if newoff != otoff: ! other += newoff - otoff otoff = other.utcoffset() if otoff is None: --- 1651,1657 ---- self._inconsistent_utcoffset_error() if newoff != otoff: ! delta = newoff - otoff ! total_added_to_other += delta ! other += delta otoff = other.utcoffset() if otoff is None: *************** *** 1663,1677 **** if altoff is None: self._inconsistent_utcoffset_error() ! # Are alt and other really the same time? alt == other iff # alt - altoff == other - otoff, iff # (other - _HOUR) - altoff = other - otoff, iff # otoff - altoff == _HOUR diff = otoff - altoff if diff == _HOUR: return alt # use the local time that makes sense # There's still a problem with the unspellable (in local time) ! # hour after DST ends. ! if self == other: return other # Else there's no way to spell self in zone other.tz. --- 1666,1693 ---- if altoff is None: self._inconsistent_utcoffset_error() ! # Are alt and other really the same time? They are iff # alt - altoff == other - otoff, iff # (other - _HOUR) - altoff = other - otoff, iff # otoff - altoff == _HOUR + # Note that the Python comparison "alt == other" would return false, + # though, because they have same tzinfo member, and utcoffset() is + # ignored when comparing times w/ the same tzinfo. diff = otoff - altoff + + # Enable the assert if you're dubious; it's expensive. + ##assert ((diff == _HOUR) == + ## (alt.replace(tzinfo=None) - alt.utcoffset() == + ## other.replace(tzinfo=None) - other.utcoffset())) if diff == _HOUR: return alt # use the local time that makes sense # There's still a problem with the unspellable (in local time) ! # hour after DST ends. other's local time now is ! # self + total_added_to_other, so self == other iff ! # self - myoff = other - otoff, iff ! # self - myoff = self + total_added_to_other - otoff, iff ! # total_added_to_other == otoff - myoff ! ##assert (self == other) == (total_added_to_other == otoff - myoff) ! if total_added_to_other == otoff - myoff: return other # Else there's no way to spell self in zone other.tz. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -d -r1.90 -r1.91 *** test_datetime.py 31 Dec 2002 15:32:12 -0000 1.90 --- test_datetime.py 1 Jan 2003 04:12:00 -0000 1.91 *************** *** 2606,2610 **** dstoff = datetimetz(2002, 10, 27, 2) - # Check a time that's inside DST. def checkinside(self, dt, tz, utc, dston, dstoff): --- 2606,2609 ---- *************** *** 2706,2712 **** self.convert_between_tz_and_utc(Eastern, Pacific) self.convert_between_tz_and_utc(Pacific, Eastern) ! # XXX These fail! ! #self.convert_between_tz_and_utc(Eastern, Central) ! #self.convert_between_tz_and_utc(Central, Eastern) --- 2705,2720 ---- self.convert_between_tz_and_utc(Eastern, Pacific) self.convert_between_tz_and_utc(Pacific, Eastern) ! # OTOH, these fail! Don't enable them. The difficulty is that ! # the edge case tests assume that every hour is representable in ! # the "utc" class. This is always true for a fixed-offset tzinfo ! # class (lke utc_real and utc_fake), but not for Eastern or Central. ! # For these adjacent DST-aware time zones, the range of time offsets ! # tested ends up creating hours in the one that aren't representable ! # in the other. For the same reason, we would see failures in the ! # Eastern vs Pacific tests too if we added 3*HOUR to the list of ! # offset deltas in convert_between_tz_and_utc(). ! # ! # self.convert_between_tz_and_utc(Eastern, Central) # can't work ! # self.convert_between_tz_and_utc(Central, Eastern) # can't work From tim_one@users.sourceforge.net Wed Jan 1 04:18:54 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 31 Dec 2002 20:18:54 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.17,1.18 Message-ID: <E18TaLG-0003Bk-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv12126/Lib/test Modified Files: test_datetime.py Log Message: The failure of the last-second addition to the timezone coversion test is understood now: it can't work. Added comments explaining why (it's "the usual"-- unrepresentable hours in local time --but in a slightly different guise). Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** test_datetime.py 31 Dec 2002 17:36:56 -0000 1.17 --- test_datetime.py 1 Jan 2003 04:18:51 -0000 1.18 *************** *** 2592,2596 **** dstoff = datetimetz(2002, 10, 27, 2) - # Check a time that's inside DST. def checkinside(self, dt, tz, utc, dston, dstoff): --- 2592,2595 ---- *************** *** 2692,2698 **** self.convert_between_tz_and_utc(Eastern, Pacific) self.convert_between_tz_and_utc(Pacific, Eastern) ! # XXX These fail! ! #self.convert_between_tz_and_utc(Eastern, Central) ! #self.convert_between_tz_and_utc(Central, Eastern) --- 2691,2706 ---- self.convert_between_tz_and_utc(Eastern, Pacific) self.convert_between_tz_and_utc(Pacific, Eastern) ! # OTOH, these fail! Don't enable them. The difficulty is that ! # the edge case tests assume that every hour is representable in ! # the "utc" class. This is always true for a fixed-offset tzinfo ! # class (lke utc_real and utc_fake), but not for Eastern or Central. ! # For these adjacent DST-aware time zones, the range of time offsets ! # tested ends up creating hours in the one that aren't representable ! # in the other. For the same reason, we would see failures in the ! # Eastern vs Pacific tests too if we added 3*HOUR to the list of ! # offset deltas in convert_between_tz_and_utc(). ! # ! # self.convert_between_tz_and_utc(Eastern, Central) # can't work ! # self.convert_between_tz_and_utc(Central, Eastern) # can't work From tim_one@users.sourceforge.net Wed Jan 1 04:48:04 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 31 Dec 2002 20:48:04 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.21,1.22 Message-ID: <E18TanU-0006NP-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv23078/Modules Modified Files: datetimemodule.c Log Message: datetimetz_astimezone(): Speed optimizations -- although I'd rather find a more elegant algorithm (OTOH, the hairy new implementation allows user-written tzinfo classes to be elegant, so it's a big win even if astimezone() remains hairy). Darn! I've only got 10 minutes left to get falling-down drunk! I suppose I'll have to smoke crack instead now. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** datetimemodule.c 31 Dec 2002 17:36:56 -0000 1.21 --- datetimemodule.c 1 Jan 2003 04:48:01 -0000 1.22 *************** *** 4754,4758 **** PyObject *result; PyObject *temp; ! int myoff, otoff, newoff; int none; --- 4754,4758 ---- PyObject *result; PyObject *temp; ! int selfoff, resoff, tempoff, total_added_to_result; int none; *************** *** 4777,4795 **** * there's no conversion of date or time fields. */ ! myoff = call_utcoffset(self->tzinfo, (PyObject *)self, &none); ! if (myoff == -1 && PyErr_Occurred()) goto Fail; if (none) return result; ! otoff = call_utcoffset(tzinfo, result, &none); ! if (otoff == -1 && PyErr_Occurred()) goto Fail; if (none) return result; ! /* Add otoff-myoff to result. */ ! mm += otoff - myoff; ! if (normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); --- 4777,4797 ---- * there's no conversion of date or time fields. */ ! selfoff = call_utcoffset(self->tzinfo, (PyObject *)self, &none); ! if (selfoff == -1 && PyErr_Occurred()) goto Fail; if (none) return result; ! resoff = call_utcoffset(tzinfo, result, &none); ! if (resoff == -1 && PyErr_Occurred()) goto Fail; if (none) return result; ! /* Add resoff-selfoff to result. */ ! total_added_to_result = resoff - selfoff; ! mm += total_added_to_result; ! if ((mm < 0 || mm >= 60) && ! normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); *************** *** 4806,4819 **** * DST boundary, if we landed on one of the DST "problem hours". */ ! newoff = call_utcoffset(tzinfo, result, &none); ! if (newoff == -1 && PyErr_Occurred()) goto Fail; if (none) goto Inconsistent; ! if (newoff != otoff) { /* We did cross a boundary. Try to correct. */ ! mm += newoff - otoff; ! if (normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); --- 4808,4824 ---- * DST boundary, if we landed on one of the DST "problem hours". */ ! tempoff = call_utcoffset(tzinfo, result, &none); ! if (tempoff == -1 && PyErr_Occurred()) goto Fail; if (none) goto Inconsistent; ! if (tempoff != resoff) { /* We did cross a boundary. Try to correct. */ ! const int delta = tempoff - resoff; ! total_added_to_result += delta; ! mm += delta; ! if ((mm < 0 || mm >= 60) && ! normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); *************** *** 4823,4828 **** result = temp; ! otoff = call_utcoffset(tzinfo, result, &none); ! if (otoff == -1 && PyErr_Occurred()) goto Fail; if (none) --- 4828,4833 ---- result = temp; ! resoff = call_utcoffset(tzinfo, result, &none); ! if (resoff == -1 && PyErr_Occurred()) goto Fail; if (none) *************** *** 4835,4845 **** */ hh -= 1; ! if (normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); if (temp == NULL) goto Fail; ! newoff = call_utcoffset(tzinfo, temp, &none); ! if (newoff == -1 && PyErr_Occurred()) { Py_DECREF(temp); goto Fail; --- 4840,4850 ---- */ hh -= 1; ! if (hh < 0 && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); if (temp == NULL) goto Fail; ! tempoff = call_utcoffset(tzinfo, temp, &none); ! if (tempoff == -1 && PyErr_Occurred()) { Py_DECREF(temp); goto Fail; *************** *** 4850,4858 **** } /* Are temp and result really the same time? temp == result iff ! * temp - newoff == result - otoff, iff ! * (result - HOUR) - newoff = result - otoff, iff ! * otoff - newoff == HOUR */ ! if (otoff - newoff == 60) { /* use the local time that makes sense */ Py_DECREF(result); --- 4855,4863 ---- } /* Are temp and result really the same time? temp == result iff ! * temp - tempoff == result - resoff, iff ! * (result - HOUR) - tempoff = result - resoff, iff ! * resoff - tempoff == HOUR */ ! if (resoff - tempoff == 60) { /* use the local time that makes sense */ Py_DECREF(result); *************** *** 4862,4877 **** /* There's still a problem with the unspellable (in local time) ! * hour after DST ends. */ ! temp = datetime_richcompare((PyDateTime_DateTime *)self, ! result, Py_EQ); ! if (temp == NULL) ! goto Fail; ! if (temp == Py_True) { ! Py_DECREF(temp); return result; ! } ! Py_DECREF(temp); ! /* Else there's no way to spell self in zone other.tz. */ PyErr_SetString(PyExc_ValueError, "astimezone(): the source " "datetimetz can't be expressed in the target " --- 4867,4883 ---- /* There's still a problem with the unspellable (in local time) ! * hour after DST ends. If self and result map to the same UTC time ! * time, we're OK, else the hour is unrepresentable in the tzinfo ! * zone. The result's local time now is ! * self + total_added_to_result, so self == result iff ! * self - selfoff == result - resoff, iff ! * self - selfoff == (self + total_added_to_result) - resoff, iff ! * - selfoff == total_added_to_result - resoff, iff ! * total_added_to_result == resoff - selfoff */ ! if (total_added_to_result == resoff - selfoff) return result; ! ! /* Else there's no way to spell self in zone tzinfo. */ PyErr_SetString(PyExc_ValueError, "astimezone(): the source " "datetimetz can't be expressed in the target " From fdrake@users.sourceforge.net Wed Jan 1 04:50:35 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 31 Dec 2002 20:50:35 -0800 Subject: [Python-checkins] python/dist/src/Doc/texinputs boilerplate.tex,1.75,1.76 Message-ID: <E18Tapv-0006cy-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory sc8-pr-cvs1:/tmp/cvs-serv25460 Modified Files: boilerplate.tex Log Message: Revert merge from 2.3 alpha 1 release branch; the change does not apply to the trunk. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -d -r1.75 -r1.76 *** boilerplate.tex 1 Jan 2003 02:14:11 -0000 1.75 --- boilerplate.tex 1 Jan 2003 04:50:32 -0000 1.76 *************** *** 6,10 **** } ! \date{December 31, 2002} % XXX update before release! \release{2.3} % software release, not documentation \setreleaseinfo{a1+} % empty for final release --- 6,10 ---- } ! \date{\today} % XXX update before release! \release{2.3} % software release, not documentation \setreleaseinfo{a1+} % empty for final release From fdrake@acm.org Wed Jan 1 04:51:34 2003 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Tue, 31 Dec 2002 23:51:34 -0500 Subject: [Python-checkins] python/dist/src/Doc/texinputs boilerplate.tex,1.74,1.75 In-Reply-To: <E18TYOc-0004lU-00@sc8-pr-cvs1.sourceforge.net> References: <E18TYOc-0004lU-00@sc8-pr-cvs1.sourceforge.net> Message-ID: <15890.29654.793226.871023@grendel.zope.com> tim_one@users.sourceforge.net writes: > Modified Files: > boilerplate.tex > Log Message: > Merging in changes from r23a1-branch. Doc/makefile had conflicts, which > I leave to Fred to sort out. It's generally safe to leave the Doc/ tree to me for these things, but thanks for trying! ;-) -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> PythonLabs at Zope Corporation From loewis@users.sourceforge.net Wed Jan 1 09:51:15 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 01 Jan 2003 01:51:15 -0800 Subject: [Python-checkins] python/dist/src/Modules fcntlmodule.c,2.36,2.37 posixmodule.c,2.279,2.280 Message-ID: <E18TfWt-0001Go-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv4773/Modules Modified Files: fcntlmodule.c posixmodule.c Log Message: Expose I_ constants. Auto-detect stropts.h. Properly configure the slave terminal. Index: fcntlmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/fcntlmodule.c,v retrieving revision 2.36 retrieving revision 2.37 diff -C2 -d -r2.36 -r2.37 *** fcntlmodule.c 2 Aug 2002 02:27:13 -0000 2.36 --- fcntlmodule.c 1 Jan 2003 09:51:12 -0000 2.37 *************** *** 10,14 **** #include <sys/ioctl.h> #include <fcntl.h> ! static int --- 10,16 ---- #include <sys/ioctl.h> #include <fcntl.h> ! #ifdef HAVE_STROPTS_H ! #include <stropts.h> ! #endif static int *************** *** 338,341 **** --- 340,345 ---- } + #define INS(x) if (ins(d, #x, (long)x)) return -1 + static int all_ins(PyObject* d) *************** *** 460,463 **** --- 464,500 ---- #endif + #ifdef HAVE_STROPTS_H + /* Unix 98 guarantees that these are in stropts.h. */ + INS(I_PUSH); + INS(I_POP); + INS(I_LOOK); + INS(I_FLUSH); + INS(I_FLUSHBAND); + INS(I_SETSIG); + INS(I_GETSIG); + INS(I_FIND); + INS(I_PEEK); + INS(I_SRDOPT); + INS(I_GRDOPT); + INS(I_NREAD); + INS(I_FDINSERT); + INS(I_STR); + INS(I_SWROPT); + INS(I_GWROPT); + INS(I_SENDFD); + INS(I_RECVFD); + INS(I_LIST); + INS(I_ATMARK); + INS(I_CKBAND); + INS(I_GETBAND); + INS(I_CANPUT); + INS(I_SETCLTIME); + INS(I_GETCLTIME); + INS(I_LINK); + INS(I_UNLINK); + INS(I_PLINK); + INS(I_PUNLINK); + #endif + return 0; } Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.279 retrieving revision 2.280 diff -C2 -d -r2.279 -r2.280 *** posixmodule.c 31 Dec 2002 16:16:07 -0000 2.279 --- posixmodule.c 1 Jan 2003 09:51:12 -0000 2.280 *************** *** 2727,2732 **** #endif /* HAVE_LIBUTIL_H */ #endif /* HAVE_PTY_H */ ! #if defined(sun) || defined(__hpux) ! #include <sys/stropts.h> #endif #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ --- 2727,2732 ---- #endif /* HAVE_LIBUTIL_H */ #endif /* HAVE_PTY_H */ ! #ifdef HAVE_STROPTS_H ! #include <stropts.h> #endif #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ From loewis@users.sourceforge.net Wed Jan 1 09:51:14 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 01 Jan 2003 01:51:14 -0800 Subject: [Python-checkins] python/dist/src configure,1.371,1.372 configure.in,1.382,1.383 pyconfig.h.in,1.67,1.68 Message-ID: <E18TfWs-0001Ga-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv4773 Modified Files: configure configure.in pyconfig.h.in Log Message: Expose I_ constants. Auto-detect stropts.h. Properly configure the slave terminal. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.371 retrieving revision 1.372 diff -C2 -d -r1.371 -r1.372 *** configure 31 Dec 2002 12:55:08 -0000 1.371 --- configure 1 Jan 2003 09:51:07 -0000 1.372 *************** *** 1,4 **** #! /bin/sh ! # From configure.in Revision: 1.381 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. --- 1,4 ---- #! /bin/sh ! # From configure.in Revision: 1.382 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. *************** *** 3978,3984 **** for ac_header in 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 thread.h unistd.h utime.h termios.h \ sys/audioio.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 \ --- 3978,3986 ---- + for ac_header in 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/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 \ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.382 retrieving revision 1.383 diff -C2 -d -r1.382 -r1.383 *** configure.in 31 Dec 2002 12:55:13 -0000 1.382 --- configure.in 1 Jan 2003 09:51:10 -0000 1.383 *************** *** 691,695 **** AC_CHECK_HEADERS(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 thread.h unistd.h utime.h termios.h \ sys/audioio.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 \ --- 691,696 ---- AC_CHECK_HEADERS(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/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 \ Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** pyconfig.h.in 31 Dec 2002 12:55:13 -0000 1.67 --- pyconfig.h.in 1 Jan 2003 09:51:11 -0000 1.68 *************** *** 440,443 **** --- 440,446 ---- #undef HAVE_STRING_H + /* Define to 1 if you have the <stropts.h> header file. */ + #undef HAVE_STROPTS_H + /* Define to 1 if you have the `strptime' function. */ #undef HAVE_STRPTIME From loewis@users.sourceforge.net Wed Jan 1 09:51:14 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 01 Jan 2003 01:51:14 -0800 Subject: [Python-checkins] python/dist/src/Lib pty.py,1.12,1.13 Message-ID: <E18TfWs-0001Gc-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv4773/Lib Modified Files: pty.py Log Message: Expose I_ constants. Auto-detect stropts.h. Properly configure the slave terminal. Index: pty.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pty.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pty.py 28 Jul 2002 09:42:57 -0000 1.12 --- pty.py 1 Jan 2003 09:51:11 -0000 1.13 *************** *** 87,91 **** Deprecated, use openpty() instead.""" ! return os.open(tty_name, os.O_RDWR) def fork(): --- 87,101 ---- Deprecated, use openpty() instead.""" ! result = os.open(tty_name, os.O_RDWR) ! try: ! from fcntl import ioctl, I_PUSH ! except ImportError: ! return result ! try: ! ioctl(result, I_PUSH, "ptem") ! ioctl(result, I_PUSH, "ldterm") ! except IOError: ! pass ! return result def fork(): From loewis@users.sourceforge.net Wed Jan 1 09:51:15 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 01 Jan 2003 01:51:15 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.586,1.587 Message-ID: <E18TfWt-0001Gm-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv4773/Misc Modified Files: NEWS Log Message: Expose I_ constants. Auto-detect stropts.h. Properly configure the slave terminal. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.586 retrieving revision 1.587 diff -C2 -d -r1.586 -r1.587 *** NEWS 31 Dec 2002 16:38:01 -0000 1.586 --- NEWS 1 Jan 2003 09:51:12 -0000 1.587 *************** *** 5,8 **** --- 5,46 ---- (editors: check NEWS.help for information about editing NEWS using ReST.) + What's New in Python 2.3 alpha 2? + ================================= + + *Release date: XX-XXX-2003 + + Core and builtins + ----------------- + + Extension modules + ----------------- + + - fcntl now exposes the strops.h I_* constants. + + Library + ------- + + Tools/Demos + ----------- + + Build + ----- + + C API + ----- + + New platforms + ------------- + + Tests + ----- + + Windows + ------- + + Mac + --- + + What's New in Python 2.3 alpha 1? ================================= From gvanrossum@users.sourceforge.net Wed Jan 1 14:41:27 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 01 Jan 2003 06:41:27 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts byext.py,NONE,1.1 Message-ID: <E18Tk3j-0001Yz-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv5893 Added Files: byext.py Log Message: Silly little script to print statistics (files, lines, words) by extension. Could use some work, but already very useful. --- NEW FILE: byext.py --- #! /usr/bin/env python """Show file statistics by extension.""" import os import sys class Stats: def __init__(self): self.stats = {} def statargs(self, args): for arg in args: if os.path.isdir(arg): self.statdir(arg) elif os.path.isfile(arg): self.statfile(arg) else: sys.stderr.write("Can't find %s\n" % file) self.addstats("<???>", "unknown", 1) def statdir(self, dir): self.addstats("<dir>", "dirs", 1) try: names = os.listdir(dir) except os.error, err: sys.stderr.write("Can't list %s: %s\n" % (file, err)) self.addstats(ext, "unlistable", 1) return names.sort() for name in names: full = os.path.join(dir, name) if os.path.islink(full): self.addstats("<lnk>", "links", 1) elif os.path.isdir(full): self.statdir(full) else: self.statfile(full) def statfile(self, file): head, ext = os.path.splitext(file) head, base = os.path.split(file) if ext == base: ext = "" # .cvsignore is deemed not to have an extension self.addstats(ext, "files", 1) try: f = open(file, "rb") except IOError, err: sys.stderr.write("Can't open %s: %s\n" % (file, err)) self.addstats(ext, "unopenable", 1) return data = f.read() f.close() self.addstats(ext, "bytes", len(data)) if '\0' in data: self.addstats(ext, "binary", 1) return if not data: self.addstats(ext, "empty", 1) #self.addstats(ext, "chars", len(data)) lines = data.splitlines() self.addstats(ext, "lines", len(lines)) del lines words = data.split() self.addstats(ext, "words", len(words)) def addstats(self, ext, key, n): d = self.stats.setdefault(ext, {}) d[key] = d.get(key, 0) + n def report(self): totals = {} exts = self.stats.keys() exts.sort() # Get the column keys columns = {} for ext in exts: columns.update(self.stats[ext]) cols = columns.keys() cols.sort() minwidth = 7 extwidth = max([len(ext) for ext in exts]) print "%*s" % (extwidth, "ext"), for col in cols: width = max(len(col), minwidth) print "%*s" % (width, col), print for ext in exts: print "%*s" % (extwidth, ext), for col in cols: width = max(len(col), minwidth) value = self.stats[ext].get(col) if value is None: s = "" else: s = "%d" % value totals[col] = totals.get(col, 0) + value print "%*s" % (width, s), print print "%*s" % (extwidth, "TOTAL"), for col in cols: width = max(len(col), minwidth) print "%*s" % (width, totals[col]), print def main(): args = sys.argv[1:] if not args: args = [os.curdir] s = Stats() s.statargs(args) s.report() if __name__ == "__main__": main() From nnorwitz@users.sourceforge.net Wed Jan 1 14:53:30 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Wed, 01 Jan 2003 06:53:30 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_pty.py,1.16,1.17 Message-ID: <E18TkFO-0002AX-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv8116/Lib/test Modified Files: test_pty.py Log Message: Revert last change -- test works on HPUX again after Martin's checkin to 'properly configure the slave terminal' See SF patch # 656590 for the details. Index: test_pty.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pty.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** test_pty.py 31 Dec 2002 18:21:11 -0000 1.16 --- test_pty.py 1 Jan 2003 14:53:27 -0000 1.17 *************** *** 26,32 **** raise TestSkipped, "Pseudo-terminals (seemingly) not functional." ! # this hangs on HPUX 11, comment out for now until we can determine cause ! ##if not os.isatty(slave_fd): ! ## raise TestFailed, "slave_fd is not a tty" # IRIX apparently turns \n into \r\n. Allow that, but avoid allowing other --- 26,31 ---- raise TestSkipped, "Pseudo-terminals (seemingly) not functional." ! if not os.isatty(slave_fd): ! raise TestFailed, "slave_fd is not a tty" # IRIX apparently turns \n into \r\n. Allow that, but avoid allowing other From nnorwitz@users.sourceforge.net Wed Jan 1 15:18:35 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Wed, 01 Jan 2003 07:18:35 -0800 Subject: [Python-checkins] python/dist/src/Include pythonrun.h,2.59,2.60 intobject.h,2.28,2.29 Message-ID: <E18Tkdf-0003df-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv13733/Include Modified Files: pythonrun.h intobject.h Log Message: Move _PyInt_Init() into pythonrun.h, since all the other _Init() functions are here. Suggested by Skip. Index: pythonrun.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v retrieving revision 2.59 retrieving revision 2.60 diff -C2 -d -r2.59 -r2.60 *** pythonrun.h 31 Dec 2002 03:42:12 -0000 2.59 --- pythonrun.h 1 Jan 2003 15:18:32 -0000 2.60 *************** *** 102,105 **** --- 102,106 ---- PyAPI_FUNC(void) _PyImportHooks_Init(void); PyAPI_FUNC(int) _PyFrame_Init(void); + PyAPI_FUNC(int) _PyInt_Init(void); /* Various internal finalizers */ Index: intobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/intobject.h,v retrieving revision 2.28 retrieving revision 2.29 diff -C2 -d -r2.28 -r2.29 *** intobject.h 31 Dec 2002 03:42:12 -0000 2.28 --- intobject.h 1 Jan 2003 15:18:32 -0000 2.29 *************** *** 31,35 **** #define PyInt_CheckExact(op) ((op)->ob_type == &PyInt_Type) - PyAPI_FUNC(int) _PyInt_Init(void); PyAPI_FUNC(PyObject *) PyInt_FromString(char*, char**, int); #ifdef Py_USING_UNICODE --- 31,34 ---- From montanaro@users.sourceforge.net Wed Jan 1 20:07:52 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:07:52 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.587,1.588 Message-ID: <E18Tp9c-0006hM-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv24833/Misc Modified Files: NEWS Log Message: Split OPT make variable into OPT and BASECFLAGS. The latter contains those compiler flags which are necessary to get a clean compile. The former is for user-specified optimizer, debug, trace fiddling. See patch 640843. Add /sw/lib and /sw/include to setup.py search paths on Darwin to take advantage of fink goodies. Add scriptsinstall target to Makefile to install certain scripts from Tools/scripts directory. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.587 retrieving revision 1.588 diff -C2 -d -r1.587 -r1.588 *** NEWS 1 Jan 2003 09:51:12 -0000 1.587 --- NEWS 1 Jan 2003 20:07:49 -0000 1.588 *************** *** 27,30 **** --- 27,48 ---- ----- + - On systems which build using the configure script, compiler flags which + used to be lumped together using the OPT flag have been split into two + groups, OPT and BASECFLAGS. OPT is meant to carry just optimization- and + debug-related flags like "-g" and "-O3". BASECFLAGS is meant to carry + compiler flags that are required to get a clean compile. On some + platforms (many Linux flavors in particular) BASECFLAGS will be empty by + default. On others, such as Mac OS X and SCO, it will contain required + flags. This change allows people building Python to override OPT without + fear of clobbering compiler flags which are required to get a clean build. + + - On Darwin/Mac OS X platforms, /sw/lib and /sw/include are added to the + relevant search lists in setup.py. This allows users building Python to + take advantage of the many packages available from the fink project + <http://fink.sf.net/>. + + - A new Makefile target, scriptsinstall, installs a number of useful scripts + from the Tools/scripts directory. + C API ----- From montanaro@users.sourceforge.net Wed Jan 1 20:07:53 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:07:53 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.107,1.108 configure,1.372,1.373 configure.in,1.383,1.384 setup.py,1.131,1.132 Message-ID: <E18Tp9d-0006hG-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv24833 Modified Files: Makefile.pre.in configure configure.in setup.py Log Message: Split OPT make variable into OPT and BASECFLAGS. The latter contains those compiler flags which are necessary to get a clean compile. The former is for user-specified optimizer, debug, trace fiddling. See patch 640843. Add /sw/lib and /sw/include to setup.py search paths on Darwin to take advantage of fink goodies. Add scriptsinstall target to Makefile to install certain scripts from Tools/scripts directory. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.107 retrieving revision 1.108 diff -C2 -d -r1.107 -r1.108 *** Makefile.pre.in 31 Dec 2002 13:48:28 -0000 1.107 --- Makefile.pre.in 1 Jan 2003 20:07:42 -0000 1.108 *************** *** 55,59 **** # Compiler options OPT= @OPT@ ! CFLAGS= $(OPT) CPPFLAGS= -I. -I$(srcdir)/Include LDFLAGS= @LDFLAGS@ --- 55,60 ---- # Compiler options OPT= @OPT@ ! BASECFLAGS= @BASECFLAGS@ ! CFLAGS= $(BASECFLAGS) $(OPT) CPPFLAGS= -I. -I$(srcdir)/Include LDFLAGS= @LDFLAGS@ *************** *** 844,847 **** --- 845,855 ---- --install-scripts=$(BINDIR) \ --install-platlib=$(DESTSHARED) + + # This installs a few of the useful scripts in Tools/scripts + scriptsinstall: + SRCDIR=$(srcdir) \ + ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \ + --prefix=$(prefix) \ + --install-scripts=$(BINDIR) # Build the toplevel Makefile Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.372 retrieving revision 1.373 diff -C2 -d -r1.372 -r1.373 *** configure 1 Jan 2003 09:51:07 -0000 1.372 --- configure 1 Jan 2003 20:07:43 -0000 1.373 *************** *** 1,6 **** #! /bin/sh ! # From configure.in Revision: 1.382 . # Guess values for system-dependent variables and create Makefiles. ! # Generated by GNU Autoconf 2.53 for python 2.3. # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 --- 1,6 ---- #! /bin/sh ! # From configure.in Revision: 1.383 . # Guess values for system-dependent variables and create Makefiles. [...4685 lines suppressed...] ! 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 || ! echo X"$as_dir" | ! sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } ! /^X\(\/\/\)[^/].*/{ s//\1/; q; } ! /^X\(\/\/\)$/{ s//\1/; q; } ! /^X\(\/\).*/{ s//\1/; q; } ! s/.*/./; q'` ! done ! test ! -n "$as_dirs" || mkdir $as_dirs ! fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 ! echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} ! { (exit 1); exit 1; }; }; } rm -f $ac_file Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.383 retrieving revision 1.384 diff -C2 -d -r1.383 -r1.384 *** configure.in 1 Jan 2003 09:51:10 -0000 1.383 --- configure.in 1 Jan 2003 20:07:47 -0000 1.384 *************** *** 169,172 **** --- 169,181 ---- # checks for alternative programs + + # compiler flags are generated in two sets, BASECFLAGS and OPT. OPT is just + # for debug/optimization stuff. BASECFLAGS is for flags that are required + # just to get things to compile and link. Users are free to override OPT + # when running configure or make. The build should not break if they do. + # BASECFLAGS should generally not be messed with, however. + + # XXX shouldn't some/most/all of this code be merged with the stuff later + # on that fiddles with OPT and BASECFLAGS? AC_MSG_CHECKING(for --without-gcc) AC_ARG_WITH(gcc, *************** *** 189,193 **** CC=mwcc without_gcc=yes ! OPT="-O -export pragma" LDFLAGS="$LDFLAGS -nodup" ;; --- 198,203 ---- CC=mwcc without_gcc=yes ! BASECFLAGS="$BASECFLAGS -export pragma" ! OPT="$OPT -O" LDFLAGS="$LDFLAGS -nodup" ;; *************** *** 195,199 **** CC=gcc without_gcc=no ! OPT=-O ;; *) --- 205,209 ---- CC=gcc without_gcc=no ! OPT="$OPT -O" ;; *) *************** *** 485,489 **** dguxR4) LDLIBRARY='libpython$(VERSION).so' ! OPT="$OPT -pic" ;; esac --- 495,499 ---- dguxR4) LDLIBRARY='libpython$(VERSION).so' ! BASECFLAGS="$BASECFLAGS -pic" ;; esac *************** *** 532,542 **** [AC_MSG_RESULT(no)]) # Optimizer/debugger flags AC_SUBST(OPT) if test -z "$OPT" then ! case $GCC in ! yes) ! case $ac_cv_prog_cc_g in yes) if test "$Py_DEBUG" = 'true' ; then --- 542,566 ---- [AC_MSG_RESULT(no)]) + # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be + # merged with this chunk of code? + # Optimizer/debugger flags + # ------------------------ + # (The following bit of code is complicated enough - please keep things + # indented properly. Just pretend you're editing Python code. ;-) + + # There are two parallel sets of case statements below, one that checks to + # see if OPT was set and one that does BASECFLAGS setting based upon + # compiler and platform. BASECFLAGS tweaks need to be made even if the + # user set OPT. + + # tweak OPT based on compiler and platform, only if the user didn't set + # it on the command line AC_SUBST(OPT) if test -z "$OPT" then ! case $GCC in ! yes) ! case $ac_cv_prog_cc_g in yes) if test "$Py_DEBUG" = 'true' ; then *************** *** 546,574 **** else OPT="-g -O3 -Wall -Wstrict-prototypes" ! fi;; *) ! OPT="-O3 -Wall -Wstrict-prototypes";; esac case $ac_sys_system in ! SCO_SV*) OPT="$OPT -m486 -DSCO5";; ! esac ;; *) ! case $ac_sys_system in ! OpenUNIX*|UnixWare*) ! OPT="-O -K pentium,host,inline,loop_unroll,alloca ";; ! SCO_SV*) ! CFLAGS="$CFLAGS -belf" ! OPT="-belf -O -Ki486 -DSCO5";; ! *) ! OPT="-O";; ! esac esac case $ac_sys_system in ! Darwin*) ! OPT="$OPT -Wno-long-double -no-cpp-precomp";; esac fi if test "$Py_DEBUG" = 'true'; then : --- 570,627 ---- else OPT="-g -O3 -Wall -Wstrict-prototypes" ! fi ! ;; *) ! OPT="-O3 -Wall -Wstrict-prototypes" ! ;; esac case $ac_sys_system in ! SCO_SV*) OPT="$OPT -m486 -DSCO5" ! ;; ! esac ;; + *) ! OPT="-O" ! ;; esac + + # The current (beta) Monterey compiler dies with optimizations + # XXX what is Monterey? Does it still die w/ -O? Can we get rid of this? case $ac_sys_system in ! Monterey*) ! OPT="" ! ;; esac + fi + AC_SUBST(BASECFLAGS) + # tweak BASECFLAGS based on compiler and platform + case $GCC in + yes) + case $ac_sys_system in + SCO_SV*) + BASECFLAGS="$BASECFLAGS -m486 -DSCO5" + ;; + # is there any other compiler on Darwin besides gcc? + Darwin*) + BASECFLAGS="$BASECFLAGS -Wno-long-double -no-cpp-precomp" + ;; + esac + ;; + + *) + case $ac_sys_system in + OpenUNIX*|UnixWare*) + BASECFLAGS="$BASECFLAGS -K pentium,host,inline,loop_unroll,alloca " + ;; + SCO_SV*) + BASECFLAGS="$BASECFLAGS -belf -Ki486 -DSCO5" + ;; + esac + ;; + esac + if test "$Py_DEBUG" = 'true'; then : *************** *** 577,588 **** fi - # The current (beta) Monterey compiler dies with optimizations - case $ac_sys_system in - Monterey*) OPT="";; - esac - if test "$ac_arch_flags" then ! OPT="$OPT $ac_arch_flags" fi --- 630,636 ---- fi if test "$ac_arch_flags" then ! BASECFLAGS="$BASECFLAGS $ac_arch_flags" fi *************** *** 599,604 **** if test $ac_cv_opt_olimit_ok = yes; then case $ac_sys_system in ! Darwin*) OPT="$OPT" ;; ! *) OPT="$OPT -OPT:Olimit=0";; esac else --- 647,658 ---- if test $ac_cv_opt_olimit_ok = yes; then case $ac_sys_system in ! # XXX is this branch needed? On MacOSX 10.2.2 the result of the ! # olimit_ok test is "no". Is it "yes" in some other Darwin-esque ! # environment? ! Darwin*) ! ;; ! *) ! BASECFLAGS="$BASECFLAGS -OPT:Olimit=0" ! ;; esac else *************** *** 614,618 **** AC_MSG_RESULT($ac_cv_olimit_ok) if test $ac_cv_olimit_ok = yes; then ! OPT="$OPT -Olimit 1500" fi fi --- 668,672 ---- AC_MSG_RESULT($ac_cv_olimit_ok) if test $ac_cv_olimit_ok = yes; then ! BASECFLAGS="$BASECFLAGS -Olimit 1500" fi fi *************** *** 940,944 **** if test "$enable_framework" then ! OPT="$OPT -fno-common -dynamic" # -F. is needed to allow linking to the framework while # in the build location. --- 994,998 ---- if test "$enable_framework" then ! BASECFLAGS="$BASECFLAGS -fno-common -dynamic" # -F. is needed to allow linking to the framework while # in the build location. *************** *** 1546,1550 **** ipv6lib=inet6 ipv6libdir=/usr/inet6/lib ! OPT="-I/usr/inet6/include $OPT" fi ;; --- 1600,1604 ---- ipv6lib=inet6 ipv6libdir=/usr/inet6/lib ! BASECFLAGS="-I/usr/inet6/include $BASECFLAGS" fi ;; *************** *** 1576,1580 **** ipv6lib=v6; ipv6libdir=/usr/local/v6/lib; ! OPT="-I/usr/local/v6/include $OPT"]) ;; zeta) --- 1630,1634 ---- ipv6lib=v6; ipv6libdir=/usr/local/v6/lib; ! BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS"]) ;; zeta) Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.131 retrieving revision 1.132 diff -C2 -d -r1.131 -r1.132 *** setup.py 31 Dec 2002 20:30:46 -0000 1.131 --- setup.py 1 Jan 2003 20:07:48 -0000 1.132 *************** *** 174,179 **** # compilers if compiler is not None: ! (ccshared,opt) = sysconfig.get_config_vars('CCSHARED','OPT') ! args['compiler_so'] = compiler + ' ' + opt + ' ' + ccshared if linker_so is not None: args['linker_so'] = linker_so --- 174,179 ---- # compilers if compiler is not None: ! (ccshared,opt,base) = sysconfig.get_config_vars('CCSHARED','OPT','BASECFLAGS') ! args['compiler_so'] = compiler + ' ' + opt + ' ' + ccshared + ' ' + base if linker_so is not None: args['linker_so'] = linker_so *************** *** 252,255 **** --- 252,261 ---- 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 + if sys.platform == "darwin": + add_dir_to_list(self.compiler.library_dirs, '/sw/lib') + add_dir_to_list(self.compiler.include_dirs, '/sw/include') if os.path.normpath(sys.prefix) != '/usr': From jvr@users.sourceforge.net Wed Jan 1 20:22:07 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:22:07 -0800 Subject: [Python-checkins] python/nondist/peps pep-0302.txt,1.11,1.12 Message-ID: <E18TpNP-0007ft-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv29486 Modified Files: pep-0302.txt Log Message: 2.3a1 integration note Index: pep-0302.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0302.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pep-0302.txt 30 Dec 2002 22:39:07 -0000 1.11 --- pep-0302.txt 1 Jan 2003 20:22:03 -0000 1.12 *************** *** 506,510 **** Implementation ! A C implementation is available as SourceForge patch 652586. http://www.python.org/sf/652586 --- 506,513 ---- 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. http://www.python.org/sf/652586 From montanaro@users.sourceforge.net Wed Jan 1 20:26:50 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:26:50 -0800 Subject: [Python-checkins] python/dist/src/Demo/scripts find-uname.py,NONE,1.1 Message-ID: <E18TpRy-00088z-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Demo/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv31282 Added Files: find-uname.py Log Message: Search for Unicode character names using regular expressions. --- NEW FILE: find-uname.py --- #!/usr/bin/env python """ For each argument on the command line, look for it in the set of all Unicode names. Arguments are treated as case-insensitive regular expressions, e.g.: % find-uname 'small letter a$' 'horizontal line' *** small letter a$ matches *** LATIN SMALL LETTER A (97) COMBINING LATIN SMALL LETTER A (867) CYRILLIC SMALL LETTER A (1072) PARENTHESIZED LATIN SMALL LETTER A (9372) CIRCLED LATIN SMALL LETTER A (9424) FULLWIDTH LATIN SMALL LETTER A (65345) *** horizontal line matches *** HORIZONTAL LINE EXTENSION (9135) """ import unicodedata import sys import re def main(args): unicode_names= [] for ix in range(sys.maxunicode+1): try: unicode_names.append( (ix, unicodedata.name(unichr(ix))) ) except ValueError: # no name for the character pass for arg in args: pat = re.compile(arg, re.I) matches = [(x,y) for (x,y) in unicode_names if pat.search(y) is not None] if matches: print "***", arg, "matches", "***" for (x,y) in matches: print "%s (%d)" % (y,x) if __name__ == "__main__": main(sys.argv[1:]) From montanaro@users.sourceforge.net Wed Jan 1 20:27:15 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:27:15 -0800 Subject: [Python-checkins] python/dist/src/Demo/scripts README,1.18,1.19 Message-ID: <E18TpSN-0008B9-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Demo/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv31431 Modified Files: README Log Message: add find-uname.py Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/scripts/README,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** README 2 Mar 1995 16:00:55 -0000 1.18 --- README 1 Jan 2003 20:27:13 -0000 1.19 *************** *** 4,7 **** --- 4,8 ---- fact.py Factorize numbers + find-uname.py Search for Unicode characters using regexps. from.py Summarize mailbox ftpstats.py Summarize ftp daemon log file From montanaro@users.sourceforge.net Wed Jan 1 20:33:40 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:33:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libconsts.tex,NONE,1.1 Message-ID: <E18TpYa-0000Gv-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv1021 Added Files: libconsts.tex Log Message: new section - builtin constants --- NEW FILE: libconsts.tex --- \section{Builtin Constants} A small number of constants live in the builtin namespace. They are: \begin{datadesc}{False} The false value of the \code{bool} type. \versionadded{2.3} \end{datadesc} \begin{datadesc}{True} The true value of the \code{bool} type. \versionadded{2.3} \end{datadesc} \begin{datadesc}{None} The sole value of \code{NoneType}. \code{None} is frequently used to represent the absence of a value, as when default arguments are not passed to a function. \end{datadesc} From montanaro@users.sourceforge.net Wed Jan 1 20:34:02 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:34:02 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib lib.tex,1.209,1.210 Message-ID: <E18TpYw-0000JA-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv1147 Modified Files: lib.tex Log Message: process libconsts.tex Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.209 retrieving revision 1.210 diff -C2 -d -r1.209 -r1.210 *** lib.tex 30 Dec 2002 22:34:10 -0000 1.209 --- lib.tex 1 Jan 2003 20:34:00 -0000 1.210 *************** *** 71,74 **** --- 71,75 ---- \input{libstdtypes} \input{libexcs} + \input{libconsts} \input{libpython} % Python Runtime Services From montanaro@users.sourceforge.net Wed Jan 1 20:37:17 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:37:17 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libobjs.tex,1.10,1.11 Message-ID: <E18Tpc5-0000Wv-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv2028 Modified Files: libobjs.tex Log Message: mention built-in constants. Index: libobjs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libobjs.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** libobjs.tex 30 Oct 2001 06:22:02 -0000 1.10 --- libobjs.tex 1 Jan 2003 20:37:14 -0000 1.11 *************** *** 1,5 **** ! \chapter{Built-in Functions, Types, and Exceptions \label{builtin}} ! Names for built-in exceptions and functions are found in a separate symbol table. This table is searched last when the interpreter looks up the meaning of a name, so local and global --- 1,6 ---- ! \chapter{Built-In Objects \label{builtin}} ! Names for built-in exceptions and functions and a number of constants are ! found in a separate symbol table. This table is searched last when the interpreter looks up the meaning of a name, so local and global *************** *** 12,15 **** --- 13,17 ---- \indexii{built-in}{exceptions} \indexii{built-in}{functions} + \indexii{built-in}{constants} \index{symbol table} From tim_one@users.sourceforge.net Wed Jan 1 20:52:15 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:52:15 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.132,1.133 doc.txt,1.76,1.77 test_datetime.py,1.91,1.92 Message-ID: <E18TpqZ-0001v7-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv5679 Modified Files: datetime.py doc.txt test_datetime.py Log Message: A quicker astimezone() implementation, rehabilitating an earlier suggestion from Guido, along with a formal correctness proof of the trickiest bit. The intricacy of the proof reveals how delicate this is, but also how robust the conclusion: correctness doesn't rely on dst() returning +- one hour (not all real time zones do!), it only relies on: 1. That dst() returns a (any) non-zero value if and only if daylight time is in effect. and 2. That the tzinfo subclass implements a consistent notion of time zone. The meaning of "consistent" was a hidden assumption, which is now an explicit requirement in the docs. Alas, it's an unverifiable (by the datetime implementation) requirement, but so it goes. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.132 retrieving revision 1.133 diff -C2 -d -r1.132 -r1.133 *** datetime.py 1 Jan 2003 04:12:00 -0000 1.132 --- datetime.py 1 Jan 2003 20:52:10 -0000 1.133 *************** *** 1620,1628 **** def astimezone(self, tz): _check_tzinfo_arg(tz) ! # This is somewhat convoluted because we can only call ! # tzinfo.utcoffset(dt) when dt.tzinfo is tzinfo. It's more ! # convoluted due to DST headaches (redundant spellings and ! # "missing" hours in local time -- see the tests for details). ! other = self.replace(tzinfo=tz) # this does no conversion # Don't call utcoffset unless necessary. First check trivial cases. --- 1620,1624 ---- def astimezone(self, tz): _check_tzinfo_arg(tz) ! other = self.replace(tzinfo=tz) # Don't call utcoffset unless necessary. First check trivial cases. *************** *** 1639,1699 **** return other ! total_added_to_other = otoff - myoff ! other += total_added_to_other ! # If tz is a fixed-offset class, we're done, but we can't know ! # whether it is. If it's a DST-aware class, and we're not near a ! # DST boundary, we're also done. If we crossed a DST boundary, ! # the offset will be different now, and that's our only clue. ! # Unfortunately, we can be in trouble even if we didn't cross a ! # DST boundary, if we landed on one of the DST "problem hours". ! newoff = other.utcoffset() ! if newoff is None: ! self._inconsistent_utcoffset_error() ! if newoff != otoff: ! delta = newoff - otoff ! total_added_to_other += delta ! other += delta otoff = other.utcoffset() if otoff is None: self._inconsistent_utcoffset_error() ! # If this is the first hour of DST, it may be a local time that ! # doesn't make sense on the local clock, in which case the naive ! # hour before it (in standard time) is equivalent and does make ! # sense on the local clock. So force that. ! alt = other - _HOUR ! altoff = alt.utcoffset() ! if altoff is None: ! self._inconsistent_utcoffset_error() ! # Are alt and other really the same time? They are iff ! # alt - altoff == other - otoff, iff ! # (other - _HOUR) - altoff = other - otoff, iff ! # otoff - altoff == _HOUR ! # Note that the Python comparison "alt == other" would return false, ! # though, because they have same tzinfo member, and utcoffset() is ! # ignored when comparing times w/ the same tzinfo. ! diff = otoff - altoff ! ! # Enable the assert if you're dubious; it's expensive. ! ##assert ((diff == _HOUR) == ! ## (alt.replace(tzinfo=None) - alt.utcoffset() == ! ## other.replace(tzinfo=None) - other.utcoffset())) ! if diff == _HOUR: ! return alt # use the local time that makes sense ! ! # There's still a problem with the unspellable (in local time) ! # hour after DST ends. other's local time now is ! # self + total_added_to_other, so self == other iff ! # self - myoff = other - otoff, iff ! # self - myoff = self + total_added_to_other - otoff, iff ! # total_added_to_other == otoff - myoff ! ##assert (self == other) == (total_added_to_other == otoff - myoff) ! if total_added_to_other == otoff - myoff: return other - # Else there's no way to spell self in zone other.tz. raise ValueError("astimezone(): the source datetimetz can't be " "expressed in the target timezone's local time") - def isoformat(self, sep='T'): s = super(datetimetz, self).isoformat(sep) --- 1635,1670 ---- return other ! # See the long comment block at the end of this file for an ! # explanation of this algorithm. That it always works requires a ! # pretty intricate proof. ! otdst = other.dst() ! if otdst is None: ! otdst = 0 ! total_added_to_other = otoff - otdst - myoff ! if total_added_to_other: ! other += total_added_to_other otoff = other.utcoffset() if otoff is None: self._inconsistent_utcoffset_error() + # The distance now from self to other is + # self - other == naive(self) - myoff - (naive(other) - otoff) == + # naive(self) - myoff - + # ((naive(self) + total_added_to_other - otoff) == + # - myoff - total_added_to_other + otoff + delta = otoff - myoff - total_added_to_other + ##assert (other == self) == (not delta) # expensive + if not delta: + return other ! # Must have crossed a DST switch point. ! total_added_to_other += delta ! other += delta ! otoff = other.utcoffset() ! ##assert (other == self) == (otoff - myoff == total_added_to_other) ! if otoff - myoff == total_added_to_other: return other raise ValueError("astimezone(): the source datetimetz can't be " "expressed in the target timezone's local time") def isoformat(self, sep='T'): s = super(datetimetz, self).isoformat(sep) *************** *** 1908,1911 **** --- 1879,1993 ---- del pickle + """ + Some time zone algebra. For a datetimetz x, let + x.n = x stripped of its timezone -- its naive time. + x.o = x.utcoffset(), and assuming that doesn't raise an exception or + return None + x.d = x.dst(), and assuming that doesn't raise an exception or + return None + x.s = x's standard offset, x.o - x.d + + Now some derived rules, where k is a duration (timedelta). + + 1. x.o = x.s + x.d + This follows from the definition of x.s. + + 2. If x and y have the same tzinfo member, x.s == y.s. + This is actually a requirement, an assumption we need to make about + sane tzinfo classes. + + 3. The naive UTC time corresponding to x is x.n - x.o. + This is again a requirement for a sane tzinfo class. + + 4. (x+k).s = x.s + This follows from #2, and that datimetimetz+timedelta preserves tzinfo. + + 5. (y+k).n = y.n + k + Again follows from how arithmetic is defined. + + Now we can explain x.astimezone(tz). Let's assume it's an interesting case + (meaning that the various tzinfo methods exist, and don't blow up or return + None when called). + + The function wants to return a datetimetz y with timezone tz, equivalent to x. + + By #3, we want + + y.n - y.o = x.n - x.o [1] + + The algorithm starts by attaching tz to x.n, and calling that y. So + x.n = y.n at the start. Then it wants to add a duration k to y, so that [1] + becomes true; in effect, we want to solve [2] for k: + + (y+k).n - (y+k).o = x.n - x.o [2] + + By #1, this is the same as + + (y+k).n - ((y+k).s + (y+k).d) = x.n - x.o [3] + + By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. + Substituting that into [3], + + x.n + k - (y+k).s - (y+k).d = x.n - x.o; the x.n terms cancel, leaving + k - (y+k).s - (y+k).d = - x.o; rearranging, + k = (y+k).s - x.o - (y+k).d; by #4, (y+k).s == y.s, so + k = y.s - x.o - (y+k).d; then by #1, y.s = y.o - y.d, so + k = y.o - y.d - x.o - (y+k).d + + On the RHS, (y+k).d can't be computed directly, but all the rest can be, and + we approximate k by ignoring the (y+k).d term at first. Note that k can't + be very large, since all offset-returning methods return a duration of + magnitude less than 24 hours. For that reason, if y is firmly in std time, + (y+k).d must be 0, so ignoring it has no consequence then. + + In any case, the new value is + + z = y + y.o - y.d - x.o + + If + z.n - z.o = x.n - x.o [4] + + then, we have an equivalent time, and are almost done. The insecurity here is + at the start of daylight time. Picture US Eastern for concreteness. The wall + time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good + sense then. A sensible Eastern tzinfo class will consider such a time to be + EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST on the + day DST starts. We want to return the 1:MM EST spelling because that's + the only spelling that makes sense on the local wall clock. + + Claim: When [4] is true, we have "the right" spelling in this endcase. No + further adjustment is necessary. + + Proof: The right spelling has z.d = 0, and the wrong spelling has z.d != 0 + (for US Eastern, the wrong spelling has z.d = 60 minutes, but we can't assume + that all time zones work this way -- we can assume a time zone is in daylight + time iff dst() doesn't return 0). By [4], and recalling that z.o = z.s + z.d, + + z.n - z.s - z.d = x.n - x.o [5] + + Also + + z.n = (y + y.o - y.d - x.o).n by the construction of z, which equals + y.n + y.o - y.d - x.o by #5. + + Plugging that into [5], + + y.n + y.o - y.d - x.o - z.s - z.d = x.n - x.o; cancelling the x.o terms, + y.n + y.o - y.d - z.s - z.d = x.n; but x.n = y.n too, so they also cancel, + y.o - y.d - z.s - z.d = 0; then y.o = y.s + y.d, so + y.s + y.d - y.d - z.s - z.d = 0; then the y.d terms cancel, + y.s - z.s - z.d = 0; but y and z are in the same timezone, so by #2 + y.s = z.s, and they also cancel, leaving + - z.d = 0; or, + z.d = 0 + + Therefore z is the standard-time spelling, and there's nothing left to do in + this case. + + Note that we actually proved something stronger: when [4] is true, it must + also be true that z.dst() returns 0. + + XXX Flesh out the rest of the algorithm. + """ def _test(): import test_datetime Index: doc.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v retrieving revision 1.76 retrieving revision 1.77 diff -C2 -d -r1.76 -r1.77 *** doc.txt 31 Dec 2002 15:56:31 -0000 1.76 --- doc.txt 1 Jan 2003 20:52:11 -0000 1.77 *************** *** 815,818 **** --- 815,830 ---- should be set. + An instance tz of a tzinfo subclass that models both standard and + daylight times must be consistent in this sense: + + tz.utcoffset(dt) - tz.dst(dt) + + must return the same result for every datetimetz dt with dt.tzinfo=tz. + For sane tzinfo subclasses, this expression yields the time zone's + "standard offset", which should not depend on the specific date and + time passed. The implementation of datetimetz.astimezone() relies on + this, but cannot detect violations; it's the programmer's + responsibility to ensure it. + These methods are called by a datetimetz or timetz object, in response to their methods of the same names. A datetimetz object passes itself as the *************** *** 1160,1164 **** XXX classes, one hour per year has two spellings in local time, and XXX another hour has no spelling in local time. ! - timetuple() --- 1172,1176 ---- XXX classes, one hour per year has two spellings in local time, and XXX another hour has no spelling in local time. ! - timetuple() Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** test_datetime.py 1 Jan 2003 04:12:00 -0000 1.91 --- test_datetime.py 1 Jan 2003 20:52:12 -0000 1.92 *************** *** 2718,2721 **** --- 2718,2746 ---- # self.convert_between_tz_and_utc(Central, Eastern) # can't work + def test_tricky(self): + # 22:00 on day before daylight starts. + fourback = self.dston - timedelta(hours=4) + ninewest = FixedOffset(-9*60, "-0900", 0) + fourback = fourback.astimezone(ninewest) + # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST. Since it's "after + # 2", we should get the 3 spelling. + # If we plug 22:00 the day before into Eastern, it "looks like std + # time", so its offset is returned as -5, and -5 - -9 = 4. Adding 4 + # to 22:00 lands on 2:00, which makes no sense in local time (the + # local clock jumps from 1 to 3). The point here is to make sure we + # get the 3 spelling. + expected = self.dston.replace(hour=3) + got = fourback.astimezone(Eastern).astimezone(None) + self.assertEqual(expected, got) + + # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST. In that + # case we want the 1:00 spelling. + sixutc = self.dston.replace(hour=6).astimezone(utc_real) + # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4, + # and adding -4-0 == -4 gives the 2:00 spelling. We want the 1:00 EST + # spelling. + expected = self.dston.replace(hour=1) + got = sixutc.astimezone(Eastern).astimezone(None) + self.assertEqual(expected, got) def test_suite(): From tim_one@users.sourceforge.net Wed Jan 1 20:57:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 01 Jan 2003 12:57:56 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.133,1.134 Message-ID: <E18Tpw4-0002M1-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv8956 Modified Files: datetime.py Log Message: Deleted now-unsed _HOUR global. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.133 retrieving revision 1.134 diff -C2 -d -r1.133 -r1.134 *** datetime.py 1 Jan 2003 20:52:10 -0000 1.133 --- datetime.py 1 Jan 2003 20:57:53 -0000 1.134 *************** *** 1523,1528 **** datetime.resolution = timedelta(microseconds=1) - _HOUR = timedelta(hours=1) - class datetimetz(datetime): --- 1523,1526 ---- From tim_one@users.sourceforge.net Wed Jan 1 21:51:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 01 Jan 2003 13:51:38 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.25,1.26 Message-ID: <E18Tqm2-0006Ed-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv23673/python/Doc/lib Modified Files: libdatetime.tex Log Message: A quicker astimezone() implementation, rehabilitating an earlier suggestion from Guido, along with a formal correctness proof of the trickiest bit. The intricacy of the proof reveals how delicate this is, but also how robust the conclusion: correctness doesn't rely on dst() returning +- one hour (not all real time zones do!), it only relies on: 1. That dst() returns a (any) non-zero value if and only if daylight time is in effect. and 2. That the tzinfo subclass implements a consistent notion of time zone. The meaning of "consistent" was a hidden assumption, which is now an explicit requirement in the docs. Alas, it's an unverifiable (by the datetime implementation) requirement, but so it goes. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** libdatetime.tex 31 Dec 2002 18:31:48 -0000 1.25 --- libdatetime.tex 1 Jan 2003 21:51:36 -0000 1.26 *************** *** 888,895 **** \class{timedelta} object representing a whole number of minutes in the same range. Most implementations of \method{utcoffset()} ! will probably look like: \begin{verbatim} ! return CONSTANT # fixed-offset class return CONSTANT + self.dst(dt) # daylight-aware class \end{verbatim} --- 888,895 ---- \class{timedelta} object representing a whole number of minutes in the same range. Most implementations of \method{utcoffset()} ! will probably look like one of these two: \begin{verbatim} ! return CONSTANT # fixed-offset class return CONSTANT + self.dst(dt) # daylight-aware class \end{verbatim} *************** *** 906,915 **** will wish to return different names depending on the specific value of \var{dt} passed, especially if the \class{tzinfo} class is ! accounting for DST. \end{methoddesc} \begin{methoddesc}{dst}{self, dt} ! Return the DST offset, in minutes east of UTC, or \code{None} if ! DST information isn't known. Return \code{0} if DST is not in effect. If DST is in effect, return the offset as an integer or \class{timedelta} object (see \method{utcoffset()} for details). --- 906,916 ---- will wish to return different names depending on the specific value of \var{dt} passed, especially if the \class{tzinfo} class is ! accounting for daylight time. \end{methoddesc} \begin{methoddesc}{dst}{self, dt} ! Return the daylight savings time (DST) adjustment, in minutes east of ! UTC, or \code{None} if DST information isn't known. Return \code{0} if ! DST is not in effect. If DST is in effect, return the offset as an integer or \class{timedelta} object (see \method{utcoffset()} for details). *************** *** 920,924 **** example, \method{datetimetz.timetuple()} calls its \member{tzinfo} member's \method{dst()} method to determine how the ! \member{tm_isdst} flag should be set. \end{methoddesc} --- 921,941 ---- example, \method{datetimetz.timetuple()} calls its \member{tzinfo} member's \method{dst()} method to determine how the ! \member{tm_isdst} flag should be set, and ! \method{datetimetz.astimezone()} calls \method{dst()} to account for ! DST changes when crossing time zones. ! ! An instance \var{tz} of a \class{tzinfo} subclass that models both ! standard and daylight times must be consistent in this sense: ! ! \code{tz.utcoffset(dt) - tz.dst(dt)} ! ! must return the same result for every \class{datetimetz} \var{dt} ! in a given year with \code{dt.tzinfo==tz} For sane \class{tzinfo} ! subclasses, this expression yields the time zone's "standard offset" ! within the year, which should be the same across all days in the year. ! The implementation of \method{datetimetz.astimezone()} relies on this, ! but cannot detect violations; it's the programmer's responsibility to ! ensure it. ! \end{methoddesc} From tim_one@users.sourceforge.net Wed Jan 1 21:51:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 01 Jan 2003 13:51:39 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.18,1.19 Message-ID: <E18Tqm3-0006En-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv23673/python/Lib/test Modified Files: test_datetime.py Log Message: A quicker astimezone() implementation, rehabilitating an earlier suggestion from Guido, along with a formal correctness proof of the trickiest bit. The intricacy of the proof reveals how delicate this is, but also how robust the conclusion: correctness doesn't rely on dst() returning +- one hour (not all real time zones do!), it only relies on: 1. That dst() returns a (any) non-zero value if and only if daylight time is in effect. and 2. That the tzinfo subclass implements a consistent notion of time zone. The meaning of "consistent" was a hidden assumption, which is now an explicit requirement in the docs. Alas, it's an unverifiable (by the datetime implementation) requirement, but so it goes. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** test_datetime.py 1 Jan 2003 04:18:51 -0000 1.18 --- test_datetime.py 1 Jan 2003 21:51:36 -0000 1.19 *************** *** 2704,2707 **** --- 2704,2732 ---- # self.convert_between_tz_and_utc(Central, Eastern) # can't work + def test_tricky(self): + # 22:00 on day before daylight starts. + fourback = self.dston - timedelta(hours=4) + ninewest = FixedOffset(-9*60, "-0900", 0) + fourback = fourback.astimezone(ninewest) + # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST. Since it's "after + # 2", we should get the 3 spelling. + # If we plug 22:00 the day before into Eastern, it "looks like std + # time", so its offset is returned as -5, and -5 - -9 = 4. Adding 4 + # to 22:00 lands on 2:00, which makes no sense in local time (the + # local clock jumps from 1 to 3). The point here is to make sure we + # get the 3 spelling. + expected = self.dston.replace(hour=3) + got = fourback.astimezone(Eastern).astimezone(None) + self.assertEqual(expected, got) + + # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST. In that + # case we want the 1:00 spelling. + sixutc = self.dston.replace(hour=6).astimezone(utc_real) + # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4, + # and adding -4-0 == -4 gives the 2:00 spelling. We want the 1:00 EST + # spelling. + expected = self.dston.replace(hour=1) + got = sixutc.astimezone(Eastern).astimezone(None) + self.assertEqual(expected, got) def test_suite(): From tim_one@users.sourceforge.net Wed Jan 1 21:51:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 01 Jan 2003 13:51:40 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.22,1.23 Message-ID: <E18Tqm4-0006Ex-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv23673/python/Modules Modified Files: datetimemodule.c Log Message: A quicker astimezone() implementation, rehabilitating an earlier suggestion from Guido, along with a formal correctness proof of the trickiest bit. The intricacy of the proof reveals how delicate this is, but also how robust the conclusion: correctness doesn't rely on dst() returning +- one hour (not all real time zones do!), it only relies on: 1. That dst() returns a (any) non-zero value if and only if daylight time is in effect. and 2. That the tzinfo subclass implements a consistent notion of time zone. The meaning of "consistent" was a hidden assumption, which is now an explicit requirement in the docs. Alas, it's an unverifiable (by the datetime implementation) requirement, but so it goes. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** datetimemodule.c 1 Jan 2003 04:48:01 -0000 1.22 --- datetimemodule.c 1 Jan 2003 21:51:37 -0000 1.23 *************** *** 4754,4759 **** PyObject *result; PyObject *temp; ! int selfoff, resoff, tempoff, total_added_to_result; int none; PyObject *tzinfo; --- 4754,4760 ---- PyObject *result; PyObject *temp; ! int selfoff, resoff, resdst, total_added_to_result; int none; + int delta; PyObject *tzinfo; *************** *** 4789,4822 **** return result; ! /* Add resoff-selfoff to result. */ ! total_added_to_result = resoff - selfoff; ! mm += total_added_to_result; ! if ((mm < 0 || mm >= 60) && ! normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) ! goto Fail; ! temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); ! if (temp == NULL) ! goto Fail; ! Py_DECREF(result); ! result = temp; ! ! /* If tz is a fixed-offset class, we're done, but we can't know ! * whether it is. If it's a DST-aware class, and we're not near a ! * DST boundary, we're also done. If we crossed a DST boundary, ! * the offset will be different now, and that's our only clue. ! * Unfortunately, we can be in trouble even if we didn't cross a ! * DST boundary, if we landed on one of the DST "problem hours". */ ! tempoff = call_utcoffset(tzinfo, result, &none); ! if (tempoff == -1 && PyErr_Occurred()) goto Fail; ! if (none) ! goto Inconsistent; ! ! if (tempoff != resoff) { ! /* We did cross a boundary. Try to correct. */ ! const int delta = tempoff - resoff; ! total_added_to_result += delta; ! mm += delta; if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) --- 4790,4804 ---- return result; ! /* See the long comment block at the end of this file for an ! * explanation of this algorithm. That it always works requires a ! * pretty intricate proof. */ ! resdst = call_dst(tzinfo, result, &none); ! if (resdst == -1 && PyErr_Occurred()) goto Fail; ! /* None and 0 dst() results are the same to us here. Debatable. */ ! total_added_to_result = resoff - resdst - selfoff; ! if (total_added_to_result != 0) { ! mm += total_added_to_result; if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) *************** *** 4833,4880 **** if (none) goto Inconsistent; ! } ! /* If this is the first hour of DST, it may be a local time that ! * doesn't make sense on the local clock, in which case the naive ! * hour before it (in standard time) is equivalent and does make ! * sense on the local clock. So force that. */ ! hh -= 1; ! if (hh < 0 && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); if (temp == NULL) goto Fail; ! tempoff = call_utcoffset(tzinfo, temp, &none); ! if (tempoff == -1 && PyErr_Occurred()) { ! Py_DECREF(temp); goto Fail; ! } ! if (none) { ! Py_DECREF(temp); goto Inconsistent; - } - /* Are temp and result really the same time? temp == result iff - * temp - tempoff == result - resoff, iff - * (result - HOUR) - tempoff = result - resoff, iff - * resoff - tempoff == HOUR - */ - if (resoff - tempoff == 60) { - /* use the local time that makes sense */ - Py_DECREF(result); - return temp; - } - Py_DECREF(temp); ! /* There's still a problem with the unspellable (in local time) ! * hour after DST ends. If self and result map to the same UTC time ! * time, we're OK, else the hour is unrepresentable in the tzinfo ! * zone. The result's local time now is ! * self + total_added_to_result, so self == result iff ! * self - selfoff == result - resoff, iff ! * self - selfoff == (self + total_added_to_result) - resoff, iff ! * - selfoff == total_added_to_result - resoff, iff ! * total_added_to_result == resoff - selfoff ! */ ! if (total_added_to_result == resoff - selfoff) return result; --- 4815,4854 ---- if (none) goto Inconsistent; ! } ! ! /* The distance now from self to result is ! * self - result == naive(self) - selfoff - (naive(result) - resoff) == ! * naive(self) - selfoff - ! * ((naive(self) + total_added_to_result - resoff) == ! * - selfoff - total_added_to_result + resoff. */ ! delta = resoff - selfoff - total_added_to_result; ! ! /* Now self and result are the same UTC time iff delta is 0. ! * If it is 0, we're done, although that takes some proving. ! */ ! if (delta == 0) ! return result; ! ! total_added_to_result += delta; ! mm += delta; ! if ((mm < 0 || mm >= 60) && ! normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; + temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); if (temp == NULL) goto Fail; ! Py_DECREF(result); ! result = temp; ! ! resoff = call_utcoffset(tzinfo, result, &none); ! if (resoff == -1 && PyErr_Occurred()) goto Fail; ! if (none) goto Inconsistent; ! if (resoff - selfoff == total_added_to_result) ! /* self and result are the same UTC time */ return result; *************** *** 5499,5500 **** --- 5473,5586 ---- return; } + + /* --------------------------------------------------------------------------- + Some time zone algebra. For a datetimetz x, let + x.n = x stripped of its timezone -- its naive time. + x.o = x.utcoffset(), and assuming that doesn't raise an exception or + return None + x.d = x.dst(), and assuming that doesn't raise an exception or + return None + x.s = x's standard offset, x.o - x.d + + Now some derived rules, where k is a duration (timedelta). + + 1. x.o = x.s + x.d + This follows from the definition of x.s. + + 2. If x and y have the same tzinfo member, x.s == y.s. + This is actually a requirement, an assumption we need to make about + sane tzinfo classes. + + 3. The naive UTC time corresponding to x is x.n - x.o. + This is again a requirement for a sane tzinfo class. + + 4. (x+k).s = x.s + This follows from #2, and that datimetimetz+timedelta preserves tzinfo. + + 5. (y+k).n = y.n + k + Again follows from how arithmetic is defined. + + Now we can explain x.astimezone(tz). Let's assume it's an interesting case + (meaning that the various tzinfo methods exist, and don't blow up or return + None when called). + + The function wants to return a datetimetz y with timezone tz, equivalent to x. + + By #3, we want + + y.n - y.o = x.n - x.o [1] + + The algorithm starts by attaching tz to x.n, and calling that y. So + x.n = y.n at the start. Then it wants to add a duration k to y, so that [1] + becomes true; in effect, we want to solve [2] for k: + + (y+k).n - (y+k).o = x.n - x.o [2] + + By #1, this is the same as + + (y+k).n - ((y+k).s + (y+k).d) = x.n - x.o [3] + + By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. + Substituting that into [3], + + x.n + k - (y+k).s - (y+k).d = x.n - x.o; the x.n terms cancel, leaving + k - (y+k).s - (y+k).d = - x.o; rearranging, + k = (y+k).s - x.o - (y+k).d; by #4, (y+k).s == y.s, so + k = y.s - x.o - (y+k).d; then by #1, y.s = y.o - y.d, so + k = y.o - y.d - x.o - (y+k).d + + On the RHS, (y+k).d can't be computed directly, but all the rest can be, and + we approximate k by ignoring the (y+k).d term at first. Note that k can't + be very large, since all offset-returning methods return a duration of + magnitude less than 24 hours. For that reason, if y is firmly in std time, + (y+k).d must be 0, so ignoring it has no consequence then. + + In any case, the new value is + + z = y + y.o - y.d - x.o + + If + z.n - z.o = x.n - x.o [4] + + then, we have an equivalent time, and are almost done. The insecurity here is + at the start of daylight time. Picture US Eastern for concreteness. The wall + time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good + sense then. A sensible Eastern tzinfo class will consider such a time to be + EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST on the + day DST starts. We want to return the 1:MM EST spelling because that's + the only spelling that makes sense on the local wall clock. + + Claim: When [4] is true, we have "the right" spelling in this endcase. No + further adjustment is necessary. + + Proof: The right spelling has z.d = 0, and the wrong spelling has z.d != 0 + (for US Eastern, the wrong spelling has z.d = 60 minutes, but we can't assume + that all time zones work this way -- we can assume a time zone is in daylight + time iff dst() doesn't return 0). By [4], and recalling that z.o = z.s + z.d, + + z.n - z.s - z.d = x.n - x.o [5] + + Also + + z.n = (y + y.o - y.d - x.o).n by the construction of z, which equals + y.n + y.o - y.d - x.o by #5. + + Plugging that into [5], + + y.n + y.o - y.d - x.o - z.s - z.d = x.n - x.o; cancelling the x.o terms, + y.n + y.o - y.d - z.s - z.d = x.n; but x.n = y.n too, so they also cancel, + y.o - y.d - z.s - z.d = 0; then y.o = y.s + y.d, so + y.s + y.d - y.d - z.s - z.d = 0; then the y.d terms cancel, + y.s - z.s - z.d = 0; but y and z are in the same timezone, so by #2 + y.s = z.s, and they also cancel, leaving + - z.d = 0; or, + z.d = 0 + + Therefore z is the standard-time spelling, and there's nothing left to do in + this case. + + Note that we actually proved something stronger: when [4] is true, it must + also be true that z.dst() returns 0. + + XXX Flesh out the rest of the algorithm. + --------------------------------------------------------------------------- */ From gvanrossum@users.sourceforge.net Thu Jan 2 02:24:25 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 01 Jan 2003 18:24:25 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts README,1.8,1.9 Message-ID: <E18Tv21-0007tj-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv30344 Modified Files: README Log Message: Add byext.py Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/README,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** README 10 Mar 2000 22:36:56 -0000 1.8 --- README 2 Jan 2003 02:24:22 -0000 1.9 *************** *** 5,8 **** --- 5,9 ---- See also the Demo/scripts directory! + byext.py Print lines/words/chars stats of files by extension byteyears.py Print product of a file's size and age checkpyc.py Check presence and validity of ".pyc" files From tim_one@users.sourceforge.net Thu Jan 2 03:06:42 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 01 Jan 2003 19:06:42 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.134,1.135 Message-ID: <E18Tvgw-0002DT-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv8239 Modified Files: datetime.py Log Message: Completed astimezone's correctness proof. That doesn't mean it's correct by your lights, it means that-- barring coding errors --it implements what it intended to implement. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.134 retrieving revision 1.135 diff -C2 -d -r1.134 -r1.135 *** datetime.py 1 Jan 2003 20:57:53 -0000 1.134 --- datetime.py 2 Jan 2003 03:06:39 -0000 1.135 *************** *** 1941,1945 **** In any case, the new value is ! z = y + y.o - y.d - x.o If --- 1941,1945 ---- In any case, the new value is ! z.n = y.n + y.o - y.d - x.o If *************** *** 1983,1991 **** this case. ! Note that we actually proved something stronger: when [4] is true, it must ! also be true that z.dst() returns 0. ! XXX Flesh out the rest of the algorithm. """ def _test(): import test_datetime --- 1983,2039 ---- this case. ! QED ! Note that we actually proved something stronger: [4] is true if and only if ! z.dst() returns 0. The "only if" part was proved directly. The "if" part ! is proved by starting with z.d = 0 and reading the proof bottom-up; all the ! steps are "iff", so are reversible. ! ! Next: if [4] isn't true, we're not done. It's helpful to step back and look ! at ! ! z.n = y.n + y.o - y.d - x.o = y.n-x.o + y.o-y.d ! ! from a higher level. Since y.n = x.n, the y.n-x.o part gives x's UTC ! equivalent hour. Then since y.s=y.o-y.d, the y.o-y.d part converts x's UTC ! equivalent into tz's standard time. IOW, z is the correct spelling of x in ! tz's standard time. ! If ! z.n - z.o != x.n - x.o ! despite that, then either (1) x is in the "unspellable hour" at the end ! of tz's daylight period; or, (2) z.n needs to be shifted into tz's daylight ! time. ! ! Assuming #2, that would be easy if we could ask the tzinfo object what the ! daylight offset would be if DST were in effect. And we could compute z.d, ! but we already have enough info to compute it from the quantities we know: ! ! Claim: The adjustment needed is adding (x.n-x.o)-(z.n-z.o) to z.n. ! ! Proof: By the comment following the last proof, z.d is not 0 now, and z.d ! is what we need to add to z.n (it's the "missing part" of the conversion from ! x's UTC equivalent to z's daylight time). ! ! z.d = z.o - z.s by #1; z.s = y.s since they're in the same time zone, so ! z.d = z.o - y.s; then y.s = y.o - y.d by #1, so ! z.d = z.o - (y.o - y.d); then since z.n = y.n+y.o-y.d-x.o, y.o-y.d= ! z.n-y.n+x.o, so ! z.d = z.o - (z.n - y.n + x.o); then x.n = y.n, so ! z.d = z.o - (z.n - x.n + x.o) ! and simple rearranging gives the desired ! z.d = (x.n - x.o) - (z.n - z.o) ! ! The code actually optimizes this some more, in a straightforward way. Letting ! ! z'.n = z.n + (x.n - x.o) - (z.n - z.o) ! ! we can again ask whether ! ! z'.n - z'.o = x.n - x.o ! ! If so, we're done. If not, the tzinfo class is insane, or we're trying to ! convert to the hour that can't be spelled in tz. """ + def _test(): import test_datetime From anthonybaxter@users.sourceforge.net Thu Jan 2 03:07:51 2003 From: anthonybaxter@users.sourceforge.net (anthonybaxter@users.sourceforge.net) Date: Wed, 01 Jan 2003 19:07:51 -0800 Subject: [Python-checkins] python/dist/src/Lib SocketServer.py,1.34,1.35 Message-ID: <E18Tvi3-0002H4-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv8500 Modified Files: SocketServer.py Log Message: Clearing out old patch queue. Patch #558547, make SocketServer more robust. This makes socketserver's close() method callable repeatedly without error - similar to other file-like objects. Index: SocketServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SocketServer.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** SocketServer.py 22 Nov 2002 14:22:49 -0000 1.34 --- SocketServer.py 2 Jan 2003 03:07:48 -0000 1.35 *************** *** 562,566 **** def finish(self): ! self.wfile.flush() self.wfile.close() self.rfile.close() --- 562,567 ---- def finish(self): ! if not self.wfile.closed: ! self.wfile.flush() self.wfile.close() self.rfile.close() From tim_one@users.sourceforge.net Thu Jan 2 03:15:04 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 01 Jan 2003 19:15:04 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.23,1.24 Message-ID: <E18Tvp2-0002jY-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv10306a/python/Modules Modified Files: datetimemodule.c Log Message: Completed astimezone's correctness proof. That doesn't mean it's correct by your lights, it means that-- barring coding errors --it implements what it intended to implement. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** datetimemodule.c 1 Jan 2003 21:51:37 -0000 1.23 --- datetimemodule.c 2 Jan 2003 03:14:59 -0000 1.24 *************** *** 5538,5542 **** In any case, the new value is ! z = y + y.o - y.d - x.o If --- 5538,5542 ---- In any case, the new value is ! z.n = y.n + y.o - y.d - x.o If *************** *** 5580,5586 **** this case. ! Note that we actually proved something stronger: when [4] is true, it must ! also be true that z.dst() returns 0. ! XXX Flesh out the rest of the algorithm. --------------------------------------------------------------------------- */ --- 5580,5633 ---- this case. ! QED ! Note that we actually proved something stronger: [4] is true if and only if ! z.dst() returns 0. The "only if" part was proved directly. The "if" part ! is proved by starting with z.d = 0 and reading the proof bottom-up; all the ! steps are "iff", so are reversible. ! ! Next: if [4] isn't true, we're not done. It's helpful to step back and look ! at ! ! z.n = y.n + y.o - y.d - x.o = y.n-x.o + y.o-y.d ! ! from a higher level. Since y.n = x.n, the y.n-x.o part gives x's UTC ! equivalent hour. Then since y.s=y.o-y.d, the y.o-y.d part converts x's UTC ! equivalent into tz's standard time. IOW, z is the correct spelling of x in ! tz's standard time. ! If ! z.n - z.o != x.n - x.o ! despite that, then either (1) x is in the "unspellable hour" at the end ! of tz's daylight period; or, (2) z.n needs to be shifted into tz's daylight ! time. ! ! Assuming #2, that would be easy if we could ask the tzinfo object what the ! daylight offset would be if DST were in effect. And we could compute z.d, ! but we already have enough info to compute it from the quantities we know: ! ! Claim: The adjustment needed is adding (x.n-x.o)-(z.n-z.o) to z.n. ! ! Proof: By the comment following the last proof, z.d is not 0 now, and z.d ! is what we need to add to z.n (it's the "missing part" of the conversion from ! x's UTC equivalent to z's daylight time). ! ! z.d = z.o - z.s by #1; z.s = y.s since they're in the same time zone, so ! z.d = z.o - y.s; then y.s = y.o - y.d by #1, so ! z.d = z.o - (y.o - y.d); then since z.n = y.n+y.o-y.d-x.o, y.o-y.d= ! z.n-y.n+x.o, so ! z.d = z.o - (z.n - y.n + x.o); then x.n = y.n, so ! z.d = z.o - (z.n - x.n + x.o) ! and simple rearranging gives the desired ! z.d = (x.n - x.o) - (z.n - z.o) ! ! The code actually optimizes this some more, in a straightforward way. Letting ! ! z'.n = z.n + (x.n - x.o) - (z.n - z.o) ! ! we can again ask whether ! ! z'.n - z'.o = x.n - x.o ! ! If so, we're done. If not, the tzinfo class is insane, or we're trying to ! convert to the hour that can't be spelled in tz. --------------------------------------------------------------------------- */ From fdrake@users.sourceforge.net Thu Jan 2 04:54:07 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Wed, 01 Jan 2003 20:54:07 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libfuncs.tex,1.125,1.126 Message-ID: <E18TxMt-0001YU-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv5969 Modified Files: libfuncs.tex Log Message: Document that apply() is deprecated. See: http://mail.python.org/pipermail/python-dev/2003-January/031556.html Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.125 retrieving revision 1.126 diff -C2 -d -r1.125 -r1.126 *** libfuncs.tex 17 Dec 2002 01:08:06 -0000 1.125 --- libfuncs.tex 2 Jan 2003 04:54:04 -0000 1.126 *************** *** 76,79 **** --- 76,82 ---- Use of \function{apply()} is not necessary since the ``extended call syntax,'' as used in the last example, is completely equivalent. + + \deprecated{2.3}{Use the extended call syntax instead, as described + above.} \end{funcdesc} From fdrake@users.sourceforge.net Thu Jan 2 04:54:24 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Wed, 01 Jan 2003 20:54:24 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libfuncs.tex,1.100.4.13,1.100.4.14 Message-ID: <E18TxNA-0001aR-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv6080 Modified Files: Tag: release22-maint libfuncs.tex Log Message: Document that apply() is deprecated. See: http://mail.python.org/pipermail/python-dev/2003-January/031556.html Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.100.4.13 retrieving revision 1.100.4.14 diff -C2 -d -r1.100.4.13 -r1.100.4.14 *** libfuncs.tex 1 Nov 2002 21:34:39 -0000 1.100.4.13 --- libfuncs.tex 2 Jan 2003 04:54:22 -0000 1.100.4.14 *************** *** 78,81 **** --- 78,84 ---- Use of \function{apply()} is not necessary since the ``extended call syntax,'' as used in the last example, is completely equivalent. + + \deprecated{2.3}{Use the extended call syntax instead, as described + above.} \end{funcdesc} From fdrake@users.sourceforge.net Thu Jan 2 05:00:15 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Wed, 01 Jan 2003 21:00:15 -0800 Subject: [Python-checkins] python/dist/src/Doc Makefile.deps,1.93,1.94 Message-ID: <E18TxSp-0002BZ-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc In directory sc8-pr-cvs1:/tmp/cvs-serv8393 Modified Files: Makefile.deps Log Message: Add dependency info for the recently added lib/libconsts.tex. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -d -r1.93 -r1.94 *** Makefile.deps 30 Dec 2002 23:01:14 -0000 1.93 --- Makefile.deps 2 Jan 2003 05:00:12 -0000 1.94 *************** *** 101,104 **** --- 101,105 ---- lib/libstdtypes.tex \ lib/libexcs.tex \ + lib/libconsts.tex \ lib/libfuncs.tex \ lib/libpython.tex \ From fdrake@users.sourceforge.net Thu Jan 2 05:13:53 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Wed, 01 Jan 2003 21:13:53 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libconsts.tex,1.1,1.2 Message-ID: <E18Txg1-0003oi-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv14650 Modified Files: libconsts.tex Log Message: - documented Ellipsis, NotImplemented - minor markup changes - indented for consistency with newer content Index: libconsts.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libconsts.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** libconsts.tex 1 Jan 2003 20:33:38 -0000 1.1 --- libconsts.tex 2 Jan 2003 05:13:51 -0000 1.2 *************** *** 1,20 **** ! \section{Builtin Constants} ! A small number of constants live in the builtin namespace. They are: \begin{datadesc}{False} ! The false value of the \code{bool} type. ! \versionadded{2.3} \end{datadesc} \begin{datadesc}{True} ! The true value of the \code{bool} type. ! \versionadded{2.3} \end{datadesc} \begin{datadesc}{None} ! The sole value of \code{NoneType}. \code{None} is frequently used to ! represent the absence of a value, as when default arguments are not passed ! to a function. \end{datadesc} --- 1,31 ---- ! \section{Built-in Constants} ! A small number of constants live in the built-in namespace. They are: \begin{datadesc}{False} ! The false value of the \class{bool} type. ! \versionadded{2.3} \end{datadesc} \begin{datadesc}{True} ! The true value of the \class{bool} type. ! \versionadded{2.3} \end{datadesc} \begin{datadesc}{None} ! The sole value of \code{\refmodule{types}.NoneType}. \code{None} is ! frequently used to represent the absence of a value, as when default ! arguments are not passed to a function. ! \end{datadesc} ! ! \begin{datadesc}{NotImplemented} ! Special value which can be returned by the ``rich comparison'' ! special methods (\method{__eq__()}, \method{__lt__()}, and friends), ! to indicate that the comparison is not implemented with respect to ! the other type. \end{datadesc} + \begin{datadesc}{Ellipsis} + Special value used in conjunction with extended slicing syntax. + % XXX Someone who understands extended slicing should fill in here. + \end{datadesc} From aimacintyre@users.sourceforge.net Thu Jan 2 12:38:42 2003 From: aimacintyre@users.sourceforge.net (aimacintyre@users.sourceforge.net) Date: Thu, 02 Jan 2003 04:38:42 -0800 Subject: [Python-checkins] python/dist/src/PC/os2emx Makefile,1.7,1.8 Message-ID: <E18U4cU-00081i-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/PC/os2emx In directory sc8-pr-cvs1:/tmp/cvs-serv30816 Modified Files: Makefile Log Message: fix a merge mistake - readline not built by default Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/os2emx/Makefile,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Makefile 31 Dec 2002 11:18:08 -0000 1.7 --- Makefile 2 Jan 2003 12:38:39 -0000 1.8 *************** *** 46,50 **** # I have had no success trying to use a DLL version, even with # the multithreading switch. ! GREADLINE= yes # Do you have the BSD DB library (v1.85) as included in the EMXBSD package? # NOTE: this library needs to be recompiled with a structure member --- 46,50 ---- # I have had no success trying to use a DLL version, even with # the multithreading switch. ! GREADLINE= no # Do you have the BSD DB library (v1.85) as included in the EMXBSD package? # NOTE: this library needs to be recompiled with a structure member From aimacintyre@users.sourceforge.net Thu Jan 2 12:40:43 2003 From: aimacintyre@users.sourceforge.net (aimacintyre@users.sourceforge.net) Date: Thu, 02 Jan 2003 04:40:43 -0800 Subject: [Python-checkins] python/dist/src/PC/os2emx config.c,1.2,1.3 Message-ID: <E18U4eR-0008Eg-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/PC/os2emx In directory sc8-pr-cvs1:/tmp/cvs-serv31636 Modified Files: config.c Log Message: bring structure closer to std config.c, whitespace normalisation Index: config.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/os2emx/config.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** config.c 10 Jun 2002 08:04:29 -0000 1.2 --- config.c 2 Jan 2003 12:40:41 -0000 1.3 *************** *** 37,40 **** --- 37,46 ---- #include "Python.h" + extern void initos2(); + extern void initsignal(); + #ifdef WITH_THREAD + extern void initthread(); + #endif + #if !HAVE_DYNAMIC_LOADING extern void init_codecs(); extern void init_curses(); *************** *** 42,55 **** extern void init_hotshot(); extern void init_locale(); ! extern void init_socket(); extern void init_sre(); extern void init_testcapi(); extern void init_weakref(); extern void initarray(); extern void initbinascii(); ! extern void initbsddb(); extern void initcPickle(); extern void initcStringIO(); extern void initcmath(); extern void initdl(); extern void initerrno(); --- 48,64 ---- extern void init_hotshot(); extern void init_locale(); ! extern void init_random(); extern void init_sre(); + extern void init_symtable(); extern void init_testcapi(); extern void init_weakref(); extern void initarray(); extern void initbinascii(); ! extern void initbsddb185(); ! extern void initbz2(); extern void initcPickle(); extern void initcStringIO(); extern void initcmath(); + extern void initdatetime(); extern void initdl(); extern void initerrno(); *************** *** 57,66 **** extern void initfpectl(); extern void initfpetest(); - extern void initgc(); extern void initimageop(); extern void initmath(); extern void initmd5(); - extern void initnew(); - extern void initos2(); extern void initoperator(); extern void initparser(); --- 66,72 ---- *************** *** 70,80 **** extern void initrgbimg(); extern void initrotor(); - extern void initselect(); extern void initsha(); - extern void initsignal(); extern void initstrop(); extern void initstruct(); extern void inittermios(); - extern void initthread(); extern void inittime(); extern void inittiming(); --- 76,83 ---- *************** *** 82,99 **** extern void initxreadlines(); extern void initxxsubtype(); extern void initzlib(); ! /* -- ADDMODULE MARKER 1 -- */ extern void PyMarshal_Init(); extern void initimp(); struct _inittab _PyImport_Inittab[] = { ! {"gc", initgc}, ! {"os2", initos2}, ! {"signal", initsignal}, #ifdef WITH_THREAD ! {"thread", initthread}, #endif #if !HAVE_DYNAMIC_LOADING --- 85,107 ---- extern void initxreadlines(); extern void initxxsubtype(); + extern void initzipimport(); extern void initzlib(); ! #ifdef USE_SOCKET ! extern void init_socket(); ! extern void initselect(); ! #endif ! #endif /* -- ADDMODULE MARKER 1 -- */ extern void PyMarshal_Init(); extern void initimp(); + extern void initgc(); struct _inittab _PyImport_Inittab[] = { ! {"os2", initos2}, ! {"signal", initsignal}, #ifdef WITH_THREAD ! {"thread", initthread}, #endif #if !HAVE_DYNAMIC_LOADING *************** *** 103,115 **** {"_hotshot", init_hotshot}, {"_locale", init_locale}, ! {"_sre", init_sre}, {"_testcapi", init_testcapi}, {"_weakref", init_weakref}, {"array", initarray}, {"binascii", initbinascii}, ! {"bsddb", initbsddb}, {"cPickle", initcPickle}, {"cStringIO", initcStringIO}, {"cmath", initcmath}, {"dl", initdl}, {"errno", initerrno}, --- 111,127 ---- {"_hotshot", init_hotshot}, {"_locale", init_locale}, ! {"_random", init_random}, ! {"_sre", init_sre}, ! {"_symtable", init_symtable}, {"_testcapi", init_testcapi}, {"_weakref", init_weakref}, {"array", initarray}, {"binascii", initbinascii}, ! {"bsddb185", initbsddb185}, ! {"bz2", initbz2}, {"cPickle", initcPickle}, {"cStringIO", initcStringIO}, {"cmath", initcmath}, + {"datetime", initdatetime}, {"dl", initdl}, {"errno", initerrno}, *************** *** 120,124 **** {"math", initmath}, {"md5", initmd5}, - {"new", initnew}, {"operator", initoperator}, {"parser", initparser}, --- 132,135 ---- *************** *** 137,162 **** {"xreadlines", initxreadlines}, {"xxsubtype", initxxsubtype}, {"zlib", initzlib}, #ifdef USE_SOCKET ! {"_socket", init_socket}, ! {"select", initselect}, #endif #endif - /* -- ADDMODULE MARKER 2 -- */ ! /* This module "lives in" with marshal.c */ ! {"marshal", PyMarshal_Init}, ! /* This lives it with import.c */ ! {"imp", initimp}, ! /* These entries are here for sys.builtin_module_names */ ! {"__main__", NULL}, ! {"__builtin__", NULL}, ! {"sys", NULL}, ! {"exceptions", NULL}, ! /* Sentinel */ ! {0, 0} }; --- 148,176 ---- {"xreadlines", initxreadlines}, {"xxsubtype", initxxsubtype}, + {"zipimport", initzipimport}, {"zlib", initzlib}, #ifdef USE_SOCKET ! {"_socket", init_socket}, ! {"select", initselect}, #endif #endif /* -- ADDMODULE MARKER 2 -- */ ! /* This module "lives in" with marshal.c */ ! {"marshal", PyMarshal_Init}, ! /* This lives it with import.c */ ! {"imp", initimp}, ! /* These entries are here for sys.builtin_module_names */ ! {"__main__", NULL}, ! {"__builtin__", NULL}, ! {"sys", NULL}, ! {"exceptions", NULL}, ! /* This lives in gcmodule.c */ ! {"gc", initgc}, ! ! /* Sentinel */ ! {0, 0} }; From aimacintyre@users.sourceforge.net Thu Jan 2 12:42:00 2003 From: aimacintyre@users.sourceforge.net (aimacintyre@users.sourceforge.net) Date: Thu, 02 Jan 2003 04:42:00 -0800 Subject: [Python-checkins] python/dist/src/PC/os2emx getpathp.c,1.1,1.2 Message-ID: <E18U4fg-0008Lb-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/PC/os2emx In directory sc8-pr-cvs1:/tmp/cvs-serv32063 Modified Files: getpathp.c Log Message: catch up with zipimport changes to std getpathp.c Index: getpathp.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/os2emx/getpathp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** getpathp.c 17 Feb 2002 05:23:30 -0000 1.1 --- getpathp.c 2 Jan 2003 12:41:58 -0000 1.2 *************** *** 251,254 **** --- 251,256 ---- char *pythonhome = Py_GetPythonHome(); char *envpath = getenv("PYTHONPATH"); + char zip_path[MAXPATHLEN+1]; + size_t len; get_progpath(); *************** *** 268,277 **** envpath = NULL; /* We need to construct a path from the following parts. (1) the PYTHONPATH environment variable, if set; ! (2) the PYTHONPATH config macro, with the leading "." of each component replaced with pythonhome, if set; ! (3) the directory containing the executable (argv0_path). ! The length calculation calculates #2 first. */ --- 270,293 ---- envpath = NULL; + /* Calculate zip archive path */ + strncpy(zip_path, progpath, MAXPATHLEN); + zip_path[MAXPATHLEN] = '\0'; + len = strlen(zip_path); + if (len > 4) { + zip_path[len-3] = 'z'; /* change ending to "zip" */ + zip_path[len-2] = 'i'; + zip_path[len-1] = 'p'; + } + else { + zip_path[0] = 0; + } + /* We need to construct a path from the following parts. (1) the PYTHONPATH environment variable, if set; ! (2) the zip archive file path; ! (3) the PYTHONPATH config macro, with the leading "." of each component replaced with pythonhome, if set; ! (4) the directory containing the executable (argv0_path). ! The length calculation calculates #3 first. */ *************** *** 290,293 **** --- 306,310 ---- bufsz += strlen(PYTHONPATH) + 1; bufsz += strlen(argv0_path) + 1; + bufsz += strlen(zip_path) + 1; if (envpath != NULL) bufsz += strlen(envpath) + 1; *************** *** 310,313 **** --- 327,335 ---- if (envpath) { strcpy(buf, envpath); + buf = strchr(buf, '\0'); + *buf++ = DELIM; + } + if (zip_path[0]) { + strcpy(buf, zip_path); buf = strchr(buf, '\0'); *buf++ = DELIM; From aimacintyre@users.sourceforge.net Thu Jan 2 12:45:37 2003 From: aimacintyre@users.sourceforge.net (aimacintyre@users.sourceforge.net) Date: Thu, 02 Jan 2003 04:45:37 -0800 Subject: [Python-checkins] python/dist/src/Modules socketmodule.c,1.249,1.250 Message-ID: <E18U4jB-0000GT-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv960 Modified Files: socketmodule.c Log Message: OS/2 sockets do not support AF_UNIX, even though EMX headers define it Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.249 retrieving revision 1.250 diff -C2 -d -r1.249 -r1.250 *** socketmodule.c 11 Dec 2002 13:10:57 -0000 1.249 --- socketmodule.c 2 Jan 2003 12:45:34 -0000 1.250 *************** *** 764,768 **** } ! #ifdef AF_UNIX case AF_UNIX: { --- 764,768 ---- } ! #if defined(AF_UNIX) && !defined(PYOS_OS2) case AF_UNIX: { *************** *** 838,842 **** switch (s->sock_family) { ! #ifdef AF_UNIX case AF_UNIX: { --- 838,842 ---- switch (s->sock_family) { ! #if defined(AF_UNIX) && !defined(PYOS_OS2) case AF_UNIX: { *************** *** 961,965 **** switch (s->sock_family) { ! #ifdef AF_UNIX case AF_UNIX: { --- 961,965 ---- switch (s->sock_family) { ! #if defined(AF_UNIX) && !defined(PYOS_OS2) case AF_UNIX: { *************** *** 3195,3199 **** PyModule_AddIntConstant(m, "AF_INET6", AF_INET6); #endif /* AF_INET6 */ ! #ifdef AF_UNIX PyModule_AddIntConstant(m, "AF_UNIX", AF_UNIX); #endif /* AF_UNIX */ --- 3195,3199 ---- PyModule_AddIntConstant(m, "AF_INET6", AF_INET6); #endif /* AF_INET6 */ ! #if defined(AF_UNIX) && !defined(PYOS_OS2) PyModule_AddIntConstant(m, "AF_UNIX", AF_UNIX); #endif /* AF_UNIX */ From aimacintyre@users.sourceforge.net Thu Jan 2 12:49:02 2003 From: aimacintyre@users.sourceforge.net (aimacintyre@users.sourceforge.net) Date: Thu, 02 Jan 2003 04:49:02 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_socketserver.py,1.7,1.8 Message-ID: <E18U4mU-0000dw-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv2433 Modified Files: test_socketserver.py Log Message: EMX fork() emulation not good enough to cope with test_socketserver Index: test_socketserver.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_socketserver.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_socketserver.py 23 Jul 2002 19:04:03 -0000 1.7 --- test_socketserver.py 2 Jan 2003 12:49:00 -0000 1.8 *************** *** 125,132 **** tcpservers = [TCPServer, ThreadingTCPServer] ! if hasattr(os, 'fork'): tcpservers.append(ForkingTCPServer) udpservers = [UDPServer, ThreadingUDPServer] ! if hasattr(os, 'fork'): udpservers.append(ForkingUDPServer) --- 125,132 ---- tcpservers = [TCPServer, ThreadingTCPServer] ! if hasattr(os, 'fork') and os.name not in ('os2',): tcpservers.append(ForkingTCPServer) udpservers = [UDPServer, ThreadingUDPServer] ! if hasattr(os, 'fork') and os.name not in ('os2',): udpservers.append(ForkingUDPServer) From jvr@users.sourceforge.net Thu Jan 2 12:55:50 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 02 Jan 2003 04:55:50 -0800 Subject: [Python-checkins] python/dist/src/Modules zipimport.c,1.6,1.7 Message-ID: <E18U4t4-0001JJ-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv1959/Modules Modified Files: zipimport.c Log Message: Ugh, zipimport is virtually broken in 2.3a1 :-( It worked by accident in the test set as it only tested with a zip archive in the current directory, but it doesn't work at all for packages when the zip archive was specified as an absolute path. It's a real embarrassing bug: a strchr call should have been strrchr; fever apparently implies dyslexia. Second stupid bug: the zipimport test failed with a name error __importer__ (which I had renamed to __loader__ everywhere but here). I would've sworn I ran the test after that change but that can't be true. What I don't understand that noone reported a failing test_zipimport.py before the release of 2.3a1. Index: zipimport.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zipimport.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** zipimport.c 31 Dec 2002 15:47:42 -0000 1.6 --- zipimport.c 2 Jan 2003 12:55:48 -0000 1.7 *************** *** 104,108 **** } /* back up one path element */ ! p = strchr(buf, SEP); if (prefix != NULL) *prefix = SEP; --- 104,108 ---- } /* back up one path element */ ! p = strrchr(buf, SEP); if (prefix != NULL) *prefix = SEP; From jvr@users.sourceforge.net Thu Jan 2 12:55:51 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 02 Jan 2003 04:55:51 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_zipimport.py,1.1,1.2 Message-ID: <E18U4t5-0001JP-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv1959/Lib/test Modified Files: test_zipimport.py Log Message: Ugh, zipimport is virtually broken in 2.3a1 :-( It worked by accident in the test set as it only tested with a zip archive in the current directory, but it doesn't work at all for packages when the zip archive was specified as an absolute path. It's a real embarrassing bug: a strchr call should have been strrchr; fever apparently implies dyslexia. Second stupid bug: the zipimport test failed with a name error __importer__ (which I had renamed to __loader__ everywhere but here). I would've sworn I ran the test after that change but that can't be true. What I don't understand that noone reported a failing test_zipimport.py before the release of 2.3a1. Index: test_zipimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zipimport.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_zipimport.py 30 Dec 2002 22:08:03 -0000 1.1 --- test_zipimport.py 2 Jan 2003 12:55:48 -0000 1.2 *************** *** 31,35 **** TESTMOD = "ziptestmodule" TESTPACK = "ziptestpackage" ! TEMP_ZIP = "junk95142.zip" --- 31,36 ---- TESTMOD = "ziptestmodule" TESTPACK = "ziptestpackage" ! TESTPACK2 = "ziptestpackage2" ! TEMP_ZIP = os.path.abspath("junk95142.zip") *************** *** 140,148 **** def testDeepPackage(self): packdir = TESTPACK + os.sep ! packdir2 = packdir + packdir files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc), packdir2 + "__init__" + pyc_ext: (NOW, test_pyc), packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)} ! self.doTest(pyc_ext, files, TESTPACK, TESTPACK, TESTMOD) def testGetData(self): --- 141,149 ---- def testDeepPackage(self): packdir = TESTPACK + os.sep ! packdir2 = packdir + TESTPACK2 + os.sep files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc), packdir2 + "__init__" + pyc_ext: (NOW, test_pyc), packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)} ! self.doTest(pyc_ext, files, TESTPACK, TESTPACK2, TESTMOD) def testGetData(self): *************** *** 164,168 **** def get_file(): return __file__ ! if __importer__.get_data("some.data") != "some data": raise AssertionError, "bad data"\n""" pyc = make_pyc(compile(src, "<???>", "exec"), NOW) --- 165,169 ---- def get_file(): return __file__ ! if __loader__.get_data("some.data") != "some data": raise AssertionError, "bad data"\n""" pyc = make_pyc(compile(src, "<???>", "exec"), NOW) From gvanrossum@users.sourceforge.net Thu Jan 2 12:59:01 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 02 Jan 2003 04:59:01 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.135,1.136 Message-ID: <E18U4w9-0001dC-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv6207 Modified Files: datetime.py Log Message: Added more reference URLs. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.135 retrieving revision 1.136 diff -C2 -d -r1.135 -r1.136 *** datetime.py 2 Jan 2003 03:06:39 -0000 1.135 --- datetime.py 2 Jan 2003 12:58:58 -0000 1.136 *************** *** 4,7 **** --- 4,14 ---- See also http://dir.yahoo.com/Reference/calendars/ + + For a primer on DST, including many current DST rules, see + http://webexhibits.org/daylightsaving/ + + For more about DST than you ever wanted to know, see + ftp://elsie.nci.nih.gov/pub/ + """ From jvr@users.sourceforge.net Thu Jan 2 13:13:03 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 02 Jan 2003 05:13:03 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bundlebuilder.py,1.1,1.2 Message-ID: <E18U59j-0002xU-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv10779/Lib/plat-mac Modified Files: bundlebuilder.py Log Message: Replaced imp.set_frozenmodules() cruft with proper zipimport support. This work uncovered the zipimport bug in 2.3a1 -- wish I'd had time to do this before the release :-(. Index: bundlebuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bundlebuilder.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** bundlebuilder.py 30 Dec 2002 22:04:20 -0000 1.1 --- bundlebuilder.py 2 Jan 2003 13:13:01 -0000 1.2 *************** *** 208,212 **** MAGIC = imp.get_magic() ! USE_FROZEN = hasattr(imp, "set_frozenmodules") # For standalone apps, we have our own minimal site.py. We don't need --- 208,212 ---- MAGIC = imp.get_magic() ! USE_ZIPIMPORT = "zipimport" in sys.builtin_module_names # For standalone apps, we have our own minimal site.py. We don't need *************** *** 217,242 **** """ ! if USE_FROZEN: ! FROZEN_ARCHIVE = "FrozenModules.marshal" ! SITE_PY += """\ ! # bootstrapping ! import imp, marshal ! f = open(sys.path[0] + "/%s", "rb") ! imp.set_frozenmodules(marshal.load(f)) ! f.close() ! """ % FROZEN_ARCHIVE SITE_CO = compile(SITE_PY, "<-bundlebuilder.py->", "exec") EXT_LOADER = """\ ! import imp, sys, os ! for p in sys.path: ! path = os.path.join(p, "%(filename)s") ! if os.path.exists(path): ! break ! else: ! assert 0, "file not found: %(filename)s" ! mod = imp.load_dynamic("%(name)s", path) ! sys.modules["%(name)s"] = mod """ --- 217,244 ---- """ ! if USE_ZIPIMPORT: ! ZIP_ARCHIVE = "Modules.zip" ! SITE_PY += "sys.path.append(sys.path[0] + '/%s')\n" % ZIP_ARCHIVE ! def getPycData(fullname, code, ispkg): ! if ispkg: ! fullname += ".__init__" ! path = fullname.replace(".", os.sep) + PYC_EXT ! return path, MAGIC + '\0\0\0\0' + marshal.dumps(code) SITE_CO = compile(SITE_PY, "<-bundlebuilder.py->", "exec") EXT_LOADER = """\ ! def __load(): ! import imp, sys, os ! for p in sys.path: ! path = os.path.join(p, "%(filename)s") ! if os.path.exists(path): ! break ! else: ! assert 0, "file not found: %(filename)s" ! mod = imp.load_dynamic("%(name)s", path) ! ! __load() ! del __load """ *************** *** 385,405 **** self.message("Adding Python modules", 1) ! if USE_FROZEN: ! # This anticipates the acceptance of this patch: ! # http://www.python.org/sf/642578 ! # Create a file containing all modules, frozen. ! frozenmodules = [] ! for name, code, ispkg in self.pymodules: ! if ispkg: ! self.message("Adding Python package %s" % name, 2) ! else: ! self.message("Adding Python module %s" % name, 2) ! frozenmodules.append((name, marshal.dumps(code), ispkg)) ! frozenmodules = tuple(frozenmodules) ! relpath = pathjoin("Contents", "Resources", FROZEN_ARCHIVE) abspath = pathjoin(self.bundlepath, relpath) ! f = open(abspath, "wb") ! marshal.dump(frozenmodules, f) ! f.close() # add site.pyc sitepath = pathjoin(self.bundlepath, "Contents", "Resources", --- 387,401 ---- self.message("Adding Python modules", 1) ! if USE_ZIPIMPORT: ! # Create a zip file containing all modules as pyc. ! import zipfile ! relpath = pathjoin("Contents", "Resources", ZIP_ARCHIVE) abspath = pathjoin(self.bundlepath, relpath) ! zf = zipfile.ZipFile(abspath, "w", zipfile.ZIP_DEFLATED) ! for name, code, ispkg in self.pymodules: ! self.message("Adding Python module %s" % name, 2) ! path, pyc = getPycData(name, code, ispkg) ! zf.writestr(path, pyc) ! zf.close() # add site.pyc sitepath = pathjoin(self.bundlepath, "Contents", "Resources", *************** *** 439,442 **** --- 435,441 ---- import modulefinder mf = modulefinder.ModuleFinder(excludes=self.excludeModules) + if USE_ZIPIMPORT: + # zipimport imports zlib, must add it manually + mf.import_hook("zlib") # manually add our own site.py site = mf.add_module("site") *************** *** 461,467 **** path = mod.__file__ filename = os.path.basename(path) ! if USE_FROZEN: ! # "proper" freezing, put extensions in Contents/Resources/, ! # freeze a tiny "loader" program. Due to Thomas Heller. dstpath = pathjoin("Contents", "Resources", filename) source = EXT_LOADER % {"name": name, "filename": filename} --- 460,467 ---- path = mod.__file__ filename = os.path.basename(path) ! if USE_ZIPIMPORT: ! # Python modules are stored in a Zip archive, but put ! # extensions in Contents/Resources/.a and add a tiny "loader" ! # program in the Zip archive. Due to Thomas Heller. dstpath = pathjoin("Contents", "Resources", filename) source = EXT_LOADER % {"name": name, "filename": filename} *************** *** 476,482 **** if mod.__code__ is not None: ispkg = mod.__path__ is not None ! if not USE_FROZEN or name != "site": # Our site.py is doing the bootstrapping, so we must ! # include a real .pyc file if USE_FROZEN is True. self.pymodules.append((name, mod.__code__, ispkg)) --- 476,482 ---- if mod.__code__ is not None: ispkg = mod.__path__ is not None ! if not USE_ZIPIMPORT or name != "site": # Our site.py is doing the bootstrapping, so we must ! # include a real .pyc file if USE_ZIPIMPORT is True. self.pymodules.append((name, mod.__code__, ispkg)) *************** *** 547,554 **** def writePyc(code, path): f = open(path, "wb") - f.write("\0" * 8) # don't bother about a time stamp - marshal.dump(code, f) - f.seek(0, 0) f.write(MAGIC) f.close() --- 547,553 ---- def writePyc(code, path): f = open(path, "wb") f.write(MAGIC) + f.write("\0" * 4) # don't bother about a time stamp + marshal.dump(code, f) f.close() From akuchling@users.sourceforge.net Thu Jan 2 13:42:34 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 02 Jan 2003 05:42:34 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.95,1.96 Message-ID: <E18U5cI-0006EU-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv23930 Modified Files: whatsnew23.tex Log Message: Fix an example Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.95 retrieving revision 1.96 diff -C2 -d -r1.95 -r1.96 *** whatsnew23.tex 31 Dec 2002 18:34:54 -0000 1.95 --- whatsnew23.tex 2 Jan 2003 13:42:32 -0000 1.96 *************** *** 80,84 **** Set([]) >>> S1.union_update(S2) - Set([1, 2, 3, 4, 5, 6]) >>> S1 Set([1, 2, 3, 4, 5, 6]) --- 80,83 ---- *************** *** 2016,2020 **** suggestions, corrections and assistance with various drafts of this article: Simon Brunning, Michael Chermside, Scott David Daniels, ! Fred~L. Drake, Jr., Raymond Hettinger, Michael Hudson, Detlef Lannert, Martin von L\"owis, Andrew MacIntyre, Lalo Martins, Gustavo Niemeyer, Neal Norwitz, Chris Reedy, Vinay Sajip, Neil Schemenauer, Jason --- 2015,2019 ---- suggestions, corrections and assistance with various drafts of this article: Simon Brunning, Michael Chermside, Scott David Daniels, ! Fred~L. Drake, Jr., Kelly Gerber, Raymond Hettinger, Michael Hudson, Detlef Lannert, Martin von L\"owis, Andrew MacIntyre, Lalo Martins, Gustavo Niemeyer, Neal Norwitz, Chris Reedy, Vinay Sajip, Neil Schemenauer, Jason From nnorwitz@users.sourceforge.net Thu Jan 2 14:56:41 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 02 Jan 2003 06:56:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_logging.py,NONE,1.1 Message-ID: <E18U6m1-0006xt-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv26301/Lib/test Added Files: test_logging.py Log Message: SF #660795 Add a test for logging from Vinay Sajip (module author) --- NEW FILE: test_logging.py --- #!/usr/bin/env python # # Copyright 2001-2002 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # This file is part of the Python logging distribution. See # http://www.red-dove.com/python_logging.html # """Test harness for the logging module. Run all tests. Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved. """ from select import select import os, sys, string, struct, types, cPickle, cStringIO import socket, threading, time, locale import logging, logging.handlers, logging.config locale.setlocale(locale.LC_ALL, '') BANNER = "-- %-10s %-6s ---------------------------------------------------\n" #---------------------------------------------------------------------------- # Log receiver #---------------------------------------------------------------------------- TIMEOUT = 10 from SocketServer import ThreadingTCPServer, StreamRequestHandler class LogRecordStreamHandler(StreamRequestHandler): """ Handler for a streaming logging request. It basically logs the record using whatever logging policy is configured locally. """ def handle(self): """ Handle multiple requests - each expected to be a 4-byte length, followed by the LogRecord in pickle format. Logs the record according to whatever policy is configured locally. """ while 1: try: chunk = self.connection.recv(4) if len(chunk) < 4: break slen = struct.unpack(">L", chunk)[0] #print slen chunk = self.connection.recv(slen) while len(chunk) < slen: chunk = chunk + self.connection.recv(slen - len(chunk)) obj = self.unPickle(chunk) record = logging.LogRecord(None, None, "", 0, "", (), None) record.__dict__.update(obj) self.handleLogRecord(record) except: raise def unPickle(self, data): return cPickle.loads(data) def handleLogRecord(self, record): logname = "logrecv.tcp." + record.name record.msg = record.msg + " (via " + logname + ")" logger = logging.getLogger(logname) logger.handle(record) class LogRecordSocketReceiver(ThreadingTCPServer): """ A simple-minded TCP socket-based logging receiver suitable for test purposes. """ allow_reuse_address = 1 def __init__(self, host='localhost', port=logging.handlers.DEFAULT_TCP_LOGGING_PORT, handler=LogRecordStreamHandler): ThreadingTCPServer.__init__(self, (host, port), handler) self.abort = 0 self.timeout = 1 def serve_until_stopped(self): abort = 0 while not abort: rd, wr, ex = select([self.socket.fileno()], [], [], self.timeout) if rd: self.handle_request() abort = self.abort def runTCP(tcpserver): tcpserver.serve_until_stopped() #---------------------------------------------------------------------------- # Test 0 #---------------------------------------------------------------------------- msgcount = 0 def nextmessage(): global msgcount rv = "Message %d" % msgcount msgcount = msgcount + 1 return rv def test0(): ERR = logging.getLogger("ERR") ERR.setLevel(logging.ERROR) INF = logging.getLogger("INF") INF.setLevel(logging.INFO) INF_ERR = logging.getLogger("INF.ERR") INF_ERR.setLevel(logging.ERROR) DEB = logging.getLogger("DEB") DEB.setLevel(logging.DEBUG) INF_UNDEF = logging.getLogger("INF.UNDEF") INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF") UNDEF = logging.getLogger("UNDEF") GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF") CHILD = logging.getLogger("INF.BADPARENT") #These should log ERR.log(logging.FATAL, nextmessage()) ERR.error(nextmessage()) INF.log(logging.FATAL, nextmessage()) INF.error(nextmessage()) INF.warn(nextmessage()) INF.info(nextmessage()) INF_UNDEF.log(logging.FATAL, nextmessage()) INF_UNDEF.error(nextmessage()) INF_UNDEF.warn (nextmessage()) INF_UNDEF.info (nextmessage()) INF_ERR.log(logging.FATAL, nextmessage()) INF_ERR.error(nextmessage()) INF_ERR_UNDEF.log(logging.FATAL, nextmessage()) INF_ERR_UNDEF.error(nextmessage()) DEB.log(logging.FATAL, nextmessage()) DEB.error(nextmessage()) DEB.warn (nextmessage()) DEB.info (nextmessage()) DEB.debug(nextmessage()) UNDEF.log(logging.FATAL, nextmessage()) UNDEF.error(nextmessage()) UNDEF.warn (nextmessage()) UNDEF.info (nextmessage()) GRANDCHILD.log(logging.FATAL, nextmessage()) CHILD.log(logging.FATAL, nextmessage()) #These should not log ERR.warn(nextmessage()) ERR.info(nextmessage()) ERR.debug(nextmessage()) INF.debug(nextmessage()) INF_UNDEF.debug(nextmessage()) INF_ERR.warn(nextmessage()) INF_ERR.info(nextmessage()) INF_ERR.debug(nextmessage()) INF_ERR_UNDEF.warn(nextmessage()) INF_ERR_UNDEF.info(nextmessage()) INF_ERR_UNDEF.debug(nextmessage()) INF.info("Messages should bear numbers 0 through 24.") #---------------------------------------------------------------------------- # Test 1 #---------------------------------------------------------------------------- # # First, we define our levels. There can be as many as you want - the only # limitations are that they should be integers, the lowest should be > 0 and # larger values mean less information being logged. If you need specific # level values which do not fit into these limitations, you can use a # mapping dictionary to convert between your application levels and the # logging system. # SILENT = 10 TACITURN = 9 TERSE = 8 EFFUSIVE = 7 SOCIABLE = 6 VERBOSE = 5 TALKATIVE = 4 GARRULOUS = 3 CHATTERBOX = 2 BORING = 1 LEVEL_RANGE = range(BORING, SILENT + 1) # # Next, we define names for our levels. You don't need to do this - in which # case the system will use "Level n" to denote the text for the level. # my_logging_levels = { SILENT : 'Silent', TACITURN : 'Taciturn', TERSE : 'Terse', EFFUSIVE : 'Effusive', SOCIABLE : 'Sociable', VERBOSE : 'Verbose', TALKATIVE : 'Talkative', GARRULOUS : 'Garrulous', CHATTERBOX : 'Chatterbox', BORING : 'Boring', } # # Now, to demonstrate filtering: suppose for some perverse reason we only # want to print out all except GARRULOUS messages. Let's create a filter for # this purpose... # class SpecificLevelFilter(logging.Filter): def __init__(self, lvl): self.level = lvl def filter(self, record): return self.level != record.levelno class GarrulousFilter(SpecificLevelFilter): def __init__(self): SpecificLevelFilter.__init__(self, GARRULOUS) # # Now, let's demonstrate filtering at the logger. This time, use a filter # which excludes SOCIABLE and TACITURN messages. Note that GARRULOUS events # are still excluded. # class VerySpecificFilter(logging.Filter): def filter(self, record): return record.levelno not in [SOCIABLE, TACITURN] def message(s): sys.stdout.write("%s\n" % s) SHOULD1 = "This should only be seen at the '%s' logging level (or lower)" def test1(): # # Now, tell the logging system to associate names with our levels. # for lvl in my_logging_levels.keys(): logging.addLevelName(lvl, my_logging_levels[lvl]) # # Now, define a test function which logs an event at each of our levels. # def doLog(log): for lvl in LEVEL_RANGE: log.log(lvl, SHOULD1, logging.getLevelName(lvl)) log = logging.getLogger("") hdlr = log.handlers[0] # # Set the logging level to each different value and call the utility # function to log events. # In the output, you should see that each time round the loop, the number of # logging events which are actually output decreases. # for lvl in LEVEL_RANGE: message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl)) log.setLevel(lvl) doLog(log) # # Now, we demonstrate level filtering at the handler level. Tell the # handler defined above to filter at level 'SOCIABLE', and repeat the # above loop. Compare the output from the two runs. # hdlr.setLevel(SOCIABLE) message("-- Filtering at handler level to SOCIABLE --") for lvl in LEVEL_RANGE: message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl)) log.setLevel(lvl) doLog(log) hdlr.setLevel(0) #turn off level filtering at the handler garr = GarrulousFilter() hdlr.addFilter(garr) message("-- Filtering using GARRULOUS filter --") for lvl in LEVEL_RANGE: message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl)) log.setLevel(lvl) doLog(log) spec = VerySpecificFilter() log.addFilter(spec) message("-- Filtering using specific filter for SOCIABLE, TACITURN --") for lvl in LEVEL_RANGE: message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl)) log.setLevel(lvl) doLog(log) log.removeFilter(spec) hdlr.removeFilter(garr) #Undo the one level which clashes...for regression tests logging.addLevelName(logging.DEBUG, "DEBUG") #---------------------------------------------------------------------------- # Test 2 #---------------------------------------------------------------------------- MSG = "-- logging %d at INFO, messages should be seen every 10 events --" def test2(): logger = logging.getLogger("") sh = logger.handlers[0] logger.removeHandler(sh) mh = logging.handlers.MemoryHandler(10,logging.WARN, sh) logger.setLevel(logging.DEBUG) logger.addHandler(mh) message("-- logging at DEBUG, nothing should be seen yet --") logger.debug("Debug message") message("-- logging at INFO, nothing should be seen yet --") logger.info("Info message") message("-- logging at WARN, 3 messages should be seen --") logger.warn("Warn message") for i in xrange(102): message(MSG % i) logger.info("Info index = %d", i) mh.close() logger.removeHandler(mh) logger.addHandler(sh) #---------------------------------------------------------------------------- # Test 3 #---------------------------------------------------------------------------- FILTER = "a.b" def doLog3(): logging.getLogger("a").info("Info 1") logging.getLogger("a.b").info("Info 2") logging.getLogger("a.c").info("Info 3") logging.getLogger("a.b.c").info("Info 4") logging.getLogger("a.b.c.d").info("Info 5") logging.getLogger("a.bb.c").info("Info 6") logging.getLogger("b").info("Info 7") logging.getLogger("b.a").info("Info 8") logging.getLogger("c.a.b").info("Info 9") logging.getLogger("a.bb").info("Info 10") def test3(): root = logging.getLogger() root.setLevel(logging.DEBUG) hand = root.handlers[0] message("Unfiltered...") doLog3() message("Filtered with '%s'..." % FILTER) filt = logging.Filter(FILTER) hand.addFilter(filt) doLog3() hand.removeFilter(filt) #---------------------------------------------------------------------------- # Test Harness #---------------------------------------------------------------------------- def banner(nm, typ): sep = BANNER % (nm, typ) sys.stdout.write(sep) sys.stdout.flush() def test_main(): rootLogger = logging.getLogger("") rootLogger.setLevel(logging.DEBUG) hdlr = logging.StreamHandler(sys.stdout) fmt = logging.Formatter(logging.BASIC_FORMAT) hdlr.setFormatter(fmt) rootLogger.addHandler(hdlr) #Set up a handler such that all events are sent via a socket to the log #receiver (logrecv). #The handler will only be added to the rootLogger for some of the tests hdlr = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT) #Configure the logger for logrecv so events do not propagate beyond it. #The sockLogger output is buffered in memory until the end of the test, #and printed at the end. sockOut = cStringIO.StringIO() sockLogger = logging.getLogger("logrecv") sockLogger.setLevel(logging.DEBUG) sockhdlr = logging.StreamHandler(sockOut) sockhdlr.setFormatter(logging.Formatter( "%(name)s -> %(levelname)s: %(message)s")) sockLogger.addHandler(sockhdlr) sockLogger.propagate = 0 #Set up servers threads = [] tcpserver = LogRecordSocketReceiver() sys.stdout.write("About to start TCP server...\n") threads.append(threading.Thread(target=runTCP, args=(tcpserver,))) for thread in threads: thread.start() try: banner("log_test0", "begin") rootLogger.addHandler(hdlr) test0() rootLogger.removeHandler(hdlr) banner("log_test0", "end") banner("log_test1", "begin") test1() banner("log_test1", "end") banner("log_test2", "begin") test2() banner("log_test2", "end") banner("log_test3", "begin") test3() banner("log_test3", "end") banner("logrecv output", "begin") sys.stdout.write(sockOut.getvalue()) sockOut.close() banner("logrecv output", "end") finally: #shut down server tcpserver.abort = 1 for thread in threads: thread.join() if __name__ == "__main__": sys.stdout.write("test_logging\n") test_main() sys.stdout.flush() From nnorwitz@users.sourceforge.net Thu Jan 2 14:56:42 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 02 Jan 2003 06:56:42 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_logging,NONE,1.1 Message-ID: <E18U6m2-0006xw-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv26301/Lib/test/output Added Files: test_logging Log Message: SF #660795 Add a test for logging from Vinay Sajip (module author) --- NEW FILE: test_logging --- test_logging About to start TCP server... -- log_test0 begin --------------------------------------------------- CRITICAL:ERR:Message 0 ERROR:ERR:Message 1 CRITICAL:INF:Message 2 ERROR:INF:Message 3 WARN:INF:Message 4 INFO:INF:Message 5 CRITICAL:INF.UNDEF:Message 6 ERROR:INF.UNDEF:Message 7 WARN:INF.UNDEF:Message 8 INFO:INF.UNDEF:Message 9 CRITICAL:INF.ERR:Message 10 ERROR:INF.ERR:Message 11 CRITICAL:INF.ERR.UNDEF:Message 12 ERROR:INF.ERR.UNDEF:Message 13 CRITICAL:DEB:Message 14 ERROR:DEB:Message 15 WARN:DEB:Message 16 INFO:DEB:Message 17 DEBUG:DEB:Message 18 CRITICAL:UNDEF:Message 19 ERROR:UNDEF:Message 20 WARN:UNDEF:Message 21 INFO:UNDEF:Message 22 CRITICAL:INF.BADPARENT.UNDEF:Message 23 CRITICAL:INF.BADPARENT:Message 24 INFO:INF:Messages should bear numbers 0 through 24. -- log_test0 end --------------------------------------------------- -- log_test1 begin --------------------------------------------------- -- setting logging level to 'Boring' ----- Boring:root:This should only be seen at the 'Boring' logging level (or lower) Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower) Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower) Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Chatterbox' ----- Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower) Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower) Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Garrulous' ----- Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower) Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Talkative' ----- Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Verbose' ----- Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Sociable' ----- Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Effusive' ----- Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Terse' ----- Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Taciturn' ----- Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Silent' ----- Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- Filtering at handler level to SOCIABLE -- -- setting logging level to 'Boring' ----- Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Chatterbox' ----- Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Garrulous' ----- Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Talkative' ----- Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Verbose' ----- Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Sociable' ----- Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Effusive' ----- Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Terse' ----- Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Taciturn' ----- Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Silent' ----- Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- Filtering using GARRULOUS filter -- -- setting logging level to 'Boring' ----- Boring:root:This should only be seen at the 'Boring' logging level (or lower) Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower) Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Chatterbox' ----- Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower) Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Garrulous' ----- Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Talkative' ----- Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Verbose' ----- Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Sociable' ----- Sociable:root:This should only be seen at the 'Sociable' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Effusive' ----- Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Terse' ----- Terse:root:This should only be seen at the 'Terse' logging level (or lower) Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Taciturn' ----- Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Silent' ----- Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- Filtering using specific filter for SOCIABLE, TACITURN -- -- setting logging level to 'Boring' ----- Boring:root:This should only be seen at the 'Boring' logging level (or lower) Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower) Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Chatterbox' ----- Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower) Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Garrulous' ----- Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Talkative' ----- Talkative:root:This should only be seen at the 'Talkative' logging level (or lower) Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Verbose' ----- Verbose:root:This should only be seen at the 'Verbose' logging level (or lower) Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Sociable' ----- Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Effusive' ----- Effusive:root:This should only be seen at the 'Effusive' logging level (or lower) Terse:root:This should only be seen at the 'Terse' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Terse' ----- Terse:root:This should only be seen at the 'Terse' logging level (or lower) Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Taciturn' ----- Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- setting logging level to 'Silent' ----- Silent:root:This should only be seen at the 'Silent' logging level (or lower) -- log_test1 end --------------------------------------------------- -- log_test2 begin --------------------------------------------------- -- logging at DEBUG, nothing should be seen yet -- -- logging at INFO, nothing should be seen yet -- -- logging at WARN, 3 messages should be seen -- DEBUG:root:Debug message INFO:root:Info message WARN:root:Warn message -- logging 0 at INFO, messages should be seen every 10 events -- -- logging 1 at INFO, messages should be seen every 10 events -- -- logging 2 at INFO, messages should be seen every 10 events -- -- logging 3 at INFO, messages should be seen every 10 events -- -- logging 4 at INFO, messages should be seen every 10 events -- -- logging 5 at INFO, messages should be seen every 10 events -- -- logging 6 at INFO, messages should be seen every 10 events -- -- logging 7 at INFO, messages should be seen every 10 events -- -- logging 8 at INFO, messages should be seen every 10 events -- -- logging 9 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 0 INFO:root:Info index = 1 INFO:root:Info index = 2 INFO:root:Info index = 3 INFO:root:Info index = 4 INFO:root:Info index = 5 INFO:root:Info index = 6 INFO:root:Info index = 7 INFO:root:Info index = 8 INFO:root:Info index = 9 -- logging 10 at INFO, messages should be seen every 10 events -- -- logging 11 at INFO, messages should be seen every 10 events -- -- logging 12 at INFO, messages should be seen every 10 events -- -- logging 13 at INFO, messages should be seen every 10 events -- -- logging 14 at INFO, messages should be seen every 10 events -- -- logging 15 at INFO, messages should be seen every 10 events -- -- logging 16 at INFO, messages should be seen every 10 events -- -- logging 17 at INFO, messages should be seen every 10 events -- -- logging 18 at INFO, messages should be seen every 10 events -- -- logging 19 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 10 INFO:root:Info index = 11 INFO:root:Info index = 12 INFO:root:Info index = 13 INFO:root:Info index = 14 INFO:root:Info index = 15 INFO:root:Info index = 16 INFO:root:Info index = 17 INFO:root:Info index = 18 INFO:root:Info index = 19 -- logging 20 at INFO, messages should be seen every 10 events -- -- logging 21 at INFO, messages should be seen every 10 events -- -- logging 22 at INFO, messages should be seen every 10 events -- -- logging 23 at INFO, messages should be seen every 10 events -- -- logging 24 at INFO, messages should be seen every 10 events -- -- logging 25 at INFO, messages should be seen every 10 events -- -- logging 26 at INFO, messages should be seen every 10 events -- -- logging 27 at INFO, messages should be seen every 10 events -- -- logging 28 at INFO, messages should be seen every 10 events -- -- logging 29 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 20 INFO:root:Info index = 21 INFO:root:Info index = 22 INFO:root:Info index = 23 INFO:root:Info index = 24 INFO:root:Info index = 25 INFO:root:Info index = 26 INFO:root:Info index = 27 INFO:root:Info index = 28 INFO:root:Info index = 29 -- logging 30 at INFO, messages should be seen every 10 events -- -- logging 31 at INFO, messages should be seen every 10 events -- -- logging 32 at INFO, messages should be seen every 10 events -- -- logging 33 at INFO, messages should be seen every 10 events -- -- logging 34 at INFO, messages should be seen every 10 events -- -- logging 35 at INFO, messages should be seen every 10 events -- -- logging 36 at INFO, messages should be seen every 10 events -- -- logging 37 at INFO, messages should be seen every 10 events -- -- logging 38 at INFO, messages should be seen every 10 events -- -- logging 39 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 30 INFO:root:Info index = 31 INFO:root:Info index = 32 INFO:root:Info index = 33 INFO:root:Info index = 34 INFO:root:Info index = 35 INFO:root:Info index = 36 INFO:root:Info index = 37 INFO:root:Info index = 38 INFO:root:Info index = 39 -- logging 40 at INFO, messages should be seen every 10 events -- -- logging 41 at INFO, messages should be seen every 10 events -- -- logging 42 at INFO, messages should be seen every 10 events -- -- logging 43 at INFO, messages should be seen every 10 events -- -- logging 44 at INFO, messages should be seen every 10 events -- -- logging 45 at INFO, messages should be seen every 10 events -- -- logging 46 at INFO, messages should be seen every 10 events -- -- logging 47 at INFO, messages should be seen every 10 events -- -- logging 48 at INFO, messages should be seen every 10 events -- -- logging 49 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 40 INFO:root:Info index = 41 INFO:root:Info index = 42 INFO:root:Info index = 43 INFO:root:Info index = 44 INFO:root:Info index = 45 INFO:root:Info index = 46 INFO:root:Info index = 47 INFO:root:Info index = 48 INFO:root:Info index = 49 -- logging 50 at INFO, messages should be seen every 10 events -- -- logging 51 at INFO, messages should be seen every 10 events -- -- logging 52 at INFO, messages should be seen every 10 events -- -- logging 53 at INFO, messages should be seen every 10 events -- -- logging 54 at INFO, messages should be seen every 10 events -- -- logging 55 at INFO, messages should be seen every 10 events -- -- logging 56 at INFO, messages should be seen every 10 events -- -- logging 57 at INFO, messages should be seen every 10 events -- -- logging 58 at INFO, messages should be seen every 10 events -- -- logging 59 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 50 INFO:root:Info index = 51 INFO:root:Info index = 52 INFO:root:Info index = 53 INFO:root:Info index = 54 INFO:root:Info index = 55 INFO:root:Info index = 56 INFO:root:Info index = 57 INFO:root:Info index = 58 INFO:root:Info index = 59 -- logging 60 at INFO, messages should be seen every 10 events -- -- logging 61 at INFO, messages should be seen every 10 events -- -- logging 62 at INFO, messages should be seen every 10 events -- -- logging 63 at INFO, messages should be seen every 10 events -- -- logging 64 at INFO, messages should be seen every 10 events -- -- logging 65 at INFO, messages should be seen every 10 events -- -- logging 66 at INFO, messages should be seen every 10 events -- -- logging 67 at INFO, messages should be seen every 10 events -- -- logging 68 at INFO, messages should be seen every 10 events -- -- logging 69 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 60 INFO:root:Info index = 61 INFO:root:Info index = 62 INFO:root:Info index = 63 INFO:root:Info index = 64 INFO:root:Info index = 65 INFO:root:Info index = 66 INFO:root:Info index = 67 INFO:root:Info index = 68 INFO:root:Info index = 69 -- logging 70 at INFO, messages should be seen every 10 events -- -- logging 71 at INFO, messages should be seen every 10 events -- -- logging 72 at INFO, messages should be seen every 10 events -- -- logging 73 at INFO, messages should be seen every 10 events -- -- logging 74 at INFO, messages should be seen every 10 events -- -- logging 75 at INFO, messages should be seen every 10 events -- -- logging 76 at INFO, messages should be seen every 10 events -- -- logging 77 at INFO, messages should be seen every 10 events -- -- logging 78 at INFO, messages should be seen every 10 events -- -- logging 79 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 70 INFO:root:Info index = 71 INFO:root:Info index = 72 INFO:root:Info index = 73 INFO:root:Info index = 74 INFO:root:Info index = 75 INFO:root:Info index = 76 INFO:root:Info index = 77 INFO:root:Info index = 78 INFO:root:Info index = 79 -- logging 80 at INFO, messages should be seen every 10 events -- -- logging 81 at INFO, messages should be seen every 10 events -- -- logging 82 at INFO, messages should be seen every 10 events -- -- logging 83 at INFO, messages should be seen every 10 events -- -- logging 84 at INFO, messages should be seen every 10 events -- -- logging 85 at INFO, messages should be seen every 10 events -- -- logging 86 at INFO, messages should be seen every 10 events -- -- logging 87 at INFO, messages should be seen every 10 events -- -- logging 88 at INFO, messages should be seen every 10 events -- -- logging 89 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 80 INFO:root:Info index = 81 INFO:root:Info index = 82 INFO:root:Info index = 83 INFO:root:Info index = 84 INFO:root:Info index = 85 INFO:root:Info index = 86 INFO:root:Info index = 87 INFO:root:Info index = 88 INFO:root:Info index = 89 -- logging 90 at INFO, messages should be seen every 10 events -- -- logging 91 at INFO, messages should be seen every 10 events -- -- logging 92 at INFO, messages should be seen every 10 events -- -- logging 93 at INFO, messages should be seen every 10 events -- -- logging 94 at INFO, messages should be seen every 10 events -- -- logging 95 at INFO, messages should be seen every 10 events -- -- logging 96 at INFO, messages should be seen every 10 events -- -- logging 97 at INFO, messages should be seen every 10 events -- -- logging 98 at INFO, messages should be seen every 10 events -- -- logging 99 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 90 INFO:root:Info index = 91 INFO:root:Info index = 92 INFO:root:Info index = 93 INFO:root:Info index = 94 INFO:root:Info index = 95 INFO:root:Info index = 96 INFO:root:Info index = 97 INFO:root:Info index = 98 INFO:root:Info index = 99 -- logging 100 at INFO, messages should be seen every 10 events -- -- logging 101 at INFO, messages should be seen every 10 events -- INFO:root:Info index = 100 INFO:root:Info index = 101 -- log_test2 end --------------------------------------------------- -- log_test3 begin --------------------------------------------------- Unfiltered... INFO:a:Info 1 INFO:a.b:Info 2 INFO:a.c:Info 3 INFO:a.b.c:Info 4 INFO:a.b.c.d:Info 5 INFO:a.bb.c:Info 6 INFO:b:Info 7 INFO:b.a:Info 8 INFO:c.a.b:Info 9 INFO:a.bb:Info 10 Filtered with 'a.b'... INFO:a.b:Info 2 INFO:a.b.c:Info 4 INFO:a.b.c.d:Info 5 -- log_test3 end --------------------------------------------------- -- logrecv output begin --------------------------------------------------- ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR) ERR -> ERROR: Message 1 (via logrecv.tcp.ERR) INF -> CRITICAL: Message 2 (via logrecv.tcp.INF) INF -> ERROR: Message 3 (via logrecv.tcp.INF) INF -> WARN: Message 4 (via logrecv.tcp.INF) INF -> INFO: Message 5 (via logrecv.tcp.INF) INF.UNDEF -> CRITICAL: Message 6 (via logrecv.tcp.INF.UNDEF) INF.UNDEF -> ERROR: Message 7 (via logrecv.tcp.INF.UNDEF) INF.UNDEF -> WARN: Message 8 (via logrecv.tcp.INF.UNDEF) INF.UNDEF -> INFO: Message 9 (via logrecv.tcp.INF.UNDEF) INF.ERR -> CRITICAL: Message 10 (via logrecv.tcp.INF.ERR) INF.ERR -> ERROR: Message 11 (via logrecv.tcp.INF.ERR) INF.ERR.UNDEF -> CRITICAL: Message 12 (via logrecv.tcp.INF.ERR.UNDEF) INF.ERR.UNDEF -> ERROR: Message 13 (via logrecv.tcp.INF.ERR.UNDEF) DEB -> CRITICAL: Message 14 (via logrecv.tcp.DEB) DEB -> ERROR: Message 15 (via logrecv.tcp.DEB) DEB -> WARN: Message 16 (via logrecv.tcp.DEB) DEB -> INFO: Message 17 (via logrecv.tcp.DEB) DEB -> DEBUG: Message 18 (via logrecv.tcp.DEB) UNDEF -> CRITICAL: Message 19 (via logrecv.tcp.UNDEF) UNDEF -> ERROR: Message 20 (via logrecv.tcp.UNDEF) UNDEF -> WARN: Message 21 (via logrecv.tcp.UNDEF) UNDEF -> INFO: Message 22 (via logrecv.tcp.UNDEF) INF.BADPARENT.UNDEF -> CRITICAL: Message 23 (via logrecv.tcp.INF.BADPARENT.UNDEF) INF.BADPARENT -> CRITICAL: Message 24 (via logrecv.tcp.INF.BADPARENT) INF -> INFO: Messages should bear numbers 0 through 24. (via logrecv.tcp.INF) -- logrecv output end --------------------------------------------------- From mwh@python.net Thu Jan 2 15:09:12 2003 From: mwh@python.net (Michael Hudson) Date: 02 Jan 2003 15:09:12 +0000 Subject: [Python-checkins] python/dist/src/Modules parsermodule.c,2.73,2.74 In-Reply-To: jhylton@users.sourceforge.net's message of "Tue, 31 Dec 2002 10:17:46 -0800" References: <E18TQxW-0000sm-00@sc8-pr-cvs1.sourceforge.net> Message-ID: <2misx7oag7.fsf@starship.python.net> Thanks for getting this in in time! I hope all my agitating about it wasn't too annoying... jhylton@users.sourceforge.net writes: > SF patch [ 597919 ] compiler package and SET_LINENO > > A variety of changes from Michael Hudson to get the compiler working > with 2.3. The primary change is the handling of SET_LINENO: Actually, the stuff that caused the most pain was PEP 263. Cheers, M. -- The gripping hand is really that there are morons everywhere, it's just that the Americon morons are funnier than average. -- Pim van Riezen, alt.sysadmin.recovery From jvr@users.sourceforge.net Thu Jan 2 15:19:33 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 02 Jan 2003 07:19:33 -0800 Subject: [Python-checkins] python/dist/src/Modules zipimport.c,1.6,1.6.2.1 Message-ID: <E18U789-0000oC-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv3083 Modified Files: Tag: r23a1-branch zipimport.c Log Message: backport zipimport fix to 2.3a1 rel branch Index: zipimport.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zipimport.c,v retrieving revision 1.6 retrieving revision 1.6.2.1 diff -C2 -d -r1.6 -r1.6.2.1 *** zipimport.c 31 Dec 2002 15:47:42 -0000 1.6 --- zipimport.c 2 Jan 2003 15:19:27 -0000 1.6.2.1 *************** *** 104,108 **** } /* back up one path element */ ! p = strchr(buf, SEP); if (prefix != NULL) *prefix = SEP; --- 104,108 ---- } /* back up one path element */ ! p = strrchr(buf, SEP); if (prefix != NULL) *prefix = SEP; From jvr@users.sourceforge.net Thu Jan 2 15:24:42 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 02 Jan 2003 07:24:42 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_zipimport.py,1.1,1.1.2.1 Message-ID: <E18U7D8-0001Ft-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv4800 Modified Files: Tag: r23a1-branch test_zipimport.py Log Message: backport zipimport fix to 2.3a1 rel branch Index: test_zipimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zipimport.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -C2 -d -r1.1 -r1.1.2.1 *** test_zipimport.py 30 Dec 2002 22:08:03 -0000 1.1 --- test_zipimport.py 2 Jan 2003 15:24:38 -0000 1.1.2.1 *************** *** 31,35 **** TESTMOD = "ziptestmodule" TESTPACK = "ziptestpackage" ! TEMP_ZIP = "junk95142.zip" --- 31,36 ---- TESTMOD = "ziptestmodule" TESTPACK = "ziptestpackage" ! TESTPACK2 = "ziptestpackage2" ! TEMP_ZIP = os.path.abspath("junk95142.zip") *************** *** 140,148 **** def testDeepPackage(self): packdir = TESTPACK + os.sep ! packdir2 = packdir + packdir files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc), packdir2 + "__init__" + pyc_ext: (NOW, test_pyc), packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)} ! self.doTest(pyc_ext, files, TESTPACK, TESTPACK, TESTMOD) def testGetData(self): --- 141,149 ---- def testDeepPackage(self): packdir = TESTPACK + os.sep ! packdir2 = packdir + TESTPACK2 + os.sep files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc), packdir2 + "__init__" + pyc_ext: (NOW, test_pyc), packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)} ! self.doTest(pyc_ext, files, TESTPACK, TESTPACK2, TESTMOD) def testGetData(self): *************** *** 164,168 **** def get_file(): return __file__ ! if __importer__.get_data("some.data") != "some data": raise AssertionError, "bad data"\n""" pyc = make_pyc(compile(src, "<???>", "exec"), NOW) --- 165,169 ---- def get_file(): return __file__ ! if __loader__.get_data("some.data") != "some data": raise AssertionError, "bad data"\n""" pyc = make_pyc(compile(src, "<???>", "exec"), NOW) From nnorwitz@users.sourceforge.net Thu Jan 2 15:32:02 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 02 Jan 2003 07:32:02 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libimaplib.tex,1.22,1.23 Message-ID: <E18U7KE-00025z-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv8024/Doc/lib Modified Files: libimaplib.tex Log Message: Add some version info for new methods and class Index: libimaplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libimaplib.tex,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** libimaplib.tex 22 Nov 2002 05:47:39 -0000 1.22 --- libimaplib.tex 2 Jan 2003 15:32:00 -0000 1.23 *************** *** 69,72 **** --- 69,73 ---- This is a subclass derived from \class{IMAP4} that connects to the \code{stdin/stdout} file descriptors created by passing \var{command} to \code{os.popen2()}. + \versionadded{2.3} \end{classdesc} *************** *** 214,217 **** --- 215,219 ---- Force use of \samp{CRAM-MD5} authentication when identifying the client to protect the password. Will only work if the server \samp{CAPABILITY} response includes the phrase \samp{AUTH=CRAM-MD5}. + \versionadded{2.3} \end{methoddesc} *************** *** 246,249 **** --- 248,252 ---- Assume authentication as \var{user}. Allows an authorised administrator to proxy into any user's mailbox. + \versionadded{2.3} \end{methoddesc} From tim_one@users.sourceforge.net Thu Jan 2 16:02:30 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 08:02:30 -0800 Subject: [Python-checkins] python/dist/src/PCbuild python20.wse,1.113,1.114 Message-ID: <E18U7ni-00059Q-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv19201/python/PCbuild Modified Files: python20.wse Log Message: SF bug 660795: logging missing from Python 2.3a1 for Windows. Added the logging package. In the meantime, Neal Norwitz added a test_logging.py to the std test suite, which would have caught this oversight in the Windows installer. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.113 retrieving revision 1.114 diff -C2 -d -r1.113 -r1.114 *** python20.wse 1 Jan 2003 02:14:12 -0000 1.113 --- python20.wse 2 Jan 2003 16:02:27 -0000 1.114 *************** *** 2015,2018 **** --- 2015,2026 ---- end item: Install File + Source=..\lib\logging\*.py + Destination=%MAINDIR%\Lib\logging + Description=Logging package + Flags=0000000000000010 + end + item: Remark + end + item: Install File Source=..\lib\site-packages\readme Destination=%MAINDIR%\Lib\site-packages\README.txt From tim_one@users.sourceforge.net Thu Jan 2 16:02:30 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 08:02:30 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.588,1.589 Message-ID: <E18U7ni-00059D-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv19201/python/Misc Modified Files: NEWS Log Message: SF bug 660795: logging missing from Python 2.3a1 for Windows. Added the logging package. In the meantime, Neal Norwitz added a test_logging.py to the std test suite, which would have caught this oversight in the Windows installer. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.588 retrieving revision 1.589 diff -C2 -d -r1.588 -r1.589 *** NEWS 1 Jan 2003 20:07:49 -0000 1.588 --- NEWS 2 Jan 2003 16:02:25 -0000 1.589 *************** *** 57,60 **** --- 57,63 ---- ------- + - The new logging package is now installed by the Windows installer. It + wasn't in 2.3a1 due to oversight. + Mac --- *************** *** 144,148 **** - PEP 302 has been accepted. Although it was inititally developed to ! support zipimport, it offers a new, general import hook mechanism. Several new variables have been added to the sys module: sys.meta_path, sys.path_hooks, and sys.path_importer_cache; these --- 147,151 ---- - PEP 302 has been accepted. Although it was inititally developed to ! support zipimport, it offers a new, general import hook mechanism. Several new variables have been added to the sys module: sys.meta_path, sys.path_hooks, and sys.path_importer_cache; these *************** *** 1079,1083 **** be used to run any Python script using the window manager (including Tkinter or wxPython scripts). ! - Most of Mac/Lib has moved to Lib/plat-mac, which is again used both in MacPython-OSX and MacPython-OS9. The only modules remaining in Mac/Lib --- 1082,1086 ---- be used to run any Python script using the window manager (including Tkinter or wxPython scripts). ! - Most of Mac/Lib has moved to Lib/plat-mac, which is again used both in MacPython-OSX and MacPython-OS9. The only modules remaining in Mac/Lib From tim_one@users.sourceforge.net Thu Jan 2 16:16:30 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 08:16:30 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.136,1.137 Message-ID: <E18U81G-0006sj-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv24973 Modified Files: datetime.py Log Message: SF bug 661086: datetime.today() truncates microseconds. On Windows, it was very common to get microsecond values (out of .today() and .now()) of the form 480999, i.e. with three trailing nines. The platform precision is .001 seconds, and fp rounding errors account for the rest. Under the covers, that 480999 started life as the fractional part of a timestamp, like .4809999978. Rounding that times 1e6 cures the irritation. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.136 retrieving revision 1.137 diff -C2 -d -r1.136 -r1.137 *** datetime.py 2 Jan 2003 12:58:58 -0000 1.136 --- datetime.py 2 Jan 2003 16:16:27 -0000 1.137 *************** *** 1283,1287 **** "Construct a datetime from a POSIX timestamp (like time.time())." y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) ! us = int((t % 1.0) * 1000000) return cls(y, m, d, hh, mm, ss, us) fromtimestamp = classmethod(fromtimestamp) --- 1283,1287 ---- "Construct a datetime from a POSIX timestamp (like time.time())." y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) ! us = int(round((t % 1.0) * 1000000)) return cls(y, m, d, hh, mm, ss, us) fromtimestamp = classmethod(fromtimestamp) From gvanrossum@users.sourceforge.net Thu Jan 2 16:27:17 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 02 Jan 2003 08:27:17 -0800 Subject: [Python-checkins] python/dist/src/Python getcopyright.c,1.16,1.17 Message-ID: <E18U8Bh-00081v-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv30843 Modified Files: getcopyright.c Log Message: Another copyright update. (JvR: can you backport this to the 2.3a1 release branch?) Index: getcopyright.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getcopyright.c,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** getcopyright.c 27 Feb 2002 13:29:46 -0000 1.16 --- getcopyright.c 2 Jan 2003 16:27:15 -0000 1.17 *************** *** 5,9 **** static char cprt[] = "\ ! Copyright (c) 2001, 2002 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ --- 5,9 ---- static char cprt[] = "\ ! Copyright (c) 2001, 2002, 2003 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ From gvanrossum@users.sourceforge.net Thu Jan 2 16:31:11 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 02 Jan 2003 08:31:11 -0800 Subject: [Python-checkins] python/dist/src LICENSE,1.24,1.25 Message-ID: <E18U8FT-0008ST-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv32499 Modified Files: LICENSE Log Message: Update the copyright year. Index: LICENSE =================================================================== RCS file: /cvsroot/python/python/dist/src/LICENSE,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** LICENSE 31 Dec 2002 01:50:07 -0000 1.24 --- LICENSE 2 Jan 2003 16:31:09 -0000 1.25 *************** *** 78,82 **** alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) ! 2001, 2002 Python Software Foundation; All Rights Reserved" are retained in Python 2.3 alone or in any derivative version prepared by Licensee. --- 78,82 ---- alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) ! 2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are retained in Python 2.3 alone or in any derivative version prepared by Licensee. From tim_one@users.sourceforge.net Thu Jan 2 16:32:59 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 08:32:59 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.24,1.25 Message-ID: <E18U8HD-0000BC-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv32028/python/Modules Modified Files: datetimemodule.c Log Message: SF bug 661086: datetime.today() truncates microseconds. On Windows, it was very common to get microsecond values (out of .today() and .now()) of the form 480999, i.e. with three trailing nines. The platform precision is .001 seconds, and fp rounding errors account for the rest. Under the covers, that 480999 started life as the fractional part of a timestamp, like .4809999978. Rounding that times 1e6 cures the irritation. Confession: the platform precision isn't really .001 seconds. It's usually worse. What actually happens is that MS rounds a cruder value to a multiple of .001, and that suffers its own rounding errors. A tiny bit of refactoring added a new internal utility to round doubles. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** datetimemodule.c 2 Jan 2003 03:14:59 -0000 1.24 --- datetimemodule.c 2 Jan 2003 16:32:54 -0000 1.25 *************** *** 121,124 **** --- 121,137 ---- } + /* Round a double to the nearest long. |x| must be small enough to fit + * in a C long; this is not checked. + */ + static long + round_to_long(double x) + { + if (x >= 0.0) + x = floor(x + 0.5); + else + x = ceil(x - 0.5); + return (long)x; + } + /* --------------------------------------------------------------------------- * General calendrical helper functions *************** *** 1906,1915 **** if (leftover_us) { /* Round to nearest whole # of us, and add into x. */ ! PyObject *temp; ! if (leftover_us >= 0.0) ! leftover_us = floor(leftover_us + 0.5); ! else ! leftover_us = ceil(leftover_us - 0.5); ! temp = PyLong_FromDouble(leftover_us); if (temp == NULL) { Py_DECREF(x); --- 1919,1923 ---- if (leftover_us) { /* Round to nearest whole # of us, and add into x. */ ! PyObject *temp = PyLong_FromLong(round_to_long(leftover_us)); if (temp == NULL) { Py_DECREF(x); *************** *** 2859,2863 **** { time_t timet = (time_t)timestamp; ! int us = (int)((timestamp - (double)timet) * 1e6); return datetime_from_timet_and_us(cls, f, timet, us); --- 2867,2872 ---- { time_t timet = (time_t)timestamp; ! double fraction = timestamp - (double)timet; ! int us = (int)round_to_long(fraction * 1e6); return datetime_from_timet_and_us(cls, f, timet, us); From gvanrossum@users.sourceforge.net Thu Jan 2 16:33:20 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 02 Jan 2003 08:33:20 -0800 Subject: [Python-checkins] python/nondist/peps pep-0101.txt,1.25,1.26 Message-ID: <E18U8HY-0000DK-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv804 Modified Files: pep-0101.txt Log Message: Add checklist for copyright year change. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** pep-0101.txt 31 Dec 2002 01:30:28 -0000 1.25 --- pep-0101.txt 2 Jan 2003 16:33:18 -0000 1.26 *************** *** 122,125 **** --- 122,139 ---- Doc/texinputs/license.tex; Fred usually takes care of that. + ___ Check the years on the copyright notice. If the last release + was some time last year, add the current year to the copyright + notice in several places: + + ___ README + + ___ LICENSE + + ___ Python/getcopyright.c + + ___ Doc/texinputs/copyright.tex + + ___ In the license.ht file for the distribution on the website. + ___ For the next few hours, selectively merge stuff from trunk into branch. For each change you see on the trunk (i.e. via the From gvanrossum@users.sourceforge.net Thu Jan 2 16:31:37 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 02 Jan 2003 08:31:37 -0800 Subject: [Python-checkins] python/dist/src/Doc/texinputs copyright.tex,1.12,1.13 Message-ID: <E18U8Ft-0008V7-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory sc8-pr-cvs1:/tmp/cvs-serv32667 Modified Files: copyright.tex Log Message: Update the copyright year. Index: copyright.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/copyright.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** copyright.tex 20 Jun 2001 21:34:35 -0000 1.12 --- copyright.tex 2 Jan 2003 16:31:35 -0000 1.13 *************** *** 1,3 **** ! Copyright \copyright{} 2001 Python Software Foundation. All rights reserved. --- 1,3 ---- ! Copyright \copyright{} 2001, 2002, 2003 Python Software Foundation. All rights reserved. From tim_one@users.sourceforge.net Thu Jan 2 17:09:21 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 09:09:21 -0800 Subject: [Python-checkins] python/dist/src/PC python_nt.rc,1.19,1.20 Message-ID: <E18U8qP-0003w2-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1:/tmp/cvs-serv14247/python/PC Modified Files: python_nt.rc Log Message: There are two more copyright notices in the Windows world: PC/python_nt.rc sets up the DLL version resource (displayed when you right-click on the DLL and select Properties). PCbuld/python20.wse sets up the installer version resource (displayed when you right-click on the installer .exe and select Properties). Turns out this one hadn't been updated since 2001 <frown>! Index: python_nt.rc =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/python_nt.rc,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** python_nt.rc 11 Oct 2002 18:25:52 -0000 1.19 --- python_nt.rc 2 Jan 2003 17:09:19 -0000 1.20 *************** *** 92,96 **** VALUE "FileVersion", PYTHON_VERSION VALUE "InternalName", "Python DLL\0" ! VALUE "LegalCopyright", "Copyright © 2001-2002 Python Software Foundation. Copyright © 2000 BeOpen.com. Copyright © 1995-2001 CNRI. Copyright © 1991-1995 SMC.\0" VALUE "OriginalFilename", PYTHON_DLL_NAME "\0" VALUE "ProductName", "Python\0" --- 92,96 ---- VALUE "FileVersion", PYTHON_VERSION VALUE "InternalName", "Python DLL\0" ! VALUE "LegalCopyright", "Copyright © 2001-2003 Python Software Foundation. Copyright © 2000 BeOpen.com. Copyright © 1995-2001 CNRI. Copyright © 1991-1995 SMC.\0" VALUE "OriginalFilename", PYTHON_DLL_NAME "\0" VALUE "ProductName", "Python\0" From tim_one@users.sourceforge.net Thu Jan 2 17:09:21 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 09:09:21 -0800 Subject: [Python-checkins] python/dist/src/PCbuild python20.wse,1.114,1.115 Message-ID: <E18U8qP-0003w7-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv14247/python/PCbuild Modified Files: python20.wse Log Message: There are two more copyright notices in the Windows world: PC/python_nt.rc sets up the DLL version resource (displayed when you right-click on the DLL and select Properties). PCbuld/python20.wse sets up the installer version resource (displayed when you right-click on the installer .exe and select Properties). Turns out this one hadn't been updated since 2001 <frown>! Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.114 retrieving revision 1.115 diff -C2 -d -r1.114 -r1.115 *** python20.wse 2 Jan 2003 16:02:27 -0000 1.114 --- python20.wse 2 Jan 2003 17:09:19 -0000 1.115 *************** *** 23,30 **** Version File=2.3a1 Version Description=Python Programming Language ! Version Copyright=©2001 Python Software Foundation Version Company=PythonLabs at Zope Corporation Crystal Format=10111100101100000010001001001001 ! Step View=&Properties Variable Name1=_WISE_ Variable Description1=WISE root directory --- 23,30 ---- Version File=2.3a1 Version Description=Python Programming Language ! Version Copyright=©2001-2003 Python Software Foundation Version Company=PythonLabs at Zope Corporation Crystal Format=10111100101100000010001001001001 ! Step View=&All Variable Name1=_WISE_ Variable Description1=WISE root directory From gvanrossum@users.sourceforge.net Thu Jan 2 17:24:04 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 02 Jan 2003 09:24:04 -0800 Subject: [Python-checkins] python/nondist/peps pep-0101.txt,1.26,1.27 Message-ID: <E18U94e-0005aU-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv21416 Modified Files: pep-0101.txt Log Message: More copyright years found. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** pep-0101.txt 2 Jan 2003 16:33:18 -0000 1.26 --- pep-0101.txt 2 Jan 2003 17:24:01 -0000 1.27 *************** *** 134,138 **** ___ Doc/texinputs/copyright.tex ! ___ In the license.ht file for the distribution on the website. ___ For the next few hours, selectively merge stuff from trunk into --- 134,148 ---- ___ Doc/texinputs/copyright.tex ! ___ PC/python_nt.rc sets up the DLL version resource for Windows ! (displayed when you right-click on the DLL and select ! Properties). ! ! ___ PCbuld/python20.wse sets up the Windows installer version ! resource (displayed when you right-click on the installer .exe ! and select Properties). ! ! ___ The license.ht file for the distribution on the website ! contains what purports to be an HTML-ized copy of the LICENSE ! file from the distribution. ___ For the next few hours, selectively merge stuff from trunk into From tim_one@users.sourceforge.net Thu Jan 2 17:47:08 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 09:47:08 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.137,1.138 Message-ID: <E18U9Qy-0008EI-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv31255 Modified Files: datetime.py Log Message: The astimezone() correctness proof endured much pain to prove what turned out to be 3 special cases of a single more-general result. Proving the latter instead is a real simplification. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.137 retrieving revision 1.138 diff -C2 -d -r1.137 -r1.138 *** datetime.py 2 Jan 2003 16:16:27 -0000 1.137 --- datetime.py 2 Jan 2003 17:47:06 -0000 1.138 *************** *** 1898,1902 **** This follows from the definition of x.s. ! 2. If x and y have the same tzinfo member, x.s == y.s. This is actually a requirement, an assumption we need to make about sane tzinfo classes. --- 1898,1902 ---- This follows from the definition of x.s. ! 2. If x and y have the same tzinfo member, x.s = y.s. This is actually a requirement, an assumption we need to make about sane tzinfo classes. *************** *** 1908,1912 **** This follows from #2, and that datimetimetz+timedelta preserves tzinfo. ! 5. (y+k).n = y.n + k Again follows from how arithmetic is defined. --- 1908,1912 ---- This follows from #2, and that datimetimetz+timedelta preserves tzinfo. ! 5. (x+k).n = x.n + k Again follows from how arithmetic is defined. *************** *** 1948,1957 **** In any case, the new value is ! z.n = y.n + y.o - y.d - x.o ! If ! z.n - z.o = x.n - x.o [4] ! then, we have an equivalent time, and are almost done. The insecurity here is at the start of daylight time. Picture US Eastern for concreteness. The wall time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good --- 1948,1967 ---- In any case, the new value is ! z = y + y.o - y.d - x.o [4] ! It's helpful to step back at look at [4] from a higher level: rewrite it as ! z = (y - x.o) + (y.o - y.d) ! ! (y - x.o).n = [by #5] y.n - x.o = [since y.n=x.n] x.n - x.o = [by #3] x's ! UTC equivalent time. So the y-x.o part essentially converts x to UTC. Then ! the y.o-y.d part essentially converts x's UTC equivalent into tz's standard ! time (y.o-y.d=y.s by #1). ! ! At this point, if ! ! z.n - z.o = x.n - x.o [5] ! ! we have an equivalent time, and are almost done. The insecurity here is at the start of daylight time. Picture US Eastern for concreteness. The wall time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good *************** *** 1961,2037 **** the only spelling that makes sense on the local wall clock. ! Claim: When [4] is true, we have "the right" spelling in this endcase. No ! further adjustment is necessary. ! ! Proof: The right spelling has z.d = 0, and the wrong spelling has z.d != 0 ! (for US Eastern, the wrong spelling has z.d = 60 minutes, but we can't assume ! that all time zones work this way -- we can assume a time zone is in daylight ! time iff dst() doesn't return 0). By [4], and recalling that z.o = z.s + z.d, ! ! z.n - z.s - z.d = x.n - x.o [5] ! ! Also ! ! z.n = (y + y.o - y.d - x.o).n by the construction of z, which equals ! y.n + y.o - y.d - x.o by #5. ! ! Plugging that into [5], ! ! y.n + y.o - y.d - x.o - z.s - z.d = x.n - x.o; cancelling the x.o terms, ! y.n + y.o - y.d - z.s - z.d = x.n; but x.n = y.n too, so they also cancel, ! y.o - y.d - z.s - z.d = 0; then y.o = y.s + y.d, so ! y.s + y.d - y.d - z.s - z.d = 0; then the y.d terms cancel, ! y.s - z.s - z.d = 0; but y and z are in the same timezone, so by #2 ! y.s = z.s, and they also cancel, leaving ! - z.d = 0; or, ! z.d = 0 ! ! Therefore z is the standard-time spelling, and there's nothing left to do in ! this case. ! ! QED ! ! Note that we actually proved something stronger: [4] is true if and only if ! z.dst() returns 0. The "only if" part was proved directly. The "if" part ! is proved by starting with z.d = 0 and reading the proof bottom-up; all the ! steps are "iff", so are reversible. ! Next: if [4] isn't true, we're not done. It's helpful to step back and look ! at ! z.n = y.n + y.o - y.d - x.o = y.n-x.o + y.o-y.d ! from a higher level. Since y.n = x.n, the y.n-x.o part gives x's UTC ! equivalent hour. Then since y.s=y.o-y.d, the y.o-y.d part converts x's UTC ! equivalent into tz's standard time. IOW, z is the correct spelling of x in ! tz's standard time. ! If ! z.n - z.o != x.n - x.o ! despite that, then either (1) x is in the "unspellable hour" at the end ! of tz's daylight period; or, (2) z.n needs to be shifted into tz's daylight ! time. ! Assuming #2, that would be easy if we could ask the tzinfo object what the ! daylight offset would be if DST were in effect. And we could compute z.d, ! but we already have enough info to compute it from the quantities we know: ! Claim: The adjustment needed is adding (x.n-x.o)-(z.n-z.o) to z.n. ! Proof: By the comment following the last proof, z.d is not 0 now, and z.d ! is what we need to add to z.n (it's the "missing part" of the conversion from ! x's UTC equivalent to z's daylight time). ! z.d = z.o - z.s by #1; z.s = y.s since they're in the same time zone, so ! z.d = z.o - y.s; then y.s = y.o - y.d by #1, so ! z.d = z.o - (y.o - y.d); then since z.n = y.n+y.o-y.d-x.o, y.o-y.d= ! z.n-y.n+x.o, so ! z.d = z.o - (z.n - y.n + x.o); then x.n = y.n, so ! z.d = z.o - (z.n - x.n + x.o) ! and simple rearranging gives the desired ! z.d = (x.n - x.o) - (z.n - z.o) ! The code actually optimizes this some more, in a straightforward way. Letting ! z'.n = z.n + (x.n - x.o) - (z.n - z.o) we can again ask whether --- 1971,2010 ---- the only spelling that makes sense on the local wall clock. ! In fact, if [5] holds at this point, we do have the standard-time spelling, ! but that takes a bit of proof. We first prove a stronger result. What's the ! difference between the LHS and RHS of [5]? Let ! diff = (x.n - x.o) - (z.n - z.o) [6] ! Now ! z.n = by [4] ! (y + y.o - y.d - x.o).n = by #5 ! y.n + y.o - y.d - x.o = since y.n = x.n ! x.n + y.o - y.d - x.o = since y.o = y.s + y.d by #1 ! x.n + (y.s + y.d) - y.d - x.o = cancelling the y.d terms ! x.n + y.s - x.o = since z and y are have the same tzinfo member, ! y.s = z.s by #2 ! x.n + z.s - x.o ! Plugging that back into [6] gives ! diff = ! (x.n - x.o) - ((x.n + z.s - x.o) - z.o) = expanding ! x.n - x.o - x.n - z.s + x.o + z.o = cancelling ! - z.s + z.o = by #2 ! z.d ! So diff = z.d. ! If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time ! spelling we wanted in the endcase described above. We're done. ! If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to ! add to z (in effect, z is in tz's standard time, and we need to shift the ! offset into tz's daylight time). ! Let ! z' = z + z.d = z + diff we can again ask whether From tim_one@users.sourceforge.net Thu Jan 2 17:55:08 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 09:55:08 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.25,1.26 Message-ID: <E18U9Yi-0000WS-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv1820/Modules Modified Files: datetimemodule.c Log Message: The astimezone() correctness proof endured much pain to prove what turned out to be 3 special cases of a single more-general result. Proving the latter instead is a real simplification. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** datetimemodule.c 2 Jan 2003 16:32:54 -0000 1.25 --- datetimemodule.c 2 Jan 2003 17:55:03 -0000 1.26 *************** *** 5497,5501 **** This follows from the definition of x.s. ! 2. If x and y have the same tzinfo member, x.s == y.s. This is actually a requirement, an assumption we need to make about sane tzinfo classes. --- 5497,5501 ---- This follows from the definition of x.s. ! 2. If x and y have the same tzinfo member, x.s = y.s. This is actually a requirement, an assumption we need to make about sane tzinfo classes. *************** *** 5507,5511 **** This follows from #2, and that datimetimetz+timedelta preserves tzinfo. ! 5. (y+k).n = y.n + k Again follows from how arithmetic is defined. --- 5507,5511 ---- This follows from #2, and that datimetimetz+timedelta preserves tzinfo. ! 5. (x+k).n = x.n + k Again follows from how arithmetic is defined. *************** *** 5547,5556 **** In any case, the new value is ! z.n = y.n + y.o - y.d - x.o ! If ! z.n - z.o = x.n - x.o [4] ! then, we have an equivalent time, and are almost done. The insecurity here is at the start of daylight time. Picture US Eastern for concreteness. The wall time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good --- 5547,5566 ---- In any case, the new value is ! z = y + y.o - y.d - x.o [4] ! It's helpful to step back at look at [4] from a higher level: rewrite it as ! z = (y - x.o) + (y.o - y.d) ! ! (y - x.o).n = [by #5] y.n - x.o = [since y.n=x.n] x.n - x.o = [by #3] x's ! UTC equivalent time. So the y-x.o part essentially converts x to UTC. Then ! the y.o-y.d part essentially converts x's UTC equivalent into tz's standard ! time (y.o-y.d=y.s by #1). ! ! At this point, if ! ! z.n - z.o = x.n - x.o [5] ! ! we have an equivalent time, and are almost done. The insecurity here is at the start of daylight time. Picture US Eastern for concreteness. The wall time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good *************** *** 5560,5636 **** the only spelling that makes sense on the local wall clock. ! Claim: When [4] is true, we have "the right" spelling in this endcase. No ! further adjustment is necessary. ! ! Proof: The right spelling has z.d = 0, and the wrong spelling has z.d != 0 ! (for US Eastern, the wrong spelling has z.d = 60 minutes, but we can't assume ! that all time zones work this way -- we can assume a time zone is in daylight ! time iff dst() doesn't return 0). By [4], and recalling that z.o = z.s + z.d, ! ! z.n - z.s - z.d = x.n - x.o [5] ! ! Also ! ! z.n = (y + y.o - y.d - x.o).n by the construction of z, which equals ! y.n + y.o - y.d - x.o by #5. ! ! Plugging that into [5], ! ! y.n + y.o - y.d - x.o - z.s - z.d = x.n - x.o; cancelling the x.o terms, ! y.n + y.o - y.d - z.s - z.d = x.n; but x.n = y.n too, so they also cancel, ! y.o - y.d - z.s - z.d = 0; then y.o = y.s + y.d, so ! y.s + y.d - y.d - z.s - z.d = 0; then the y.d terms cancel, ! y.s - z.s - z.d = 0; but y and z are in the same timezone, so by #2 ! y.s = z.s, and they also cancel, leaving ! - z.d = 0; or, ! z.d = 0 ! ! Therefore z is the standard-time spelling, and there's nothing left to do in ! this case. ! ! QED ! ! Note that we actually proved something stronger: [4] is true if and only if ! z.dst() returns 0. The "only if" part was proved directly. The "if" part ! is proved by starting with z.d = 0 and reading the proof bottom-up; all the ! steps are "iff", so are reversible. ! Next: if [4] isn't true, we're not done. It's helpful to step back and look ! at ! z.n = y.n + y.o - y.d - x.o = y.n-x.o + y.o-y.d ! from a higher level. Since y.n = x.n, the y.n-x.o part gives x's UTC ! equivalent hour. Then since y.s=y.o-y.d, the y.o-y.d part converts x's UTC ! equivalent into tz's standard time. IOW, z is the correct spelling of x in ! tz's standard time. ! If ! z.n - z.o != x.n - x.o ! despite that, then either (1) x is in the "unspellable hour" at the end ! of tz's daylight period; or, (2) z.n needs to be shifted into tz's daylight ! time. ! Assuming #2, that would be easy if we could ask the tzinfo object what the ! daylight offset would be if DST were in effect. And we could compute z.d, ! but we already have enough info to compute it from the quantities we know: ! Claim: The adjustment needed is adding (x.n-x.o)-(z.n-z.o) to z.n. ! Proof: By the comment following the last proof, z.d is not 0 now, and z.d ! is what we need to add to z.n (it's the "missing part" of the conversion from ! x's UTC equivalent to z's daylight time). ! z.d = z.o - z.s by #1; z.s = y.s since they're in the same time zone, so ! z.d = z.o - y.s; then y.s = y.o - y.d by #1, so ! z.d = z.o - (y.o - y.d); then since z.n = y.n+y.o-y.d-x.o, y.o-y.d= ! z.n-y.n+x.o, so ! z.d = z.o - (z.n - y.n + x.o); then x.n = y.n, so ! z.d = z.o - (z.n - x.n + x.o) ! and simple rearranging gives the desired ! z.d = (x.n - x.o) - (z.n - z.o) ! The code actually optimizes this some more, in a straightforward way. Letting ! z'.n = z.n + (x.n - x.o) - (z.n - z.o) we can again ask whether --- 5570,5609 ---- the only spelling that makes sense on the local wall clock. ! In fact, if [5] holds at this point, we do have the standard-time spelling, ! but that takes a bit of proof. We first prove a stronger result. What's the ! difference between the LHS and RHS of [5]? Let ! diff = (x.n - x.o) - (z.n - z.o) [6] ! Now ! z.n = by [4] ! (y + y.o - y.d - x.o).n = by #5 ! y.n + y.o - y.d - x.o = since y.n = x.n ! x.n + y.o - y.d - x.o = since y.o = y.s + y.d by #1 ! x.n + (y.s + y.d) - y.d - x.o = cancelling the y.d terms ! x.n + y.s - x.o = since z and y are have the same tzinfo member, ! y.s = z.s by #2 ! x.n + z.s - x.o ! Plugging that back into [6] gives ! diff = ! (x.n - x.o) - ((x.n + z.s - x.o) - z.o) = expanding ! x.n - x.o - x.n - z.s + x.o + z.o = cancelling ! - z.s + z.o = by #2 ! z.d ! So diff = z.d. ! If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time ! spelling we wanted in the endcase described above. We're done. ! If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to ! add to z (in effect, z is in tz's standard time, and we need to shift the ! offset into tz's daylight time). ! Let ! z' = z + z.d = z + diff we can again ask whether From jvr@users.sourceforge.net Thu Jan 2 18:47:07 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 02 Jan 2003 10:47:07 -0800 Subject: [Python-checkins] python/nondist/peps pep-0302.txt,1.12,1.13 Message-ID: <E18UAN1-00069H-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv22921 Modified Files: pep-0302.txt Log Message: - added two items from Paul Moore to "Open Issues" - removed section that still mentioned importers-on-sys.path Index: pep-0302.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0302.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pep-0302.txt 1 Jan 2003 20:22:03 -0000 1.12 --- pep-0302.txt 2 Jan 2003 18:47:04 -0000 1.13 *************** *** 430,443 **** Open Issues - The new hook method allows for the possibility of objects other than - strings appearing on sys.path. Existing code is entitled to assume - that sys.path only contains strings (the Python documentation states - this). It is not clear if this will cause significant breakage. In - particular, it is much less clear that code is entitled to assume - that sys.path contains a list of *directory names* - most code which - assumes that sys.path items contain strings also rely on this extra - assumption, and so could be considered as broken (or at least "not - robust") already. - Modules often need supporting data files to do their job, particularly in the case of complex packages or full applications. --- 430,433 ---- *************** *** 480,487 **** On the other hand, importer objects are mostly permanent, as they ! live or are kept alive on sys.meta_path, sys.path_importer_cache or ! sys.path, so for a loader to keep a reference to the importer costs ! us nothing extra. Whether loaders will ever need to carry so much ! independent state for this to become a real issue is questionable. It was suggested on python-dev that it would be useful to be able to --- 470,477 ---- On the other hand, importer objects are mostly permanent, as they ! live or are kept alive on sys.meta_path, sys.path_importer_cache, so ! for a loader to keep a reference to the importer costs us nothing ! extra. Whether loaders will ever need to carry so much independent ! state for this to become a real issue is questionable. It was suggested on python-dev that it would be useful to be able to *************** *** 502,505 **** --- 492,516 ---- a new module implementing a subset of ihooks as a new-style importer, or add a hookable built-in path importer object. + + There is no specific support within this PEP for "stacking" hooks. + For example, it is not obvious how to write a hook to load modules + from ..tar.gz files by combining separate hooks to load modules from + .tar and ..gz files. However, there is no support for such stacking + in the existing hook mechanisms (either the basic "replace + __import__" method, or any of the existing import hook modules) and + so this functionality is not an obvious requirement of the new + mechanism. It may be worth considering as a future enhancement, + however. + + It is possible (via sys.meta_path) to add hooks which run before + sys.path is processed. However, there is no equivalent way of + adding hooks to run after sys.path is processed. For now, if a hook + is required after sys.path has been processed, it can be simulated + by adding an arbitrary "cookie" string at the end of sys.path, and + having the required hook associated with this cookie, via the normal + sys.path_hooks processing. In the longer term, the path handling + code will become a "real" hook on sys.meta_path, and at that stage + it will be possible to insert user-defined hooks either before or + after it. From tim_one@users.sourceforge.net Thu Jan 2 19:10:23 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 11:10:23 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.589,1.590 Message-ID: <E18UAjX-0000Cn-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv454/python/Misc Modified Files: NEWS Log Message: Added a section to record datetime changes. There's apparently going to be an unbounded number of API changes <0.6 wink>. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.589 retrieving revision 1.590 diff -C2 -d -r1.589 -r1.590 *** NEWS 2 Jan 2003 16:02:25 -0000 1.589 --- NEWS 2 Jan 2003 19:10:19 -0000 1.590 *************** *** 18,21 **** --- 18,26 ---- - fcntl now exposes the strops.h I_* constants. + - datetime changes: + + today() and now() now round system timestamps to the closest + microsecond <http://www.python.org/sf/661086>. + Library ------- From tim_one@users.sourceforge.net Thu Jan 2 19:25:29 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 11:25:29 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.138,1.139 doc.txt,1.77,1.78 test_datetime.py,1.92,1.93 Message-ID: <E18UAy9-0001SI-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv5288 Modified Files: datetime.py doc.txt test_datetime.py Log Message: astimezone() internals: if utcoffset() returns a duration, complain if dst() returns None (instead of treating that as 0). Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.138 retrieving revision 1.139 diff -C2 -d -r1.138 -r1.139 *** datetime.py 2 Jan 2003 17:47:06 -0000 1.138 --- datetime.py 2 Jan 2003 19:25:27 -0000 1.139 *************** *** 1645,1649 **** otdst = other.dst() if otdst is None: ! otdst = 0 total_added_to_other = otoff - otdst - myoff if total_added_to_other: --- 1645,1650 ---- otdst = other.dst() if otdst is None: ! raise ValueError("astimezone(): utcoffset() returned a duration " ! "but dst() returned None") total_added_to_other = otoff - otdst - myoff if total_added_to_other: *************** *** 1666,1669 **** --- 1667,1672 ---- other += delta otoff = other.utcoffset() + if otoff is None: + self._inconsistent_utcoffset_error() ##assert (other == self) == (otoff - myoff == total_added_to_other) if otoff - myoff == total_added_to_other: Index: doc.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v retrieving revision 1.77 retrieving revision 1.78 diff -C2 -d -r1.77 -r1.78 *** doc.txt 1 Jan 2003 20:52:11 -0000 1.77 --- doc.txt 2 Jan 2003 19:25:27 -0000 1.78 *************** *** 792,805 **** return CONSTANT + self.dst(dt) # daylight-aware class ! - tzname(self, dt) ! Return the timezone name corresponding to the datetime represented ! by dt, as a string. Nothing about string names is defined by the ! datetime module, and there's no requirement that it mean anything ! in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", ! "US/Eastern", "America/New York" are all valid replies. Return ! None if a string name isn't known. Note that this is a method ! rather than a fixed string primarily because some tzinfo objects ! will wish to return different names depending on the specific value ! of dt passed, especially if the tzinfo class is accounting for DST. - dst(self, dt) --- 792,797 ---- return CONSTANT + self.dst(dt) # daylight-aware class ! If utcoffset() does not return None, dst() should not return None ! either. - dst(self, dt) *************** *** 826,829 **** --- 818,832 ---- this, but cannot detect violations; it's the programmer's responsibility to ensure it. + + - tzname(self, dt) + Return the timezone name corresponding to the datetime represented + by dt, as a string. Nothing about string names is defined by the + datetime module, and there's no requirement that it mean anything + in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", + "US/Eastern", "America/New York" are all valid replies. Return + None if a string name isn't known. Note that this is a method + rather than a fixed string primarily because some tzinfo objects + will wish to return different names depending on the specific value + of dt passed, especially if the tzinfo class is accounting for DST. These methods are called by a datetimetz or timetz object, in response to Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.92 retrieving revision 1.93 diff -C2 -d -r1.92 -r1.93 *** test_datetime.py 1 Jan 2003 20:52:12 -0000 1.92 --- test_datetime.py 2 Jan 2003 19:25:27 -0000 1.93 *************** *** 2606,2609 **** --- 2606,2611 ---- dstoff = datetimetz(2002, 10, 27, 2) + theclass = datetimetz + # Check a time that's inside DST. def checkinside(self, dt, tz, utc, dston, dstoff): *************** *** 2743,2746 **** --- 2745,2763 ---- got = sixutc.astimezone(Eastern).astimezone(None) self.assertEqual(expected, got) + + def test_bogus_dst(self): + class ok(tzinfo): + def utcoffset(self, dt): return HOUR + def dst(self, dt): return HOUR + + now = self.theclass.now().replace(tzinfo=utc_real) + # Doesn't blow up. + now.astimezone(ok()) + + # Does blow up. + class notok(ok): + def dst(self, dt): return None + self.assertRaises(ValueError, now.astimezone, notok()) + def test_suite(): From tim_one@users.sourceforge.net Thu Jan 2 19:35:55 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 11:35:55 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.26,1.27 Message-ID: <E18UB8F-0002ap-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv9800/Doc/lib Modified Files: libdatetime.tex Log Message: astimezone() internals: if utcoffset() returns a duration, complain if dst() returns None (instead of treating that as 0). Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** libdatetime.tex 1 Jan 2003 21:51:36 -0000 1.26 --- libdatetime.tex 2 Jan 2003 19:35:53 -0000 1.27 *************** *** 894,912 **** return CONSTANT + self.dst(dt) # daylight-aware class \end{verbatim} - \end{methoddesc} ! \begin{methoddesc}{tzname}{self, dt} ! Return the timezone name corresponding to the \class{datetime} represented ! by \var{dt}, as a string. Nothing about string names is defined by the ! \module{datetime} module, and there's no requirement that it mean anything ! in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", ! "US/Eastern", "America/New York" are all valid replies. Return ! \code{None} if a string name isn't known. Note that this is a method ! rather than a fixed string primarily because some \class{tzinfo} objects ! will wish to return different names depending on the specific value ! of \var{dt} passed, especially if the \class{tzinfo} class is ! accounting for daylight time. \end{methoddesc} \begin{methoddesc}{dst}{self, dt} Return the daylight savings time (DST) adjustment, in minutes east of --- 894,905 ---- return CONSTANT + self.dst(dt) # daylight-aware class \end{verbatim} ! If \method{utcoffset()} does not return \code{None}, ! \method{dst()} should not return \code{None} either. ! ! \end{methoddesc} + \begin{methoddesc}{dst}{self, dt} Return the daylight savings time (DST) adjustment, in minutes east of *************** *** 938,941 **** --- 931,947 ---- ensure it. + \begin{methoddesc}{tzname}{self, dt} + Return the timezone name corresponding to the \class{datetime} represented + by \var{dt}, as a string. Nothing about string names is defined by the + \module{datetime} module, and there's no requirement that it mean anything + in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", + "US/Eastern", "America/New York" are all valid replies. Return + \code{None} if a string name isn't known. Note that this is a method + rather than a fixed string primarily because some \class{tzinfo} objects + will wish to return different names depending on the specific value + of \var{dt} passed, especially if the \class{tzinfo} class is + accounting for daylight time. + \end{methoddesc} + \end{methoddesc} *************** *** 1380,1384 **** >>> from datetime import * >>> class TZ(tzinfo): ! ... def utcoffset(self, dt): return -399 ... >>> datetimetz(2002, 12, 25, tzinfo=TZ()).isoformat(' ') --- 1386,1390 ---- >>> from datetime import * >>> class TZ(tzinfo): ! ... def utcoffset(self, dt): return timedelta(minutes=-399) ... >>> datetimetz(2002, 12, 25, tzinfo=TZ()).isoformat(' ') From tim_one@users.sourceforge.net Thu Jan 2 19:35:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 11:35:56 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.19,1.20 Message-ID: <E18UB8G-0002ax-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv9800/Lib/test Modified Files: test_datetime.py Log Message: astimezone() internals: if utcoffset() returns a duration, complain if dst() returns None (instead of treating that as 0). Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_datetime.py 1 Jan 2003 21:51:36 -0000 1.19 --- test_datetime.py 2 Jan 2003 19:35:53 -0000 1.20 *************** *** 2592,2595 **** --- 2592,2597 ---- dstoff = datetimetz(2002, 10, 27, 2) + theclass = datetimetz + # Check a time that's inside DST. def checkinside(self, dt, tz, utc, dston, dstoff): *************** *** 2729,2732 **** --- 2731,2749 ---- got = sixutc.astimezone(Eastern).astimezone(None) self.assertEqual(expected, got) + + def test_bogus_dst(self): + class ok(tzinfo): + def utcoffset(self, dt): return HOUR + def dst(self, dt): return HOUR + + now = self.theclass.now().replace(tzinfo=utc_real) + # Doesn't blow up. + now.astimezone(ok()) + + # Does blow up. + class notok(ok): + def dst(self, dt): return None + self.assertRaises(ValueError, now.astimezone, notok()) + def test_suite(): From tim_one@users.sourceforge.net Thu Jan 2 19:35:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 11:35:56 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.590,1.591 Message-ID: <E18UB8G-0002b3-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv9800/Misc Modified Files: NEWS Log Message: astimezone() internals: if utcoffset() returns a duration, complain if dst() returns None (instead of treating that as 0). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.590 retrieving revision 1.591 diff -C2 -d -r1.590 -r1.591 *** NEWS 2 Jan 2003 19:10:19 -0000 1.590 --- NEWS 2 Jan 2003 19:35:54 -0000 1.591 *************** *** 23,26 **** --- 23,30 ---- microsecond <http://www.python.org/sf/661086>. + In dt.asdatetime(tz), if tz.utcoffset(dt) returns a duration, + ValueError is raised of tz.dst(dt) returns None (2.3a1 treated it + as 0 instead). + Library ------- From tim_one@users.sourceforge.net Thu Jan 2 19:35:57 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 11:35:57 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.26,1.27 Message-ID: <E18UB8H-0002b9-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv9800/Modules Modified Files: datetimemodule.c Log Message: astimezone() internals: if utcoffset() returns a duration, complain if dst() returns None (instead of treating that as 0). Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** datetimemodule.c 2 Jan 2003 17:55:03 -0000 1.26 --- datetimemodule.c 2 Jan 2003 19:35:54 -0000 1.27 *************** *** 4806,4810 **** if (resdst == -1 && PyErr_Occurred()) goto Fail; ! /* None and 0 dst() results are the same to us here. Debatable. */ total_added_to_result = resoff - resdst - selfoff; if (total_added_to_result != 0) { --- 4806,4814 ---- if (resdst == -1 && PyErr_Occurred()) goto Fail; ! if (none) { ! PyErr_SetString(PyExc_ValueError, "astimezone(): utcoffset() " ! "returned a duration but dst() returned None"); ! goto Fail; ! } total_added_to_result = resoff - resdst - selfoff; if (total_added_to_result != 0) { From rhettinger@users.sourceforge.net Thu Jan 2 19:46:51 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 02 Jan 2003 11:46:51 -0800 Subject: [Python-checkins] python/nondist/sandbox/twister Makefile,1.2,NONE NEWS,1.2,NONE _random.c,1.26,NONE librandom.tex,1.6,NONE random.py,1.10,NONE setup.py,1.2,NONE test_random.py,1.13,NONE Message-ID: <E18UBIp-0003nF-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/twister In directory sc8-pr-cvs1:/tmp/cvs-serv14553 Removed Files: Makefile NEWS _random.c librandom.tex random.py setup.py test_random.py Log Message: Clean sandbox --- Makefile DELETED --- --- NEWS DELETED --- --- _random.c DELETED --- --- librandom.tex DELETED --- --- random.py DELETED --- --- setup.py DELETED --- --- test_random.py DELETED --- From montanaro@users.sourceforge.net Thu Jan 2 20:51:10 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 02 Jan 2003 12:51:10 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.591,1.592 Message-ID: <E18UCJ4-0001f7-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv5845/Misc Modified Files: NEWS Log Message: Allow list sort's comparison function to explicitly be None. See SF patch 661092. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.591 retrieving revision 1.592 diff -C2 -d -r1.591 -r1.592 *** NEWS 2 Jan 2003 19:35:54 -0000 1.591 --- NEWS 2 Jan 2003 20:51:05 -0000 1.592 *************** *** 13,16 **** --- 13,20 ---- ----------------- + - List objects' sort() method now accepts None as the comparison function. + Passing None is semantically identical to calling sort() with no + arguments. + Extension modules ----------------- From montanaro@users.sourceforge.net Thu Jan 2 20:51:10 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 02 Jan 2003 12:51:10 -0800 Subject: [Python-checkins] python/dist/src/Objects listobject.c,2.144,2.145 Message-ID: <E18UCJ4-0001fB-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv5845/Objects Modified Files: listobject.c Log Message: Allow list sort's comparison function to explicitly be None. See SF patch 661092. Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.144 retrieving revision 2.145 diff -C2 -d -r2.144 -r2.145 *** listobject.c 29 Dec 2002 16:33:11 -0000 2.144 --- listobject.c 2 Jan 2003 20:51:08 -0000 2.145 *************** *** 1658,1661 **** --- 1658,1664 ---- return NULL; } + if (compare == Py_None) + compare = NULL; + merge_init(&ms, compare); *************** *** 2070,2074 **** "L.reverse() -- reverse *IN PLACE*"); PyDoc_STRVAR(sort_doc, ! "L.sort([cmpfunc]) -- stable sort *IN PLACE*; cmpfunc(x, y) -> -1, 0, 1"); static PyMethodDef list_methods[] = { --- 2073,2077 ---- "L.reverse() -- reverse *IN PLACE*"); PyDoc_STRVAR(sort_doc, ! "L.sort(cmpfunc=None) -- stable sort *IN PLACE*; cmpfunc(x, y) -> -1, 0, 1"); static PyMethodDef list_methods[] = { From montanaro@users.sourceforge.net Thu Jan 2 20:51:37 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 02 Jan 2003 12:51:37 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sort.py,1.3,1.4 Message-ID: <E18UCJV-0001em-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv5845/Lib/test Modified Files: test_sort.py Log Message: Allow list sort's comparison function to explicitly be None. See SF patch 661092. Index: test_sort.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sort.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_sort.py 12 Nov 2002 22:08:08 -0000 1.3 --- test_sort.py 2 Jan 2003 20:51:04 -0000 1.4 *************** *** 146,149 **** --- 146,169 ---- bug453523() + def cmpNone(): + global nerrors + + if verbose: + print "Testing None as a comparison function." + + L = range(50) + random.shuffle(L) + try: + L.sort(None) + except TypeError: + print " Passing None as cmpfunc failed." + nerrors += 1 + else: + if L != range(50): + print " Passing None as cmpfunc failed." + nerrors += 1 + + cmpNone() + if nerrors: print "Test failed", nerrors From montanaro@users.sourceforge.net Thu Jan 2 20:51:37 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 02 Jan 2003 12:51:37 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex,1.115,1.116 Message-ID: <E18UCJV-0001eh-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv5845/Doc/lib Modified Files: libstdtypes.tex Log Message: Allow list sort's comparison function to explicitly be None. See SF patch 661092. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.115 retrieving revision 1.116 diff -C2 -d -r1.115 -r1.116 *** libstdtypes.tex 29 Dec 2002 05:49:09 -0000 1.115 --- libstdtypes.tex 2 Jan 2003 20:51:03 -0000 1.116 *************** *** 926,930 **** \lineiii{\var{s}.reverse()} {reverses the items of \var{s} in place}{(6)} ! \lineiii{\var{s}.sort(\optional{\var{cmpfunc}})} {sort the items of \var{s} in place}{(6), (7), (8), (9)} \end{tableiii} --- 926,930 ---- \lineiii{\var{s}.reverse()} {reverses the items of \var{s} in place}{(6)} ! \lineiii{\var{s}.sort(\optional{\var{cmpfunc=None}})} {sort the items of \var{s} in place}{(6), (7), (8), (9)} \end{tableiii} *************** *** 971,978 **** than the second argument. Note that this slows the sorting process down considerably; e.g. to sort a list in reverse order it is much ! faster to call method \method{sort()} followed by ! \method{reverse()} than to use method ! \method{sort()} with a comparison function that reverses the ! ordering of the elements. \item[(8)] Whether the \method{sort()} method is stable is not defined by --- 971,979 ---- than the second argument. Note that this slows the sorting process down considerably; e.g. to sort a list in reverse order it is much ! faster to call method \method{sort()} followed by \method{reverse()} ! than to use method \method{sort()} with a comparison function that ! reverses the ordering of the elements. Passing \constant{None} as the ! comparison function is semantically equivalent to calling ! \method{sort()} with no comparison function. \item[(8)] Whether the \method{sort()} method is stable is not defined by From tim_one@users.sourceforge.net Thu Jan 2 21:01:26 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:01:26 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime US.py,1.14,1.15 datetime.py,1.139,1.140 doc.txt,1.78,1.79 test_datetime.py,1.93,1.94 Message-ID: <E18UCT0-0002ZO-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv9826 Modified Files: US.py datetime.py doc.txt test_datetime.py Log Message: The tzinfo methods utcoffset() and dst() must return a timedelta object (or None) now. In 2.3a1 they could also return an int or long, but that was an unhelpfully redundant leftover from an earlier version wherein they couldn't return a timedelta. TOOWTDI. Index: US.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/US.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** US.py 31 Dec 2002 05:58:02 -0000 1.14 --- US.py 2 Jan 2003 21:01:19 -0000 1.15 *************** *** 130,140 **** Converting to UTC and subtracting, we get the "about an hour": >>> class UTC(tzinfo): ... def utcoffset(self, dt): ! ... return 0 ... def tzname(self, dt): ... return "utc" - ... def dst(self, dt): - ... return 0 >>> utc = UTC() --- 130,140 ---- Converting to UTC and subtracting, we get the "about an hour": + >>> ZERO = timedelta(0) >>> class UTC(tzinfo): ... def utcoffset(self, dt): ! ... return ZERO ! ... dst = utcoffset ... def tzname(self, dt): ... return "utc" >>> utc = UTC() Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.139 retrieving revision 1.140 diff -C2 -d -r1.139 -r1.140 *** datetime.py 2 Jan 2003 19:25:27 -0000 1.139 --- datetime.py 2 Jan 2003 21:01:19 -0000 1.140 *************** *** 237,241 **** # name is the offset-producing method, "utcoffset" or "dst". # offset is what it returned. ! # If offset isn't None, int, long, or timedelta, raises TypeError. # If offset is None, returns None. # Else offset is checked for being in range, and a whole # of minutes. --- 237,241 ---- # name is the offset-producing method, "utcoffset" or "dst". # offset is what it returned. ! # If offset isn't None or timedelta, raises TypeError. # If offset is None, returns None. # Else offset is checked for being in range, and a whole # of minutes. *************** *** 245,262 **** if offset is None: return None ! if not isinstance(offset, (int, long, timedelta)): ! raise TypeError("tzinfo.%s() must return None, integer " "or timedelta, not '%s'" % (name, type(offset))) ! if isinstance(offset, timedelta): ! days = offset.days ! if days < -1 or days > 0: ! offset = 1440 # trigger out-of-range ! else: ! seconds = days * 86400 + offset.seconds ! minutes, seconds = divmod(seconds, 60) ! if seconds or offset.microseconds: ! raise ValueError("tzinfo.%s() must return a whole number " ! "of minutes" % name) ! offset = minutes if -1440 < offset < 1440: return offset --- 245,261 ---- if offset is None: return None ! if not isinstance(offset, timedelta): ! raise TypeError("tzinfo.%s() must return None " "or timedelta, not '%s'" % (name, type(offset))) ! days = offset.days ! if days < -1 or days > 0: ! offset = 1440 # trigger out-of-range ! else: ! seconds = days * 86400 + offset.seconds ! minutes, seconds = divmod(seconds, 60) ! if seconds or offset.microseconds: ! raise ValueError("tzinfo.%s() must return a whole number " ! "of minutes" % name) ! offset = minutes if -1440 < offset < 1440: return offset Index: doc.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -d -r1.78 -r1.79 *** doc.txt 2 Jan 2003 19:25:27 -0000 1.78 --- doc.txt 2 Jan 2003 21:01:21 -0000 1.79 *************** *** 783,790 **** tzinfo object represents both time zone and DST adjustments, utcoffset() should return their sum. If the UTC offset isn't known, ! return None. Else the value returned must be an int, long, or ! timedelta object, in the range -1439 to 1439 inclusive (1440 = 24*60; ! the magnitude of the offset must be less than one day, and must be ! a whole number of minutes). Most implementations of utcoffset() will probably look like: --- 783,790 ---- tzinfo object represents both time zone and DST adjustments, utcoffset() should return their sum. If the UTC offset isn't known, ! return None. Else the value returned must be a timedelta object ! specifying a whole number of minutes in the range -1439 to 1439 ! inclusive (1440 = 24*60; the magnitude of the offset must be less ! than one day). Most implementations of utcoffset() will probably look like: *************** *** 798,809 **** Return the DST offset, in minutes east of UTC, or None if DST information isn't known. Return 0 if DST is not in effect. ! If DST is in effect, return an int, long, or timedelta object, in ! the range -1439 to 1439 inclusive. This must be a whole number of ! minutes. Note that DST offset, if applicable, has already been added ! to the UTC offset returned by utcoffset(), so there's no need to ! consult dst() unless you're interested in displaying DST info ! separately. For example, datetimetz.timetuple() calls its ! tzinfo object's dst() method to determine how the tm_isdst flag ! should be set. An instance tz of a tzinfo subclass that models both standard and --- 798,809 ---- Return the DST offset, in minutes east of UTC, or None if DST information isn't known. Return 0 if DST is not in effect. ! If DST is in effect, return the offset as a timedelta object (see ! utcoffset() for details). Note that DST offset, if applicable, has ! already been added to the UTC offset returned by utcoffset(), so ! there's no need to consult dst() unless you're interested in ! displaying DST info separately. For example, datetimetz.timetuple() ! calls its tzinfo object's dst() method to determine how the tm_isdst ! flag should be set, and datetimetz.astimezone() calls dst() to ! account for DST changes when crossing time zones. An instance tz of a tzinfo subclass that models both standard and *************** *** 850,878 **** Example tzinfo classes: ! class UTC(tzinfo): ! "UTC" def utcoffset(self, dt): ! return 0 def tzname(self, dt): return "UTC" def dst(self, dt): ! return 0 class FixedOffset(tzinfo): ! "Fixed offset in minutes east from UTC" def __init__(self, offset, name): self.__offset = offset self.__name = name def utcoffset(self, dt): return self.__offset def tzname(self, dt): return self.__name def dst(self, dt): ! # It depends on more than we know in an example. ! return None # Indicate we don't know import time class LocalTime(tzinfo): ! "Local time as defined by the operating system" def _isdst(self, dt): t = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, --- 850,890 ---- Example tzinfo classes: ! from datetime import tzinfo, timedelta ! ! ZERO = timedelta(0) ! ! class UTC(tzinfo): ! """UTC""" ! def utcoffset(self, dt): ! return ZERO ! def tzname(self, dt): return "UTC" + def dst(self, dt): ! return ZERO class FixedOffset(tzinfo): ! """Fixed offset in minutes east from UTC.""" ! def __init__(self, offset, name): self.__offset = offset self.__name = name + def utcoffset(self, dt): return self.__offset + def tzname(self, dt): return self.__name + def dst(self, dt): ! return ZERO import time + class LocalTime(tzinfo): ! """Local time as defined by the operating system.""" ! def _isdst(self, dt): t = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, *************** *** 881,889 **** t = time.localtime(time.mktime(t)) return t.tm_isdst > 0 def utcoffset(self, dt): if self._isdst(dt): ! return -time.timezone/60 else: ! return -time.altzone/60 def tzname(self, dt): return time.tzname[self._isdst(dt)] --- 893,903 ---- t = time.localtime(time.mktime(t)) return t.tm_isdst > 0 + def utcoffset(self, dt): if self._isdst(dt): ! return timedelta(seconds=-time.timezone//60) else: ! return timedelta(seconds=-time.altzone//60) ! def tzname(self, dt): return time.tzname[self._isdst(dt)] Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -d -r1.93 -r1.94 *** test_datetime.py 2 Jan 2003 19:25:27 -0000 1.93 --- test_datetime.py 2 Jan 2003 21:01:22 -0000 1.94 *************** *** 44,47 **** --- 44,51 ---- class FixedOffset(tzinfo): def __init__(self, offset, name, dstoffset=42): + if isinstance(offset, int): + offset = timedelta(minutes=offset) + if isinstance(dstoffset, int): + dstoffset = timedelta(minutes=dstoffset) self.__offset = offset self.__name = name *************** *** 90,96 **** self.failUnless(isinstance(fo, tzinfo)) for dt in datetime.now(), None: ! self.assertEqual(fo.utcoffset(dt), 3) self.assertEqual(fo.tzname(dt), "Three") ! self.assertEqual(fo.dst(dt), 42) def test_pickling_base(self): --- 94,100 ---- self.failUnless(isinstance(fo, tzinfo)) for dt in datetime.now(), None: ! self.assertEqual(fo.utcoffset(dt), timedelta(minutes=3)) self.assertEqual(fo.tzname(dt), "Three") ! self.assertEqual(fo.dst(dt), timedelta(minutes=42)) def test_pickling_base(self): *************** *** 112,119 **** # Make sure we can pickle/unpickle an instance of a subclass. ! orig = PicklableFixedOffset(-300, 'cookie') self.failUnless(isinstance(orig, tzinfo)) self.failUnless(type(orig) is PicklableFixedOffset) ! self.assertEqual(orig.utcoffset(None), -300) self.assertEqual(orig.tzname(None), 'cookie') for pickler in pickle, cPickle: --- 116,124 ---- # Make sure we can pickle/unpickle an instance of a subclass. ! offset = timedelta(minutes=-300) ! orig = PicklableFixedOffset(offset, 'cookie') self.failUnless(isinstance(orig, tzinfo)) self.failUnless(type(orig) is PicklableFixedOffset) ! self.assertEqual(orig.utcoffset(None), offset) self.assertEqual(orig.tzname(None), 'cookie') for pickler in pickle, cPickle: *************** *** 123,127 **** self.failUnless(isinstance(derived, tzinfo)) self.failUnless(type(derived) is PicklableFixedOffset) ! self.assertEqual(derived.utcoffset(None), -300) self.assertEqual(derived.tzname(None), 'cookie') --- 128,132 ---- self.failUnless(isinstance(derived, tzinfo)) self.failUnless(type(derived) is PicklableFixedOffset) ! self.assertEqual(derived.utcoffset(None), offset) self.assertEqual(derived.tzname(None), 'cookie') *************** *** 1575,1579 **** class introspective(tzinfo): def tzname(self, dt): return dt and "real" or "none" ! def utcoffset(self, dt): return dt and 42 or -42 dst = utcoffset --- 1580,1585 ---- class introspective(tzinfo): def tzname(self, dt): return dt and "real" or "none" ! def utcoffset(self, dt): ! return timedelta(minutes = dt and 42 or -42) dst = utcoffset *************** *** 1606,1610 **** class Edgy(tzinfo): def __init__(self, offset): ! self.offset = offset def utcoffset(self, dt): return self.offset --- 1612,1616 ---- class Edgy(tzinfo): def __init__(self, offset): ! self.offset = timedelta(minutes=offset) def utcoffset(self, dt): return self.offset *************** *** 1642,1662 **** self.failUnless(t.tzname() is None) - class C2(tzinfo): - def utcoffset(self, dt): return -1439 - def dst(self, dt): return 1439 - def tzname(self, dt): return "aname" class C3(tzinfo): def utcoffset(self, dt): return timedelta(minutes=-1439) def dst(self, dt): return timedelta(minutes=1439) def tzname(self, dt): return "aname" ! for t in cls(1, 1, 1, tzinfo=C2()), cls(1, 1, 1, tzinfo=C3()): ! self.assertEqual(t.utcoffset(), timedelta(minutes=-1439)) ! self.assertEqual(t.dst(), timedelta(minutes=1439)) ! self.assertEqual(t.tzname(), "aname") # Wrong types. class C4(tzinfo): def utcoffset(self, dt): return "aname" ! def dst(self, dt): return () def tzname(self, dt): return 0 t = cls(1, 1, 1, tzinfo=C4()) --- 1648,1664 ---- self.failUnless(t.tzname() is None) class C3(tzinfo): def utcoffset(self, dt): return timedelta(minutes=-1439) def dst(self, dt): return timedelta(minutes=1439) def tzname(self, dt): return "aname" ! t = cls(1, 1, 1, tzinfo=C3()) ! self.assertEqual(t.utcoffset(), timedelta(minutes=-1439)) ! self.assertEqual(t.dst(), timedelta(minutes=1439)) ! self.assertEqual(t.tzname(), "aname") # Wrong types. class C4(tzinfo): def utcoffset(self, dt): return "aname" ! def dst(self, dt): return 7 def tzname(self, dt): return 0 t = cls(1, 1, 1, tzinfo=C4()) *************** *** 1666,1678 **** # Offset out of range. - class C5(tzinfo): - def utcoffset(self, dt): return -1440 - def dst(self, dt): return 1440 class C6(tzinfo): def utcoffset(self, dt): return timedelta(hours=-24) def dst(self, dt): return timedelta(hours=24) ! for t in cls(1, 1, 1, tzinfo=C5()), cls(1, 1, 1, tzinfo=C6()): ! self.assertRaises(ValueError, t.utcoffset) ! self.assertRaises(ValueError, t.dst) # Not a whole number of minutes. --- 1668,1677 ---- # Offset out of range. class C6(tzinfo): def utcoffset(self, dt): return timedelta(hours=-24) def dst(self, dt): return timedelta(hours=24) ! t = cls(1, 1, 1, tzinfo=C6()) ! self.assertRaises(ValueError, t.utcoffset) ! self.assertRaises(ValueError, t.dst) # Not a whole number of minutes. *************** *** 1692,1698 **** def utcoffset(self, t): if t.minute < 10: ! return t.minute # d0 and d1 equal after adjustment else: ! return 59 # d2 off in the weeds base = cls(8, 9, 10, tzinfo=OperandDependentOffset()) --- 1691,1699 ---- def utcoffset(self, t): if t.minute < 10: ! # d0 and d1 equal after adjustment ! return timedelta(minutes=t.minute) else: ! # d2 off in the weeds ! return timedelta(minutes=59) base = cls(8, 9, 10, tzinfo=OperandDependentOffset()) *************** *** 1951,1957 **** class Varies(tzinfo): def __init__(self): ! self.offset = 22 def utcoffset(self, t): ! self.offset += 1 return self.offset --- 1952,1958 ---- class Varies(tzinfo): def __init__(self): ! self.offset = timedelta(minutes=22) def utcoffset(self, t): ! self.offset += timedelta(minutes=1) return self.offset *************** *** 2042,2046 **** # Try a bogus uctoffset. class Bogus(tzinfo): ! def utcoffset(self, dt): return 1440 # out of bounds t1 = self.theclass(2, 2, 2, tzinfo=Bogus()) t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, "")) --- 2043,2048 ---- # Try a bogus uctoffset. class Bogus(tzinfo): ! def utcoffset(self, dt): ! return timedelta(minutes=1440) # out of bounds t1 = self.theclass(2, 2, 2, tzinfo=Bogus()) t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, "")) *************** *** 2273,2276 **** --- 2275,2280 ---- class DST(tzinfo): def __init__(self, dstvalue): + if isinstance(dstvalue, int): + dstvalue = timedelta(minutes=dstvalue) self.dstvalue = dstvalue def dst(self, dt): *************** *** 2305,2308 **** --- 2309,2314 ---- class DST(tzinfo): def __init__(self, dstvalue): + if isinstance(dstvalue, int): + dstvalue = timedelta(minutes=dstvalue) self.dstvalue = dstvalue def dst(self, dt): *************** *** 2317,2321 **** def __init__(self, uofs, dofs=None): DST.__init__(self, dofs) ! self.uofs = uofs def utcoffset(self, dt): return self.uofs --- 2323,2327 ---- def __init__(self, uofs, dofs=None): DST.__init__(self, dofs) ! self.uofs = timedelta(minutes=uofs) def utcoffset(self, dt): return self.uofs *************** *** 2468,2474 **** def utcoffset(self, t): if t.minute < 10: ! return t.minute # d0 and d1 equal after adjustment else: ! return 59 # d2 off in the weeds base = cls(8, 9, 10, 11, 12, 13, 14, tzinfo=OperandDependentOffset()) --- 2474,2482 ---- def utcoffset(self, t): if t.minute < 10: ! # d0 and d1 equal after adjustment ! return timedelta(minutes=t.minute) else: ! # d2 off in the weeds ! return timedelta(minutes=59) base = cls(8, 9, 10, 11, 12, 13, 14, tzinfo=OperandDependentOffset()) *************** *** 2517,2523 **** class Varies(tzinfo): def __init__(self): ! self.offset = 22 def utcoffset(self, t): ! self.offset += 1 return self.offset --- 2525,2531 ---- class Varies(tzinfo): def __init__(self): ! self.offset = timedelta(minutes=22) def utcoffset(self, t): ! self.offset += timedelta(minutes=1) return self.offset From jackjansen@users.sourceforge.net Thu Jan 2 21:15:31 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:15:31 -0800 Subject: [Python-checkins] python/dist/src/Python getcopyright.c,1.16,1.16.4.1 Message-ID: <E18UCgd-0003iQ-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv14268 Modified Files: Tag: r23a1-branch getcopyright.c Log Message: Merged 2003 copyright from the trunk. Index: getcopyright.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getcopyright.c,v retrieving revision 1.16 retrieving revision 1.16.4.1 diff -C2 -d -r1.16 -r1.16.4.1 *** getcopyright.c 27 Feb 2002 13:29:46 -0000 1.16 --- getcopyright.c 2 Jan 2003 21:15:28 -0000 1.16.4.1 *************** *** 5,9 **** static char cprt[] = "\ ! Copyright (c) 2001, 2002 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ --- 5,9 ---- static char cprt[] = "\ ! Copyright (c) 2001, 2002, 2003 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ From jackjansen@users.sourceforge.net Thu Jan 2 21:16:51 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:16:51 -0800 Subject: [Python-checkins] python/dist/src/Mac/Resources pythonpath.r,1.15,1.15.2.1 Message-ID: <E18UChv-0003pB-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Mac/Resources In directory sc8-pr-cvs1:/tmp/cvs-serv14650 Modified Files: Tag: r23a1-branch pythonpath.r Log Message: lib-scriptpackages was missing from sys.path. Added. Index: pythonpath.r =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Resources/pythonpath.r,v retrieving revision 1.15 retrieving revision 1.15.2.1 diff -C2 -d -r1.15 -r1.15.2.1 *** pythonpath.r 30 Dec 2002 23:07:44 -0000 1.15 --- pythonpath.r 2 Jan 2003 21:16:47 -0000 1.15.2.1 *************** *** 90,95 **** "$(PYTHON)", "$(PYTHON):Lib", - "$(PYTHON):Lib:plat-mac", "$(PYTHON):Lib:lib-dynload", "$(PYTHON):Mac:Lib", "$(PYTHON):Extensions:img:Mac", --- 90,96 ---- "$(PYTHON)", "$(PYTHON):Lib", "$(PYTHON):Lib:lib-dynload", + "$(PYTHON):Lib:plat-mac", + "$(PYTHON):Lib:plat-mac:lib-scriptpackages", "$(PYTHON):Mac:Lib", "$(PYTHON):Extensions:img:Mac", From tim_one@users.sourceforge.net Thu Jan 2 21:17:21 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:17:21 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime doc.txt,1.79,1.80 Message-ID: <E18UCiP-0003sN-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv14827 Modified Files: doc.txt Log Message: Repaired LocalTime example. Index: doc.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v retrieving revision 1.79 retrieving revision 1.80 diff -C2 -d -r1.79 -r1.80 *** doc.txt 2 Jan 2003 21:01:21 -0000 1.79 --- doc.txt 2 Jan 2003 21:17:19 -0000 1.80 *************** *** 896,902 **** def utcoffset(self, dt): if self._isdst(dt): ! return timedelta(seconds=-time.timezone//60) else: ! return timedelta(seconds=-time.altzone//60) def tzname(self, dt): --- 896,902 ---- def utcoffset(self, dt): if self._isdst(dt): ! return timedelta(seconds=-time.timezone) else: ! return timedelta(seconds=-time.altzone) def tzname(self, dt): From jackjansen@users.sourceforge.net Thu Jan 2 21:18:49 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:18:49 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts fullbuild.py,1.88,1.88.2.1 genpluginprojects.py,1.38,1.38.2.1 Message-ID: <E18UCjp-0003zA-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv15285 Modified Files: Tag: r23a1-branch fullbuild.py genpluginprojects.py Log Message: - Added datetime - Moved Carbon plugin modules (the underlying _ versions) to lib-dynload. Index: fullbuild.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fullbuild.py,v retrieving revision 1.88 retrieving revision 1.88.2.1 diff -C2 -d -r1.88 -r1.88.2.1 *** fullbuild.py 24 Dec 2002 13:07:58 -0000 1.88 --- fullbuild.py 2 Jan 2003 21:18:44 -0000 1.88.2.1 *************** *** 203,206 **** --- 203,207 ---- (":Mac:Build:pyexpat.carbon.mcp", "pyexpat.carbon"), (":Mac:Build:calldll.carbon.mcp", "calldll.carbon"), + (":Mac:Build:datetime.carbon.mcp", "datetime.carbon"), (":Mac:Build:gdbm.carbon.mcp", "gdbm.carbon"), (":Mac:Build:icglue.carbon.mcp", "icglue.carbon"), Index: genpluginprojects.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/genpluginprojects.py,v retrieving revision 1.38 retrieving revision 1.38.2.1 diff -C2 -d -r1.38 -r1.38.2.1 *** genpluginprojects.py 24 Dec 2002 13:07:58 -0000 1.38 --- genpluginprojects.py 2 Jan 2003 21:18:45 -0000 1.38.2.1 *************** *** 115,164 **** genpluginproject("carbon", "_testcapi") genpluginproject("carbon", "xx") genpluginproject("carbon", "xxsubtype", sources=["xxsubtype.c"]) genpluginproject("carbon", "_hotshot", sources=["_hotshot.c"]) # bgen-generated Toolbox modules ! genpluginproject("carbon", "_AE", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_AH", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_App", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Cm", outputdir="::Lib:Carbon") ! # XXX can't work properly because we need to set a custom fragment initializer ! #genpluginproject("carbon", "_CG", ! # sources=["_CGModule.c", "CFMLateImport.c"], ! # libraries=["CGStubLib"], ! # outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Ctl", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Dlg", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Drag", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Evt", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_File", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Fm", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Folder", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Help", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_IBCarbon", sources=[":ibcarbon:_IBCarbon.c"], ! outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Icn", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_List", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Menu", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Qd", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Qt", ! libraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Qdoffs", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Res", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Scrap", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Snd", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Sndihooks", sources=[":snd:_Sndihooks.c"], outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_TE", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Mlte", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Win", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_CF", sources=["_CFmodule.c", "pycfbridge.c"], outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_CarbonEvt", outputdir="::Lib:Carbon") genpluginproject("carbon", "hfsplus") --- 115,159 ---- genpluginproject("carbon", "_testcapi") genpluginproject("carbon", "xx") + genpluginproject("carbon", "datetime") genpluginproject("carbon", "xxsubtype", sources=["xxsubtype.c"]) genpluginproject("carbon", "_hotshot", sources=["_hotshot.c"]) # bgen-generated Toolbox modules ! genpluginproject("carbon", "_AE") ! genpluginproject("carbon", "_AH") ! genpluginproject("carbon", "_App") ! genpluginproject("carbon", "_Cm") ! genpluginproject("carbon", "_Ctl") ! genpluginproject("carbon", "_Dlg") ! genpluginproject("carbon", "_Drag") genpluginproject("carbon", "_Evt", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_File", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_Fm", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_Folder", ! stdlibraryflags="Debug, WeakImport") ! genpluginproject("carbon", "_Help") ! genpluginproject("carbon", "_IBCarbon", sources=[":ibcarbon:_IBCarbon.c"]) ! genpluginproject("carbon", "_Icn") ! genpluginproject("carbon", "_List") ! genpluginproject("carbon", "_Menu") genpluginproject("carbon", "_Qd", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_Qt", ! libraryflags="Debug, WeakImport") genpluginproject("carbon", "_Qdoffs", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_Res", ! stdlibraryflags="Debug, WeakImport") ! genpluginproject("carbon", "_Scrap") ! genpluginproject("carbon", "_Snd") ! genpluginproject("carbon", "_Sndihooks", sources=[":snd:_Sndihooks.c"]) ! genpluginproject("carbon", "_TE") ! genpluginproject("carbon", "_Mlte") ! genpluginproject("carbon", "_Win") ! genpluginproject("carbon", "_CF", sources=["_CFmodule.c", "pycfbridge.c"]) ! genpluginproject("carbon", "_CarbonEvt") genpluginproject("carbon", "hfsplus") From jackjansen@users.sourceforge.net Thu Jan 2 21:19:16 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:19:16 -0800 Subject: [Python-checkins] python/dist/src/Mac/Build _CG.carbon.mcp,1.5,1.5.2.1 Message-ID: <E18UCkG-00041x-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Mac/Build In directory sc8-pr-cvs1:/tmp/cvs-serv15457 Modified Files: Tag: r23a1-branch _CG.carbon.mcp Log Message: - Moved Carbon plugin modules (the underlying _ versions) to lib-dynload. Index: _CG.carbon.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/_CG.carbon.mcp,v retrieving revision 1.5 retrieving revision 1.5.2.1 diff -C2 -d -r1.5 -r1.5.2.1 Binary files /tmp/cvsaD6E0V and /tmp/cvs0IdMLH differ From jackjansen@users.sourceforge.net Thu Jan 2 21:20:37 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:20:37 -0800 Subject: [Python-checkins] python/dist/src/Mac/Build PythonCore.mcp,1.41,1.41.2.1 PythonInterpreter.mcp,1.21,1.21.2.1 PythonStandSmall.mcp,1.47,1.47.2.1 Message-ID: <E18UClZ-0004AW-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Mac/Build In directory sc8-pr-cvs1:/tmp/cvs-serv15940 Modified Files: Tag: r23a1-branch PythonCore.mcp PythonInterpreter.mcp PythonStandSmall.mcp Log Message: Added datetime Index: PythonCore.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.mcp,v retrieving revision 1.41 retrieving revision 1.41.2.1 diff -C2 -d -r1.41 -r1.41.2.1 Binary files /tmp/cvsgp8ikQ and /tmp/cvsg1ZJ0v differ Index: PythonInterpreter.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonInterpreter.mcp,v retrieving revision 1.21 retrieving revision 1.21.2.1 diff -C2 -d -r1.21 -r1.21.2.1 Binary files /tmp/cvsRD1y6Z and /tmp/cvs8NLBOP differ Index: PythonStandSmall.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonStandSmall.mcp,v retrieving revision 1.47 retrieving revision 1.47.2.1 diff -C2 -d -r1.47 -r1.47.2.1 Binary files /tmp/cvswUzVe3 and /tmp/cvsMpbYxV differ From jackjansen@users.sourceforge.net Thu Jan 2 21:21:31 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:21:31 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.21,1.21.2.1 Message-ID: <E18UCmR-0004FZ-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv16293 Modified Files: Tag: r23a1-branch datetimemodule.c Log Message: Added a couple of casts to make this compile with CodeWarrior Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.21 retrieving revision 1.21.2.1 diff -C2 -d -r1.21 -r1.21.2.1 *** datetimemodule.c 31 Dec 2002 17:36:56 -0000 1.21 --- datetimemodule.c 2 Jan 2003 21:21:29 -0000 1.21.2.1 *************** *** 2561,2565 **** date_getstate(PyDateTime_Date *self) { ! return PyString_FromStringAndSize(self->data, _PyDateTime_DATE_DATASIZE); } --- 2561,2565 ---- date_getstate(PyDateTime_Date *self) { ! return PyString_FromStringAndSize((char *)self->data, _PyDateTime_DATE_DATASIZE); } *************** *** 3347,3351 **** datetime_getstate(PyDateTime_DateTime *self) { ! return PyString_FromStringAndSize(self->data, _PyDateTime_DATETIME_DATASIZE); } --- 3347,3351 ---- datetime_getstate(PyDateTime_DateTime *self) { ! return PyString_FromStringAndSize((char *)self->data, _PyDateTime_DATETIME_DATASIZE); } *************** *** 3817,3821 **** time_getstate(PyDateTime_Time *self) { ! return PyString_FromStringAndSize(self->data, _PyDateTime_TIME_DATASIZE); } --- 3817,3821 ---- time_getstate(PyDateTime_Time *self) { ! return PyString_FromStringAndSize((char *)self->data, _PyDateTime_TIME_DATASIZE); } From jackjansen@users.sourceforge.net Thu Jan 2 21:22:02 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:22:02 -0800 Subject: [Python-checkins] python/dist/src/Lib fileinput.py,1.15,1.15.2.1 Message-ID: <E18UCmw-0004I8-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv16449 Modified Files: Tag: r23a1-branch fileinput.py Log Message: Test that chmod() actually exists before calling it (it doesn't on MacOS9). Index: fileinput.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/fileinput.py,v retrieving revision 1.15 retrieving revision 1.15.2.1 diff -C2 -d -r1.15 -r1.15.2.1 *** fileinput.py 14 Aug 2002 02:58:16 -0000 1.15 --- fileinput.py 2 Jan 2003 21:22:00 -0000 1.15.2.1 *************** *** 310,314 **** self._output = os.fdopen(fd, "w") try: ! os.chmod(self._filename, perm) except OSError: pass --- 310,315 ---- self._output = os.fdopen(fd, "w") try: ! if hasattr(os, 'chmod'): ! os.chmod(self._filename, perm) except OSError: pass From jackjansen@users.sourceforge.net Thu Jan 2 21:24:24 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:24:24 -0800 Subject: [Python-checkins] python/dist/src/Lib os.py,1.63,1.63.2.1 Message-ID: <E18UCpE-0004VM-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv17293 Modified Files: Tag: r23a1-branch os.py Log Message: Always define getenv(), as suggested by Guido. This means that os.getenv() is also defined for MacPython-OS9 (even though it doesn't actually do anything useful), and it shouldn't hurt on other platforms. Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.63 retrieving revision 1.63.2.1 diff -C2 -d -r1.63 -r1.63.2.1 *** os.py 9 Oct 2002 17:23:29 -0000 1.63 --- os.py 2 Jan 2003 21:24:22 -0000 1.63.2.1 *************** *** 417,425 **** environ = _Environ(environ) ! def getenv(key, default=None): ! """Get an environment variable, return None if it doesn't exist. ! The optional second argument can specify an alternate default.""" ! return environ.get(key, default) ! __all__.append("getenv") def _exists(name): --- 417,425 ---- environ = _Environ(environ) ! def getenv(key, default=None): ! """Get an environment variable, return None if it doesn't exist. ! The optional second argument can specify an alternate default.""" ! return environ.get(key, default) ! __all__.append("getenv") def _exists(name): From tim_one@users.sourceforge.net Thu Jan 2 21:28:10 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:28:10 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.592,1.593 Message-ID: <E18UCss-0004uW-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv18654/python/Misc Modified Files: NEWS Log Message: The tzinfo methods utcoffset() and dst() must return a timedelta object (or None) now. In 2.3a1 they could also return an int or long, but that was an unhelpfully redundant leftover from an earlier version wherein they couldn't return a timedelta. TOOWTDI. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.592 retrieving revision 1.593 diff -C2 -d -r1.592 -r1.593 *** NEWS 2 Jan 2003 20:51:05 -0000 1.592 --- NEWS 2 Jan 2003 21:28:07 -0000 1.593 *************** *** 28,34 **** In dt.asdatetime(tz), if tz.utcoffset(dt) returns a duration, ! ValueError is raised of tz.dst(dt) returns None (2.3a1 treated it as 0 instead). ! Library ------- --- 28,39 ---- In dt.asdatetime(tz), if tz.utcoffset(dt) returns a duration, ! ValueError is raised if tz.dst(dt) returns None (2.3a1 treated it as 0 instead). ! ! The tzinfo methods utcoffset() and dst() must return a timedelta object ! (or None) now. In 2.3a1 they could also return an int or long, but that ! was an unhelpfully redundant leftover from an earlier version wherein ! they couldn't return a timedelta. TOOWTDI. ! Library ------- From tim_one@users.sourceforge.net Thu Jan 2 21:28:09 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:28:09 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.27,1.28 tzinfo-examples.py,1.1,1.2 Message-ID: <E18UCsr-0004uJ-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv18654/python/Doc/lib Modified Files: libdatetime.tex tzinfo-examples.py Log Message: The tzinfo methods utcoffset() and dst() must return a timedelta object (or None) now. In 2.3a1 they could also return an int or long, but that was an unhelpfully redundant leftover from an earlier version wherein they couldn't return a timedelta. TOOWTDI. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** libdatetime.tex 2 Jan 2003 19:35:53 -0000 1.27 --- libdatetime.tex 2 Jan 2003 21:28:07 -0000 1.28 *************** *** 232,247 **** \lineiii{\var{t1} = \var{t2} // \var{i}} {The floor is computed and the remainder (if any) is thrown away.} ! {(2)} \lineiii{+\var{t1}} {Returns a \class{timedelta} object with the same value.} ! {} \lineiii{-\var{t1}} {equivalent to \class{timedelta}(-\var{t1.days}, -\var{t1.seconds}, -\var{t1.microseconds}),and to \var{t1}* -1.} ! {(1)(3)} \lineiii{abs(\var{t})} {equivalent to +\var{t} when \code{t.days >= 0}, and to ! -\var{t} when \code{t.days < 0}.} ! {(1)} \end{tableiii} \noindent --- 232,248 ---- \lineiii{\var{t1} = \var{t2} // \var{i}} {The floor is computed and the remainder (if any) is thrown away.} ! {(3)} \lineiii{+\var{t1}} {Returns a \class{timedelta} object with the same value.} ! {(2)} \lineiii{-\var{t1}} {equivalent to \class{timedelta}(-\var{t1.days}, -\var{t1.seconds}, -\var{t1.microseconds}),and to \var{t1}* -1.} ! {(1)(4)} \lineiii{abs(\var{t})} {equivalent to +\var{t} when \code{t.days >= 0}, and to ! -\var{t} when \code{t.days < 0}. ! overflow.} ! {(2)} \end{tableiii} \noindent *************** *** 253,259 **** \item[(2)] ! Division by 0 raises \exception{ZeroDivisionError}. \item[(3)] -\var{timedelta.max} is not representable as a \class{timedelta} object. \end{description} --- 254,263 ---- \item[(2)] ! This is exact, and cannot overflow. \item[(3)] + Division by 0 raises \exception{ZeroDivisionError}. + + \item[(4)] -\var{timedelta.max} is not representable as a \class{timedelta} object. \end{description} *************** *** 884,892 **** \method{utcoffset()} should return their sum. If the UTC offset isn't known, return \code{None}. Else the value returned must be ! an integer, in the range -1439 to 1439 inclusive (1440 = 24*60; ! the magnitude of the offset must be less than one day), or a ! \class{timedelta} object representing a whole number of minutes ! in the same range. Most implementations of \method{utcoffset()} ! will probably look like one of these two: \begin{verbatim} --- 888,895 ---- \method{utcoffset()} should return their sum. If the UTC offset isn't known, return \code{None}. Else the value returned must be ! a \class{timedelta} object specifying a whole number of minutes in the ! range -1439 to 1439 inclusive (1440 = 24*60; the magnitude of the offset ! must be less than one day). Most implementations of ! \method{utcoffset()} will probably look like one of these two: \begin{verbatim} *************** *** 897,902 **** If \method{utcoffset()} does not return \code{None}, \method{dst()} should not return \code{None} either. - - \end{methoddesc} --- 900,903 ---- *************** *** 906,910 **** UTC, or \code{None} if DST information isn't known. Return \code{0} if DST is not in effect. ! If DST is in effect, return the offset as an integer or \class{timedelta} object (see \method{utcoffset()} for details). Note that DST offset, if applicable, has --- 907,911 ---- UTC, or \code{None} if DST information isn't known. Return \code{0} if DST is not in effect. ! If DST is in effect, return the offset as a \class{timedelta} object (see \method{utcoffset()} for details). Note that DST offset, if applicable, has Index: tzinfo-examples.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/tzinfo-examples.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** tzinfo-examples.py 23 Dec 2002 18:52:19 -0000 1.1 --- tzinfo-examples.py 2 Jan 2003 21:28:07 -0000 1.2 *************** *** 1,3 **** ! from datetime import tzinfo class UTC(tzinfo): --- 1,5 ---- ! from datetime import tzinfo, timedelta ! ! ZERO = timedelta(0) class UTC(tzinfo): *************** *** 5,9 **** def utcoffset(self, dt): ! return 0 def tzname(self, dt): --- 7,11 ---- def utcoffset(self, dt): ! return ZERO def tzname(self, dt): *************** *** 11,15 **** def dst(self, dt): ! return 0 class FixedOffset(tzinfo): --- 13,17 ---- def dst(self, dt): ! return ZERO class FixedOffset(tzinfo): *************** *** 27,32 **** def dst(self, dt): ! # It depends on more than we know in an example. ! return None # Indicate we don't know import time --- 29,33 ---- def dst(self, dt): ! return ZERO import time *************** *** 44,50 **** def utcoffset(self, dt): if self._isdst(dt): ! return -time.timezone/60 else: ! return -time.altzone/60 def tzname(self, dt): --- 45,51 ---- def utcoffset(self, dt): if self._isdst(dt): ! return timedelta(seconds=-time.timezone) else: ! return timedelta(seconds=-time.altzone) def tzname(self, dt): From tim_one@users.sourceforge.net Thu Jan 2 21:28:09 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:28:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.20,1.21 Message-ID: <E18UCsr-0004uO-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv18654/python/Lib/test Modified Files: test_datetime.py Log Message: The tzinfo methods utcoffset() and dst() must return a timedelta object (or None) now. In 2.3a1 they could also return an int or long, but that was an unhelpfully redundant leftover from an earlier version wherein they couldn't return a timedelta. TOOWTDI. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** test_datetime.py 2 Jan 2003 19:35:53 -0000 1.20 --- test_datetime.py 2 Jan 2003 21:28:07 -0000 1.21 *************** *** 27,30 **** --- 27,34 ---- class FixedOffset(tzinfo): def __init__(self, offset, name, dstoffset=42): + if isinstance(offset, int): + offset = timedelta(minutes=offset) + if isinstance(dstoffset, int): + dstoffset = timedelta(minutes=dstoffset) self.__offset = offset self.__name = name *************** *** 73,79 **** self.failUnless(isinstance(fo, tzinfo)) for dt in datetime.now(), None: ! self.assertEqual(fo.utcoffset(dt), 3) self.assertEqual(fo.tzname(dt), "Three") ! self.assertEqual(fo.dst(dt), 42) def test_pickling_base(self): --- 77,83 ---- self.failUnless(isinstance(fo, tzinfo)) for dt in datetime.now(), None: ! self.assertEqual(fo.utcoffset(dt), timedelta(minutes=3)) self.assertEqual(fo.tzname(dt), "Three") ! self.assertEqual(fo.dst(dt), timedelta(minutes=42)) def test_pickling_base(self): *************** *** 95,102 **** # Make sure we can pickle/unpickle an instance of a subclass. ! orig = PicklableFixedOffset(-300, 'cookie') self.failUnless(isinstance(orig, tzinfo)) self.failUnless(type(orig) is PicklableFixedOffset) ! self.assertEqual(orig.utcoffset(None), -300) self.assertEqual(orig.tzname(None), 'cookie') for pickler in pickle, cPickle: --- 99,107 ---- # Make sure we can pickle/unpickle an instance of a subclass. ! offset = timedelta(minutes=-300) ! orig = PicklableFixedOffset(offset, 'cookie') self.failUnless(isinstance(orig, tzinfo)) self.failUnless(type(orig) is PicklableFixedOffset) ! self.assertEqual(orig.utcoffset(None), offset) self.assertEqual(orig.tzname(None), 'cookie') for pickler in pickle, cPickle: *************** *** 106,110 **** self.failUnless(isinstance(derived, tzinfo)) self.failUnless(type(derived) is PicklableFixedOffset) ! self.assertEqual(derived.utcoffset(None), -300) self.assertEqual(derived.tzname(None), 'cookie') --- 111,115 ---- self.failUnless(isinstance(derived, tzinfo)) self.failUnless(type(derived) is PicklableFixedOffset) ! self.assertEqual(derived.utcoffset(None), offset) self.assertEqual(derived.tzname(None), 'cookie') *************** *** 1563,1567 **** class introspective(tzinfo): def tzname(self, dt): return dt and "real" or "none" ! def utcoffset(self, dt): return dt and 42 or -42 dst = utcoffset --- 1568,1573 ---- class introspective(tzinfo): def tzname(self, dt): return dt and "real" or "none" ! def utcoffset(self, dt): ! return timedelta(minutes = dt and 42 or -42) dst = utcoffset *************** *** 1594,1598 **** class Edgy(tzinfo): def __init__(self, offset): ! self.offset = offset def utcoffset(self, dt): return self.offset --- 1600,1604 ---- class Edgy(tzinfo): def __init__(self, offset): ! self.offset = timedelta(minutes=offset) def utcoffset(self, dt): return self.offset *************** *** 1630,1650 **** self.failUnless(t.tzname() is None) - class C2(tzinfo): - def utcoffset(self, dt): return -1439 - def dst(self, dt): return 1439 - def tzname(self, dt): return "aname" class C3(tzinfo): def utcoffset(self, dt): return timedelta(minutes=-1439) def dst(self, dt): return timedelta(minutes=1439) def tzname(self, dt): return "aname" ! for t in cls(1, 1, 1, tzinfo=C2()), cls(1, 1, 1, tzinfo=C3()): ! self.assertEqual(t.utcoffset(), timedelta(minutes=-1439)) ! self.assertEqual(t.dst(), timedelta(minutes=1439)) ! self.assertEqual(t.tzname(), "aname") # Wrong types. class C4(tzinfo): def utcoffset(self, dt): return "aname" ! def dst(self, dt): return () def tzname(self, dt): return 0 t = cls(1, 1, 1, tzinfo=C4()) --- 1636,1652 ---- self.failUnless(t.tzname() is None) class C3(tzinfo): def utcoffset(self, dt): return timedelta(minutes=-1439) def dst(self, dt): return timedelta(minutes=1439) def tzname(self, dt): return "aname" ! t = cls(1, 1, 1, tzinfo=C3()) ! self.assertEqual(t.utcoffset(), timedelta(minutes=-1439)) ! self.assertEqual(t.dst(), timedelta(minutes=1439)) ! self.assertEqual(t.tzname(), "aname") # Wrong types. class C4(tzinfo): def utcoffset(self, dt): return "aname" ! def dst(self, dt): return 7 def tzname(self, dt): return 0 t = cls(1, 1, 1, tzinfo=C4()) *************** *** 1654,1666 **** # Offset out of range. - class C5(tzinfo): - def utcoffset(self, dt): return -1440 - def dst(self, dt): return 1440 class C6(tzinfo): def utcoffset(self, dt): return timedelta(hours=-24) def dst(self, dt): return timedelta(hours=24) ! for t in cls(1, 1, 1, tzinfo=C5()), cls(1, 1, 1, tzinfo=C6()): ! self.assertRaises(ValueError, t.utcoffset) ! self.assertRaises(ValueError, t.dst) # Not a whole number of minutes. --- 1656,1665 ---- # Offset out of range. class C6(tzinfo): def utcoffset(self, dt): return timedelta(hours=-24) def dst(self, dt): return timedelta(hours=24) ! t = cls(1, 1, 1, tzinfo=C6()) ! self.assertRaises(ValueError, t.utcoffset) ! self.assertRaises(ValueError, t.dst) # Not a whole number of minutes. *************** *** 1680,1686 **** def utcoffset(self, t): if t.minute < 10: ! return t.minute # d0 and d1 equal after adjustment else: ! return 59 # d2 off in the weeds base = cls(8, 9, 10, tzinfo=OperandDependentOffset()) --- 1679,1687 ---- def utcoffset(self, t): if t.minute < 10: ! # d0 and d1 equal after adjustment ! return timedelta(minutes=t.minute) else: ! # d2 off in the weeds ! return timedelta(minutes=59) base = cls(8, 9, 10, tzinfo=OperandDependentOffset()) *************** *** 1938,1944 **** class Varies(tzinfo): def __init__(self): ! self.offset = 22 def utcoffset(self, t): ! self.offset += 1 return self.offset --- 1939,1945 ---- class Varies(tzinfo): def __init__(self): ! self.offset = timedelta(minutes=22) def utcoffset(self, t): ! self.offset += timedelta(minutes=1) return self.offset *************** *** 2029,2033 **** # Try a bogus uctoffset. class Bogus(tzinfo): ! def utcoffset(self, dt): return 1440 # out of bounds t1 = self.theclass(2, 2, 2, tzinfo=Bogus()) t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, "")) --- 2030,2035 ---- # Try a bogus uctoffset. class Bogus(tzinfo): ! def utcoffset(self, dt): ! return timedelta(minutes=1440) # out of bounds t1 = self.theclass(2, 2, 2, tzinfo=Bogus()) t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, "")) *************** *** 2260,2263 **** --- 2262,2267 ---- class DST(tzinfo): def __init__(self, dstvalue): + if isinstance(dstvalue, int): + dstvalue = timedelta(minutes=dstvalue) self.dstvalue = dstvalue def dst(self, dt): *************** *** 2292,2295 **** --- 2296,2301 ---- class DST(tzinfo): def __init__(self, dstvalue): + if isinstance(dstvalue, int): + dstvalue = timedelta(minutes=dstvalue) self.dstvalue = dstvalue def dst(self, dt): *************** *** 2304,2308 **** def __init__(self, uofs, dofs=None): DST.__init__(self, dofs) ! self.uofs = uofs def utcoffset(self, dt): return self.uofs --- 2310,2314 ---- def __init__(self, uofs, dofs=None): DST.__init__(self, dofs) ! self.uofs = timedelta(minutes=uofs) def utcoffset(self, dt): return self.uofs *************** *** 2455,2461 **** def utcoffset(self, t): if t.minute < 10: ! return t.minute # d0 and d1 equal after adjustment else: ! return 59 # d2 off in the weeds base = cls(8, 9, 10, 11, 12, 13, 14, tzinfo=OperandDependentOffset()) --- 2461,2469 ---- def utcoffset(self, t): if t.minute < 10: ! # d0 and d1 equal after adjustment ! return timedelta(minutes=t.minute) else: ! # d2 off in the weeds ! return timedelta(minutes=59) base = cls(8, 9, 10, 11, 12, 13, 14, tzinfo=OperandDependentOffset()) *************** *** 2503,2509 **** class Varies(tzinfo): def __init__(self): ! self.offset = 22 def utcoffset(self, t): ! self.offset += 1 return self.offset --- 2511,2517 ---- class Varies(tzinfo): def __init__(self): ! self.offset = timedelta(minutes=22) def utcoffset(self, t): ! self.offset += timedelta(minutes=1) return self.offset From tim_one@users.sourceforge.net Thu Jan 2 21:28:10 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:28:10 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.27,1.28 Message-ID: <E18UCss-0004ud-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv18654/python/Modules Modified Files: datetimemodule.c Log Message: The tzinfo methods utcoffset() and dst() must return a timedelta object (or None) now. In 2.3a1 they could also return an int or long, but that was an unhelpfully redundant leftover from an earlier version wherein they couldn't return a timedelta. TOOWTDI. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** datetimemodule.c 2 Jan 2003 19:35:54 -0000 1.27 --- datetimemodule.c 2 Jan 2003 21:28:08 -0000 1.28 *************** *** 630,638 **** * result. tzinfo must be an instance of the tzinfo class. If the method * returns None, this returns 0 and sets *none to 1. If the method doesn't ! * return a Python int or long or timedelta, TypeError is raised and this ! * returns -1. If it returns an int or long, but is outside the valid ! * range for a UTC minute offset, or it returns a timedelta and the value is ! * out of range or isn't a whole number of minutes, ValueError is raised and ! * this returns -1. * Else *none is set to 0 and the integer method result is returned. */ --- 630,636 ---- * result. tzinfo must be an instance of the tzinfo class. If the method * returns None, this returns 0 and sets *none to 1. If the method doesn't ! * return None or timedelta, TypeError is raised and this returns -1. If it ! * returnsa timedelta and the value is out of range or isn't a whole number ! * of minutes, ValueError is raised and this returns -1. * Else *none is set to 0 and the integer method result is returned. */ *************** *** 642,646 **** { PyObject *u; ! long result = -1; /* Py{Int,Long}_AsLong return long */ assert(tzinfo != NULL); --- 640,644 ---- { PyObject *u; ! int result = -1; assert(tzinfo != NULL); *************** *** 657,666 **** *none = 1; } - else if (PyInt_Check(u)) - result = PyInt_AS_LONG(u); - - else if (PyLong_Check(u)) - result = PyLong_AsLong(u); - else if (PyDelta_Check(u)) { const int days = GET_TD_DAYS(u); --- 655,658 ---- *************** *** 684,688 **** else { PyErr_Format(PyExc_TypeError, ! "tzinfo.%s() must return None, integer or " "timedelta, not '%s'", name, u->ob_type->tp_name); --- 676,680 ---- else { PyErr_Format(PyExc_TypeError, ! "tzinfo.%s() must return None or " "timedelta, not '%s'", name, u->ob_type->tp_name); *************** *** 697,701 **** result = -1; } ! return (int)result; } --- 689,693 ---- result = -1; } ! return result; } *************** *** 703,710 **** * result. tzinfo must be an instance of the tzinfo class. If utcoffset() * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset() ! & doesn't return a Python int or long, TypeError is raised and this ! * returns -1. If utcoffset() returns an int outside the legitimate range ! * for a UTC offset, ValueError is raised and this returns -1. Else ! * *none is set to 0 and the offset is returned. */ static int --- 695,702 ---- * result. tzinfo must be an instance of the tzinfo class. If utcoffset() * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset() ! * doesn't return None or timedelta, TypeError is raised and this returns -1. ! * If utcoffset() returns an invalid timedelta (out of range, or not a whole ! * # of minutes), ValueError is raised and this returns -1. Else *none is ! * set to 0 and the offset is returned (as int # of minutes east of UTC). */ static int *************** *** 746,753 **** * result. tzinfo must be an instance of the tzinfo class. If dst() * returns None, call_dst returns 0 and sets *none to 1. If dst() ! & doesn't return a Python int or long, TypeError is raised and this ! * returns -1. If dst() returns an int outside the legitimate range ! * for a UTC offset, ValueError is raised and this returns -1. Else ! * *none is set to 0 and the offset is returned. */ static int --- 738,745 ---- * result. tzinfo must be an instance of the tzinfo class. If dst() * returns None, call_dst returns 0 and sets *none to 1. If dst() ! & doesn't return None or timedelta, TypeError is raised and this ! * returns -1. If dst() returns an invalid timedelta for for a UTC offset, ! * ValueError is raised and this returns -1. Else *none is set to 0 and ! * the offset is returned (as an int # of minutes east of UTC). */ static int From akuchling@users.sourceforge.net Thu Jan 2 21:33:17 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 02 Jan 2003 13:33:17 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.96,1.97 Message-ID: <E18UCxp-0005Xy-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv21287 Modified Files: whatsnew23.tex Log Message: Fix PEP 302 description; bump version number Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -d -r1.96 -r1.97 *** whatsnew23.tex 2 Jan 2003 13:42:32 -0000 1.96 --- whatsnew23.tex 2 Jan 2003 21:33:15 -0000 1.97 *************** *** 3,7 **** \title{What's New in Python 2.3} ! \release{0.06} \author{A.M. Kuchling} \authoraddress{\email{amk@amk.ca}} --- 3,7 ---- \title{What's New in Python 2.3} ! \release{0.07} \author{A.M. Kuchling} \authoraddress{\email{amk@amk.ca}} *************** *** 718,724 **** \begin{itemize} ! \item \code{sys.path_hooks} is a list of functions. Each function ! takes a string containing a path and returns either \code{None} or an ! importer object that will handle imports from this path. \item \code{sys.path_importer_cache} caches importer objects for --- 718,726 ---- \begin{itemize} ! \item \code{sys.path_hooks} is a list of callable objects; most ! often they'll be classes. Each callable takes a string containing ! a path and either returns an importer object that will handle imports ! from this path or raises an \exception{ImportError} exception if it ! can't handle this path. \item \code{sys.path_importer_cache} caches importer objects for *************** *** 748,756 **** loader = mp(fullname) if loader is not None: ! <module> = loader(fullname) for path in sys.path: for hook in sys.path_hooks: ! importer = hook(path) if importer is not None: loader = importer.find_module(fullname) --- 750,763 ---- loader = mp(fullname) if loader is not None: ! <module> = loader.load_module(fullname) for path in sys.path: for hook in sys.path_hooks: ! try: ! importer = hook(path) ! except ImportError: ! # ImportError, so try the other path hooks ! pass ! else: if importer is not None: loader = importer.find_module(fullname) *************** *** 2015,2022 **** suggestions, corrections and assistance with various drafts of this article: Simon Brunning, Michael Chermside, Scott David Daniels, ! Fred~L. Drake, Jr., Kelly Gerber, Raymond Hettinger, Michael Hudson, Detlef Lannert, ! Martin von L\"owis, Andrew MacIntyre, Lalo Martins, Gustavo Niemeyer, ! Neal Norwitz, Chris Reedy, Vinay Sajip, Neil Schemenauer, Jason ! Tishler. \end{document} --- 2022,2029 ---- suggestions, corrections and assistance with various drafts of this article: Simon Brunning, Michael Chermside, Scott David Daniels, ! Fred~L. Drake, Jr., Kelly Gerber, Raymond Hettinger, Michael Hudson, ! Detlef Lannert, Martin von L\"owis, Andrew MacIntyre, Lalo Martins, ! Gustavo Niemeyer, Neal Norwitz, Hans Nowak, Chris Reedy, Vinay Sajip, ! Neil Schemenauer, Jason Tishler, Just van~Rossum. \end{document} From rhettinger@users.sourceforge.net Thu Jan 2 22:08:50 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 02 Jan 2003 14:08:50 -0800 Subject: [Python-checkins] python/dist/src/Objects stringobject.c,2.147.6.11,2.147.6.12 unicodeobject.c,2.124.6.18,2.124.6.19 Message-ID: <E18UDWE-0000yg-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv3455/Objects Modified Files: Tag: release22-maint stringobject.c unicodeobject.c Log Message: Backport MAL's patch for bug #659709: bogus computation of float length Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.147.6.11 retrieving revision 2.147.6.12 diff -C2 -d -r2.147.6.11 -r2.147.6.12 *** stringobject.c 11 Oct 2002 00:47:19 -0000 2.147.6.11 --- stringobject.c 2 Jan 2003 22:08:34 -0000 2.147.6.12 *************** *** 3060,3078 **** if (type == 'f' && fabs(x)/1e25 >= 1e25) type = 'g'; ! PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", ! (flags&F_ALT) ? "#" : "", ! prec, type); ! /* worst case length calc to ensure no buffer overrun: fmt = %#.<prec>g buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp for any double rep.) len = 1 + prec + 1 + 2 + 5 = 9 + prec If prec=0 the effective precision is 1 (the leading digit is ! always given), therefore increase by one to 10+prec. */ ! if (buflen <= (size_t)10 + (size_t)prec) { PyErr_SetString(PyExc_OverflowError, "formatted float is too long (precision too large?)"); return -1; } PyOS_snprintf(buf, buflen, fmt, x); return strlen(buf); --- 3060,3088 ---- if (type == 'f' && fabs(x)/1e25 >= 1e25) type = 'g'; ! /* Worst case length calc to ensure no buffer overrun: ! ! 'g' formats: fmt = %#.<prec>g buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp for any double rep.) len = 1 + prec + 1 + 2 + 5 = 9 + prec + + 'f' formats: + buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) + len = 1 + 50 + 1 + prec = 52 + prec + If prec=0 the effective precision is 1 (the leading digit is ! always given), therefore increase the length by one. ! ! */ ! if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) || ! (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { PyErr_SetString(PyExc_OverflowError, "formatted float is too long (precision too large?)"); return -1; } + PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", + (flags&F_ALT) ? "#" : "", + prec, type); PyOS_snprintf(buf, buflen, fmt, x); return strlen(buf); Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.124.6.18 retrieving revision 2.124.6.19 diff -C2 -d -r2.124.6.18 -r2.124.6.19 *** unicodeobject.c 7 Nov 2002 00:22:53 -0000 2.124.6.18 --- unicodeobject.c 2 Jan 2003 22:08:39 -0000 2.124.6.19 *************** *** 5251,5268 **** if (type == 'f' && (fabs(x) / 1e25) >= 1e25) type = 'g'; ! PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", ! (flags & F_ALT) ? "#" : "", prec, type); ! /* worst case length calc to ensure no buffer overrun: ! fmt = %#.<prec>g ! buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp ! for any double rep.) ! len = 1 + prec + 1 + 2 + 5 = 9 + prec If prec=0 the effective precision is 1 (the leading digit is ! always given), therefore increase by one to 10+prec. */ ! if (buflen <= (size_t)10 + (size_t)prec) { PyErr_SetString(PyExc_OverflowError, ! "formatted float is too long (precision too long?)"); return -1; } return usprintf(buf, fmt, x); } --- 5251,5279 ---- if (type == 'f' && (fabs(x) / 1e25) >= 1e25) type = 'g'; ! /* Worst case length calc to ensure no buffer overrun: ! ! 'g' formats: ! fmt = %#.<prec>g ! buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp ! for any double rep.) ! len = 1 + prec + 1 + 2 + 5 = 9 + prec ! ! 'f' formats: ! buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) ! len = 1 + 50 + 1 + prec = 52 + prec ! If prec=0 the effective precision is 1 (the leading digit is ! always given), therefore increase the length by one. ! ! */ ! if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) || ! (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { PyErr_SetString(PyExc_OverflowError, ! "formatted float is too long (precision too large?)"); return -1; } + PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", + (flags&F_ALT) ? "#" : "", + prec, type); return usprintf(buf, fmt, x); } From rhettinger@users.sourceforge.net Thu Jan 2 22:09:08 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 02 Jan 2003 14:09:08 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_string.py,1.15.6.2,1.15.6.3 Message-ID: <E18UDWW-0000xp-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv3455/Lib/test Modified Files: Tag: release22-maint test_string.py Log Message: Backport MAL's patch for bug #659709: bogus computation of float length Index: test_string.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_string.py,v retrieving revision 1.15.6.2 retrieving revision 1.15.6.3 diff -C2 -d -r1.15.6.2 -r1.15.6.3 *** test_string.py 7 Oct 2002 01:18:17 -0000 1.15.6.2 --- test_string.py 2 Jan 2003 22:08:32 -0000 1.15.6.3 *************** *** 56,57 **** --- 56,83 ---- string.lowercase string.uppercase + + # Float formatting + for prec in range(100): + formatstring = u'%%.%if' % prec + value = 0.01 + for x in range(60): + value = value * 3.141592655 / 3.0 * 10.0 + #print 'Overflow check for x=%i and prec=%i:' % \ + # (x, prec), + try: + result = formatstring % value + except OverflowError: + # The formatfloat() code in stringobject.c and + # unicodeobject.c uses a 120 byte buffer and switches from + # 'f' formatting to 'g' at precision 50, so we expect + # OverflowErrors for the ranges x < 50 and prec >= 67. + if x >= 50 or \ + prec < 67: + print '*** unexpected OverflowError for x=%i and prec=%i' % (x, prec) + else: + #print 'OverflowError' + pass + else: + #print result + pass + From gvanrossum@users.sourceforge.net Thu Jan 2 22:20:58 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 02 Jan 2003 14:20:58 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime PSF.py,1.1,1.2 Message-ID: <E18UDhy-0002IJ-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv8802 Modified Files: PSF.py Log Message: Whitespace normalization. :-) Index: PSF.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/PSF.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PSF.py 28 Dec 2002 18:16:46 -0000 1.1 --- PSF.py 2 Jan 2003 22:20:52 -0000 1.2 *************** *** 65,67 **** if __name__ == '__main__': ! main() \ No newline at end of file --- 65,67 ---- if __name__ == '__main__': ! main() From bwarsaw@users.sourceforge.net Thu Jan 2 22:48:39 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Thu, 02 Jan 2003 14:48:39 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.28,1.29 Message-ID: <E18UE8l-0004z5-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv19139 Modified Files: test_email.py Log Message: Jack complained that on test_crlf_separation() was failing on MacOS9 because the test file, msg_26.txt which has \r\n line endings, was getting munged by cvs, which knows to do line ending conversions for text files. But we want \r\n to be preserved on all platforms, so we cvs admin'd the file to be -kb (binary), which means we have to open the file in binary mode to preserve these line ends. Hopefully this will be the end of the thrashing on this issue (but probably not). Test passes on *nix now, and Tim confirms it passes on Windows. We'll leave it to Jack to test MacOS. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** test_email.py 30 Dec 2002 19:14:38 -0000 1.28 --- test_email.py 2 Jan 2003 22:48:36 -0000 1.29 *************** *** 1,3 **** ! # Copyright (C) 2001,2002 Python Software Foundation # email package unit tests --- 1,3 ---- ! # Copyright (C) 2001,2002,2003 Python Software Foundation # email package unit tests *************** *** 51,57 **** ! def openfile(filename): path = os.path.join(os.path.dirname(landmark), 'data', filename) ! return open(path, 'r') --- 51,57 ---- ! def openfile(filename, mode='r'): path = os.path.join(os.path.dirname(landmark), 'data', filename) ! return open(path, mode) *************** *** 1884,1888 **** def test_crlf_separation(self): eq = self.assertEqual ! fp = openfile('msg_26.txt') try: msg = Parser().parse(fp) --- 1884,1888 ---- def test_crlf_separation(self): eq = self.assertEqual ! fp = openfile('msg_26.txt', mode='rb') try: msg = Parser().parse(fp) From jackjansen@users.sourceforge.net Thu Jan 2 23:07:50 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 15:07:50 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules macmodule.c,1.53,1.53.2.1 Message-ID: <E18UERK-0006mD-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv26030 Modified Files: Tag: r23a1-branch macmodule.c Log Message: Made fdopen() signature the same as for posixmodule. Index: macmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macmodule.c,v retrieving revision 1.53 retrieving revision 1.53.2.1 diff -C2 -d -r1.53 -r1.53.2.1 *** macmodule.c 12 Dec 2002 10:31:49 -0000 1.53 --- macmodule.c 2 Jan 2003 23:07:46 -0000 1.53.2.1 *************** *** 219,225 **** extern int fclose(FILE *); int fd; ! char *mode; FILE *fp; ! if (!PyArg_ParseTuple(args, "is", &fd, &mode)) return NULL; Py_BEGIN_ALLOW_THREADS --- 219,227 ---- extern int fclose(FILE *); int fd; ! char *mode = "r"; ! int bufsize = -1; FILE *fp; ! PyObject *f; ! if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize)) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 228,232 **** if (fp == NULL) return mac_error(); ! return PyFile_FromFile(fp, "(fdopen)", mode, fclose); } #endif --- 230,237 ---- if (fp == NULL) return mac_error(); ! f = PyFile_FromFile(fp, "<fdopen>", mode, fclose); ! if (f != NULL) ! PyFile_SetBufSize(f, bufsize); ! return f; } #endif From jackjansen@users.sourceforge.net Thu Jan 2 23:08:40 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 15:08:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_tempfile.py,1.12,1.12.2.1 Message-ID: <E18UES8-0006q6-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv26281 Modified Files: Tag: r23a1-branch test_tempfile.py Log Message: Added the Mac to platforms that don't have user/group/other modes. Set the limit for the number of open files to 32 if platform==mac. Index: test_tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_tempfile.py,v retrieving revision 1.12 retrieving revision 1.12.2.1 diff -C2 -d -r1.12 -r1.12.2.1 *** test_tempfile.py 22 Nov 2002 20:13:43 -0000 1.12 --- test_tempfile.py 2 Jan 2003 23:08:37 -0000 1.12.2.1 *************** *** 26,30 **** # TEST_FILES may need to be tweaked for systems depending on the maximum # number of files that can be opened at one time (see ulimit -n) ! TEST_FILES = 100 # This is organized as one test for each chunk of code in tempfile.py, --- 26,33 ---- # TEST_FILES may need to be tweaked for systems depending on the maximum # number of files that can be opened at one time (see ulimit -n) ! if sys.platform == 'mac': ! TEST_FILES = 32 ! else: ! TEST_FILES = 100 # This is organized as one test for each chunk of code in tempfile.py, *************** *** 259,263 **** mode = stat.S_IMODE(os.stat(file.name).st_mode) expected = 0600 ! if sys.platform in ('win32', 'os2emx'): # There's no distinction among 'user', 'group' and 'world'; # replicate the 'user' bits. --- 262,266 ---- mode = stat.S_IMODE(os.stat(file.name).st_mode) expected = 0600 ! if sys.platform in ('win32', 'os2emx', 'mac'): # There's no distinction among 'user', 'group' and 'world'; # replicate the 'user' bits. *************** *** 464,468 **** mode = stat.S_IMODE(os.stat(dir).st_mode) expected = 0700 ! if sys.platform in ('win32', 'os2emx'): # There's no distinction among 'user', 'group' and 'world'; # replicate the 'user' bits. --- 467,471 ---- mode = stat.S_IMODE(os.stat(dir).st_mode) expected = 0700 ! if sys.platform in ('win32', 'os2emx', 'mac'): # There's no distinction among 'user', 'group' and 'world'; # replicate the 'user' bits. From gvanrossum@users.sourceforge.net Thu Jan 2 23:11:04 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 02 Jan 2003 15:11:04 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime Local.py,NONE,1.1 Message-ID: <E18UEUS-00073N-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv27103 Added Files: Local.py Log Message: A really naive tzinfo class that tries to implement the notion of "local time according to the time module". --- NEW FILE: Local.py --- """A tzinfo object mirroring local time.""" import time as _time from datetime import date, time, timedelta, datetime, datetimetz, tzinfo STDOFFSET = timedelta(seconds = -_time.timezone) if _time.daylight: DSTOFFSET = timedelta(seconds = -_time.altzone) else: DSTOFFSET = STDOFFSET ZERO = timedelta() DSTDIFF = DSTOFFSET - STDOFFSET class LocalTimezone(tzinfo): def utcoffset(self, dt): if self._isdst(dt): return DSTOFFSET else: return STDOFFSET def dst(self, dt): if self._isdst(dt): return DSTDIFF else: return ZERO def tzname(self, dt): return _time.tzname[self._isdst(dt)] def _isdst(self, dt): tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1) stamp = _time.mktime(tt) tt = _time.localtime(stamp) return tt[8] > 0 Local = LocalTimezone() demo = """ *** This test only works in US/Eastern *** Pick a time in standard time. >>> dt = datetimetz(2003, 1, 2, 18, 05, 49) >>> dt.isoformat() '2003-01-02T18:05:49' >>> dt = dt.replace(tzinfo=Local) >>> dt.isoformat() '2003-01-02T18:05:49-05:00' Pick a time in DST. >>> dt = datetimetz(2003, 7, 2, 18, 05, 49) >>> dt.isoformat() '2003-07-02T18:05:49' >>> dt = dt.replace(tzinfo=Local) >>> dt.isoformat() '2003-07-02T18:05:49-04:00' """ __test__ = {'demo': demo} def _test(): import doctest, Local return doctest.testmod(Local) if __name__ == "__main__": _test() From jackjansen@users.sourceforge.net Thu Jan 2 23:09:38 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 02 Jan 2003 15:09:38 -0800 Subject: [Python-checkins] python/dist/src/Mac ReadMe,1.45,1.45.2.1 Message-ID: <E18UET4-0006vB-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Mac In directory sc8-pr-cvs1:/tmp/cvs-serv26587 Modified Files: Tag: r23a1-branch ReadMe Log Message: Added notes for failing tests. Most of these failures have been added to the sf bug manager, socket I'll have to look in to myself. Index: ReadMe =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/ReadMe,v retrieving revision 1.45 retrieving revision 1.45.2.1 diff -C2 -d -r1.45 -r1.45.2.1 *** ReadMe 19 Aug 2002 13:17:39 -0000 1.45 --- ReadMe 2 Jan 2003 23:09:35 -0000 1.45.2.1 *************** *** 84,87 **** --- 84,99 ---- frozen modules. This should not be a problem in normal use. + test_email fails with "AssertionError: 2042 != 2". This will be fixed in + the next release. + + test_httplib fails with an unexpected output error. This will be fixed in + the next release. + + test_pep263 crashes with a syntax error. This will be fixed in the next release. + + test_socket fails, this problem is being investigated. + + test_strptime fails, this problem is being investigated. + Three tests will fail on MacOS9 with MemoryErrors: test_longexp, test_sha and test_zlib (on MacOSX these should pass). From akuchling@users.sourceforge.net Thu Jan 2 23:50:20 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 02 Jan 2003 15:50:20 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.97,1.98 Message-ID: <E18UF6S-0001x1-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv7459 Modified Files: whatsnew23.tex Log Message: Fix error in previous correction; thanks, Just! Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -d -r1.97 -r1.98 *** whatsnew23.tex 2 Jan 2003 21:33:15 -0000 1.97 --- whatsnew23.tex 2 Jan 2003 23:50:18 -0000 1.98 *************** *** 760,764 **** pass else: - if importer is not None: loader = importer.find_module(fullname) <module> = loader.load_module(fullname) --- 760,763 ---- From goodger@users.sourceforge.net Fri Jan 3 03:30:00 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu, 02 Jan 2003 19:30:00 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS.help,1.3,1.4 Message-ID: <E18UIX2-0007fE-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29445 Modified Files: NEWS.help Log Message: Updated (2.3 OK now) Index: NEWS.help =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS.help,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NEWS.help 31 Dec 2002 17:51:30 -0000 1.3 --- NEWS.help 3 Jan 2003 03:29:58 -0000 1.4 *************** *** 12,22 **** http://docutils.sf.net/docutils-snapshot.tgz ! Unfortunately, docutils doesn't work with Python 2.3 yet; you need ! Python 2.2.2 (or perhaps an older version). ! To process NEWS into NEWS.html, first install docutils for Python 2.2, ! and then run this command: ! python2.2 .../docutils/tools/html.py NEWS >NEWS.html Here ".../docutils" is the directory into which the above snapshot was --- 12,21 ---- http://docutils.sf.net/docutils-snapshot.tgz ! Docutils works with Python 2.1 or newer (including 2.3). ! To process NEWS into NEWS.html, first install Docutils, and then run ! this command: ! python .../docutils/tools/html.py NEWS >NEWS.html Here ".../docutils" is the directory into which the above snapshot was *************** *** 33,37 **** ================================= ! *XXX Release date: DD-MMM-2002 XXX* * Subsections are underlined with a single row of hyphens: --- 32,39 ---- ================================= ! *Release date: DD-MMM-2002* ! ! Note that the release date line is emphasized, with a "*" at each ! end. * Subsections are underlined with a single row of hyphens: From goodger@users.sourceforge.net Fri Jan 3 03:30:23 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu, 02 Jan 2003 19:30:23 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.593,1.594 Message-ID: <E18UIXP-0007hn-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29613 Modified Files: NEWS Log Message: Fixed markup. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.593 retrieving revision 1.594 diff -C2 -d -r1.593 -r1.594 *** NEWS 2 Jan 2003 21:28:07 -0000 1.593 --- NEWS 3 Jan 2003 03:30:21 -0000 1.594 *************** *** 8,12 **** ================================= ! *Release date: XX-XXX-2003 Core and builtins --- 8,12 ---- ================================= ! *Release date: XX-XXX-2003* Core and builtins *************** *** 39,45 **** --- 39,49 ---- ------- + TBD + Tools/Demos ----------- + TBD + Build ----- *************** *** 66,75 **** --- 70,85 ---- ----- + TBD + New platforms ------------- + TBD + Tests ----- + TBD + Windows ------- *************** *** 81,84 **** --- 91,96 ---- --- + TBD + What's New in Python 2.3 alpha 1? *************** *** 99,103 **** - int() now returns a long object if the argument is outside the ! integer range, so int("4"*1000), int(1e200) and int(1L<<1000) will all return long objects instead of raising an OverflowError. --- 111,115 ---- - int() now returns a long object if the argument is outside the ! integer range, so int("4" * 1000), int(1e200) and int(1L<<1000) will all return long objects instead of raising an OverflowError. *************** *** 802,808 **** honored, and so unicode conversion error handling can be specified. ! - distutils' build_ext command now links c++ extensions with the c++ compiler available in the Makefile or CXX environment variable, if ! running under *nix. - New module bz2: provides a comprehensive interface for the bz2 compression --- 814,820 ---- honored, and so unicode conversion error handling can be specified. ! - distutils' build_ext command now links C++ extensions with the C++ compiler available in the Makefile or CXX environment variable, if ! running under \*nix. - New module bz2: provides a comprehensive interface for the bz2 compression *************** *** 810,814 **** functions, and types for sequential (de)compression. ! - New pdb command `pp' which is like `p' except that it pretty-prints the value of its expression argument. --- 822,826 ---- functions, and types for sequential (de)compression. ! - New pdb command 'pp' which is like 'p' except that it pretty-prints the value of its expression argument. *************** *** 1937,1943 **** Tool to a standard library package. (Tools/compiler still exists as a sample driver.) - - Tools - ----- Build --- 1949,1952 ---- From goodger@users.sourceforge.net Fri Jan 3 04:06:28 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu, 02 Jan 2003 20:06:28 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/parsers/rst states.py,1.3,1.4 Message-ID: <E18UJ6K-0002VD-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils/parsers/rst In directory sc8-pr-cvs1:/tmp/cvs-serv9606/parsers/rst Modified Files: states.py Log Message: More Python 2.3 & PyXML compatibility updates Index: states.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/parsers/rst/states.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** states.py 1 Jan 2003 02:35:59 -0000 1.3 --- states.py 3 Jan 2003 04:06:26 -0000 1.4 *************** *** 1911,1915 **** options = utils.extract_extension_options(node, option_spec) except KeyError, detail: ! return 0, ('unknown option: "%s"' % detail) except (ValueError, TypeError), detail: return 0, ('invalid option value: %s' % detail) --- 1911,1915 ---- options = utils.extract_extension_options(node, option_spec) except KeyError, detail: ! return 0, ('unknown option: "%s"' % detail.args[0]) except (ValueError, TypeError), detail: return 0, ('invalid option value: %s' % detail) From goodger@users.sourceforge.net Fri Jan 3 04:06:28 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu, 02 Jan 2003 20:06:28 -0800 Subject: [Python-checkins] python/nondist/peps/docutils nodes.py,1.1,1.2 statemachine.py,1.1,1.2 Message-ID: <E18UJ6K-0002VA-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils In directory sc8-pr-cvs1:/tmp/cvs-serv9606 Modified Files: nodes.py statemachine.py Log Message: More Python 2.3 & PyXML compatibility updates Index: nodes.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/nodes.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** nodes.py 8 Nov 2002 23:47:51 -0000 1.1 --- nodes.py 3 Jan 2003 04:06:26 -0000 1.2 *************** *** 58,63 **** def asdom(self, dom=xml.dom.minidom): ! """Return a DOM representation of this Node.""" ! return self._dom_node(dom) def pformat(self, indent=' ', level=0): --- 58,64 ---- def asdom(self, dom=xml.dom.minidom): ! """Return a DOM **fragment** representation of this Node.""" ! domroot = dom.Document() ! return self._dom_node(domroot) def pformat(self, indent=' ', level=0): *************** *** 181,188 **** return '<%s: %s>' % (self.tagname, data) ! def _dom_node(self, dom): ! return dom.Text(self.data) ! ! def _rooted_dom_node(self, domroot): return domroot.createTextNode(self.data) --- 182,186 ---- return '<%s: %s>' % (self.tagname, data) ! def _dom_node(self, domroot): return domroot.createTextNode(self.data) *************** *** 261,273 **** self.tagname = self.__class__.__name__ ! def _dom_node(self, dom): ! element = dom.Element(self.tagname) ! for attribute, value in self.attributes.items(): ! element.setAttribute(attribute, str(value)) ! for child in self.children: ! element.appendChild(child._dom_node(dom)) ! return element ! ! def _rooted_dom_node(self, domroot): element = domroot.createElement(self.tagname) for attribute, value in self.attributes.items(): --- 259,263 ---- self.tagname = self.__class__.__name__ ! def _dom_node(self, domroot): element = domroot.createElement(self.tagname) for attribute, value in self.attributes.items(): *************** *** 276,280 **** element.setAttribute(attribute, str(value)) for child in self.children: ! element.appendChild(child._rooted_dom_node(domroot)) return element --- 266,270 ---- element.setAttribute(attribute, str(value)) for child in self.children: ! element.appendChild(child._dom_node(domroot)) return element *************** *** 336,340 **** return self.children[key] elif isinstance(key, SliceType): ! assert key.step is None, 'cannot handle slice with stride' return self.children[key.start:key.stop] else: --- 326,330 ---- return self.children[key] elif isinstance(key, SliceType): ! assert key.step in (None, 1), 'cannot handle slice with stride' return self.children[key.start:key.stop] else: *************** *** 349,353 **** self.children[key] = item elif isinstance(key, SliceType): ! assert key.step is None, 'cannot handle slice with stride' for node in item: self.setup_child(node) --- 339,343 ---- self.children[key] = item elif isinstance(key, SliceType): ! assert key.step in (None, 1), 'cannot handle slice with stride' for node in item: self.setup_child(node) *************** *** 363,367 **** del self.children[key] elif isinstance(key, SliceType): ! assert key.step is None, 'cannot handle slice with stride' del self.children[key.start:key.stop] else: --- 353,357 ---- del self.children[key] elif isinstance(key, SliceType): ! assert key.step in (None, 1), 'cannot handle slice with stride' del self.children[key.start:key.stop] else: *************** *** 702,707 **** def asdom(self, dom=xml.dom.minidom): domroot = dom.Document() ! domroot.appendChild(self._rooted_dom_node(domroot)) return domroot --- 692,698 ---- def asdom(self, dom=xml.dom.minidom): + """Return a DOM representation of this document.""" domroot = dom.Document() ! domroot.appendChild(self._dom_node(domroot)) return domroot Index: statemachine.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/statemachine.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** statemachine.py 8 Nov 2002 23:47:51 -0000 1.1 --- statemachine.py 3 Jan 2003 04:06:26 -0000 1.2 *************** *** 111,114 **** --- 111,115 ---- import sys import re + from types import SliceType as _SliceType *************** *** 1105,1124 **** def __len__(self): return len(self.data) def __getitem__(self, i): ! try: ! return self.data[i] ! except TypeError: ! assert i.step is None, 'cannot handle slice with stride' return self.__class__(self.data[i.start:i.stop], items=self.items[i.start:i.stop], parent=self, parent_offset=i.start) def __setitem__(self, i, item): ! try: ! self.data[i] = item ! if self.parent: ! self.parent[i + self.parent_offset] = item ! except TypeError: ! assert i.step is None, 'cannot handle slice with stride' if not isinstance(item, ViewList): raise TypeError('assigning non-ViewList to ViewList slice') --- 1106,1126 ---- def __len__(self): return len(self.data) + # The __getitem__()/__setitem__() methods check whether the index + # is a slice first, since native list objects start supporting + # them directly in Python 2.3 (no exception is raised when + # indexing a list with a slice object; they just work). + def __getitem__(self, i): ! if isinstance(i, _SliceType): ! assert i.step in (None, 1), 'cannot handle slice with stride' return self.__class__(self.data[i.start:i.stop], items=self.items[i.start:i.stop], parent=self, parent_offset=i.start) + else: + return self.data[i] def __setitem__(self, i, item): ! if isinstance(i, _SliceType): ! assert i.step in (None, 1), 'cannot handle slice with stride' if not isinstance(item, ViewList): raise TypeError('assigning non-ViewList to ViewList slice') *************** *** 1129,1132 **** --- 1131,1138 ---- self.parent[i.start + self.parent_offset : i.stop + self.parent_offset] = item + else: + self.data[i] = item + if self.parent: + self.parent[i + self.parent_offset] = item def __delitem__(self, i): From goodger@users.sourceforge.net Fri Jan 3 04:06:28 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu, 02 Jan 2003 20:06:28 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/parsers/rst/languages sv.py,1.2,1.3 Message-ID: <E18UJ6K-0002VJ-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils/parsers/rst/languages In directory sc8-pr-cvs1:/tmp/cvs-serv9606/parsers/rst/languages Modified Files: sv.py Log Message: More Python 2.3 & PyXML compatibility updates Index: sv.py =================================================================== RCS file: /cvsroot/python/python/nondist/peps/docutils/parsers/rst/languages/sv.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** sv.py 17 Nov 2002 00:09:19 -0000 1.2 --- sv.py 3 Jan 2003 04:06:26 -0000 1.3 *************** *** 14,18 **** directives = { u'observera': 'attention', ! u'varning': 'caution', u'fara': 'danger', u'fel': 'error', --- 14,18 ---- directives = { u'observera': 'attention', ! u'caution (translation required)': 'caution', u'fara': 'danger', u'fel': 'error', *************** *** 22,25 **** --- 22,28 ---- u'tips': 'tip', u'varning': 'warning', + u'\u00e4mne': 'topic', + 'line-block (translation required)': 'line-block', + 'parsed-literal (translation required)': 'parsed-literal', # u'fr\u00e5gor': 'questions', # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: *************** *** 30,38 **** u'bild': 'image', u'figur': 'figure', u'r\u00e5': 'raw', # FIXME: Translation might be too literal. u'inneh\u00e5ll': 'contents', # u'fotnoter': 'footnotes', # u'citeringar': 'citations', ! u'\u00e4mne': 'topic'} """Swedish name to registered (in directives/__init__.py) directive name mapping.""" --- 33,46 ---- u'bild': 'image', u'figur': 'figure', + 'include (translation required)': 'include', u'r\u00e5': 'raw', # FIXME: Translation might be too literal. + 'replace (translation required)': 'replace', u'inneh\u00e5ll': 'contents', + 'sectnum (translation required)': 'sectnum', + 'section-numbering (translation required)': 'sectnum', + 'target-notes (translation required)': 'target-notes', # u'fotnoter': 'footnotes', # u'citeringar': 'citations', ! } """Swedish name to registered (in directives/__init__.py) directive name mapping.""" From goodger@users.sourceforge.net Fri Jan 3 04:07:29 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu, 02 Jan 2003 20:07:29 -0800 Subject: [Python-checkins] python/nondist/peps/docutils/parsers/rst/languages fr.py,NONE,1.1 Message-ID: <E18UJ7J-0002al-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/peps/docutils/parsers/rst/languages In directory sc8-pr-cvs1:/tmp/cvs-serv9950/parsers/rst/languages Added Files: fr.py Log Message: update --- NEW FILE: fr.py --- # Author: your name here! # Contact: goodger@users.sourceforge.net # Revision: $Revision: 1.1 $ # Date: $Date: 2003/01/03 04:07:27 $ # Copyright: This module has been placed in the public domain. """ French-language mappings for language-dependent features of reStructuredText. """ __docformat__ = 'reStructuredText' directives = { 'attention (translation required)': 'attention', 'caution (translation required)': 'caution', 'danger (translation required)': 'danger', 'error (translation required)': 'error', 'hint (translation required)': 'hint', 'important (translation required)': 'important', 'note (translation required)': 'note', 'tip (translation required)': 'tip', 'warning (translation required)': 'warning', 'topic (translation required)': 'topic', 'line-block (translation required)': 'line-block', 'parsed-literal (translation required)': 'parsed-literal', #'questions (translation required)': 'questions', #'qa (translation required)': 'questions', #'faq (translation required)': 'questions', 'meta (translation required)': 'meta', #'imagemap (translation required)': 'imagemap', 'image (translation required)': 'image', 'figure (translation required)': 'figure', 'include (translation required)': 'include', 'raw (translation required)': 'raw', 'replace (translation required)': 'replace', 'contents (translation required)': 'contents', 'sectnum (translation required)': 'sectnum', 'section-numbering (translation required)': 'sectnum', 'target-notes (translation required)': 'target-notes', #'footnotes (translation required)': 'footnotes', #'citations (translation required)': 'citations', } """French name to registered (in directives/__init__.py) directive name mapping.""" From rhettinger@users.sourceforge.net Fri Jan 3 08:25:00 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 03 Jan 2003 00:25:00 -0800 Subject: [Python-checkins] python/dist/src/Modules arraymodule.c,2.79,2.80 cStringIO.c,2.38,2.39 operator.c,2.25,2.26 Message-ID: <E18UN8W-0007pe-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv28739 Modified Files: arraymodule.c cStringIO.c operator.c Log Message: SF patch 660559: Use METH_O and METH_NOARGS where possible Simplify code and speed access by using PyArg_UnpackTuple, METH_O and METH_NOARGS in three modules that can benefit from it. Index: arraymodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v retrieving revision 2.79 retrieving revision 2.80 diff -C2 -d -r2.79 -r2.80 *** arraymodule.c 2 Aug 2002 02:27:12 -0000 2.79 --- arraymodule.c 3 Jan 2003 08:24:58 -0000 2.80 *************** *** 801,812 **** static PyObject * ! array_count(arrayobject *self, PyObject *args) { int count = 0; int i; - PyObject *v; - if (!PyArg_ParseTuple(args, "O:count", &v)) - return NULL; for (i = 0; i < self->ob_size; i++) { PyObject *selfi = getarrayitem((PyObject *)self, i); --- 801,809 ---- static PyObject * ! array_count(arrayobject *self, PyObject *v) { int count = 0; int i; for (i = 0; i < self->ob_size; i++) { PyObject *selfi = getarrayitem((PyObject *)self, i); *************** *** 827,837 **** static PyObject * ! array_index(arrayobject *self, PyObject *args) { int i; - PyObject *v; - if (!PyArg_ParseTuple(args, "O:index", &v)) - return NULL; for (i = 0; i < self->ob_size; i++) { PyObject *selfi = getarrayitem((PyObject *)self, i); --- 824,831 ---- static PyObject * ! array_index(arrayobject *self, PyObject *v) { int i; for (i = 0; i < self->ob_size; i++) { PyObject *selfi = getarrayitem((PyObject *)self, i); *************** *** 854,864 **** static PyObject * ! array_remove(arrayobject *self, PyObject *args) { int i; - PyObject *v; - if (!PyArg_ParseTuple(args, "O:remove", &v)) - return NULL; for (i = 0; i < self->ob_size; i++) { PyObject *selfi = getarrayitem((PyObject *)self,i); --- 848,855 ---- static PyObject * ! array_remove(arrayobject *self, PyObject *v) { int i; for (i = 0; i < self->ob_size; i++) { PyObject *selfi = getarrayitem((PyObject *)self,i); *************** *** 916,925 **** static PyObject * ! array_extend(arrayobject *self, PyObject *args) { - PyObject *bb; - - if (!PyArg_ParseTuple(args, "O:extend", &bb)) - return NULL; if (array_do_extend(self, bb) == -1) return NULL; --- 907,912 ---- static PyObject * ! array_extend(arrayobject *self, PyObject *bb) { if (array_do_extend(self, bb) == -1) return NULL; *************** *** 950,958 **** static PyObject * ! array_buffer_info(arrayobject *self, PyObject *args) { PyObject* retval = NULL; - if (!PyArg_ParseTuple(args, ":buffer_info")) - return NULL; retval = PyTuple_New(2); if (!retval) --- 937,943 ---- static PyObject * ! array_buffer_info(arrayobject *self, PyObject *unused) { PyObject* retval = NULL; retval = PyTuple_New(2); if (!retval) *************** *** 975,983 **** static PyObject * ! array_append(arrayobject *self, PyObject *args) { - PyObject *v; - if (!PyArg_ParseTuple(args, "O:append", &v)) - return NULL; return ins(self, (int) self->ob_size, v); } --- 960,965 ---- static PyObject * ! array_append(arrayobject *self, PyObject *v) { return ins(self, (int) self->ob_size, v); } *************** *** 990,1001 **** static PyObject * ! array_byteswap(arrayobject *self, PyObject *args) { char *p; int i; - if (!PyArg_ParseTuple(args, ":byteswap")) - return NULL; - switch (self->ob_descr->itemsize) { case 1: --- 972,980 ---- static PyObject * ! array_byteswap(arrayobject *self, PyObject *unused) { char *p; int i; switch (self->ob_descr->itemsize) { case 1: *************** *** 1050,1054 **** static PyObject * ! array_reverse(arrayobject *self, PyObject *args) { register int itemsize = self->ob_descr->itemsize; --- 1029,1033 ---- static PyObject * ! array_reverse(arrayobject *self, PyObject *unused) { register int itemsize = self->ob_descr->itemsize; *************** *** 1058,1064 **** assert(itemsize <= sizeof(tmp)); - if (!PyArg_ParseTuple(args, ":reverse")) - return NULL; - if (self->ob_size > 1) { for (p = self->ob_item, --- 1037,1040 ---- *************** *** 1139,1148 **** static PyObject * ! array_tofile(arrayobject *self, PyObject *args) { - PyObject *f; FILE *fp; ! if (!PyArg_ParseTuple(args, "O:tofile", &f)) ! return NULL; fp = PyFile_AsFile(f); if (fp == NULL) { --- 1115,1122 ---- static PyObject * ! array_tofile(arrayobject *self, PyObject *f) { FILE *fp; ! fp = PyFile_AsFile(f); if (fp == NULL) { *************** *** 1170,1180 **** static PyObject * ! array_fromlist(arrayobject *self, PyObject *args) { int n; - PyObject *list; int itemsize = self->ob_descr->itemsize; ! if (!PyArg_ParseTuple(args, "O:fromlist", &list)) ! return NULL; if (!PyList_Check(list)) { PyErr_SetString(PyExc_TypeError, "arg must be list"); --- 1144,1152 ---- static PyObject * ! array_fromlist(arrayobject *self, PyObject *list) { int n; int itemsize = self->ob_descr->itemsize; ! if (!PyList_Check(list)) { PyErr_SetString(PyExc_TypeError, "arg must be list"); *************** *** 1215,1224 **** static PyObject * ! array_tolist(arrayobject *self, PyObject *args) { PyObject *list = PyList_New(self->ob_size); int i; ! if (!PyArg_ParseTuple(args, ":tolist")) ! return NULL; if (list == NULL) return NULL; --- 1187,1195 ---- static PyObject * ! array_tolist(arrayobject *self, PyObject *unused) { PyObject *list = PyList_New(self->ob_size); int i; ! if (list == NULL) return NULL; *************** *** 1278,1285 **** static PyObject * ! array_tostring(arrayobject *self, PyObject *args) { - if (!PyArg_ParseTuple(args, ":tostring")) - return NULL; return PyString_FromStringAndSize(self->ob_item, self->ob_size * self->ob_descr->itemsize); --- 1249,1254 ---- static PyObject * ! array_tostring(arrayobject *self, PyObject *unused) { return PyString_FromStringAndSize(self->ob_item, self->ob_size * self->ob_descr->itemsize); *************** *** 1336,1343 **** static PyObject * ! array_tounicode(arrayobject *self, PyObject *args) { - if (!PyArg_ParseTuple(args, ":tounicode")) - return NULL; if (self->ob_descr->typecode != 'u') { PyErr_SetString(PyExc_ValueError, --- 1305,1310 ---- static PyObject * ! array_tounicode(arrayobject *self, PyObject *unused) { if (self->ob_descr->typecode != 'u') { PyErr_SetString(PyExc_ValueError, *************** *** 1381,1397 **** PyMethodDef array_methods[] = { ! {"append", (PyCFunction)array_append, METH_VARARGS, append_doc}, ! {"buffer_info", (PyCFunction)array_buffer_info, METH_VARARGS, buffer_info_doc}, ! {"byteswap", (PyCFunction)array_byteswap, METH_VARARGS, byteswap_doc}, ! {"count", (PyCFunction)array_count, METH_VARARGS, count_doc}, ! {"extend", (PyCFunction)array_extend, METH_VARARGS, extend_doc}, {"fromfile", (PyCFunction)array_fromfile, METH_VARARGS, fromfile_doc}, ! {"fromlist", (PyCFunction)array_fromlist, METH_VARARGS, fromlist_doc}, {"fromstring", (PyCFunction)array_fromstring, METH_VARARGS, --- 1348,1364 ---- PyMethodDef array_methods[] = { ! {"append", (PyCFunction)array_append, METH_O, append_doc}, ! {"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS, buffer_info_doc}, ! {"byteswap", (PyCFunction)array_byteswap, METH_NOARGS, byteswap_doc}, ! {"count", (PyCFunction)array_count, METH_O, count_doc}, ! {"extend", (PyCFunction)array_extend, METH_O, extend_doc}, {"fromfile", (PyCFunction)array_fromfile, METH_VARARGS, fromfile_doc}, ! {"fromlist", (PyCFunction)array_fromlist, METH_O, fromlist_doc}, {"fromstring", (PyCFunction)array_fromstring, METH_VARARGS, *************** *** 1401,1405 **** fromunicode_doc}, #endif ! {"index", (PyCFunction)array_index, METH_VARARGS, index_doc}, {"insert", (PyCFunction)array_insert, METH_VARARGS, --- 1368,1372 ---- fromunicode_doc}, #endif ! {"index", (PyCFunction)array_index, METH_O, index_doc}, {"insert", (PyCFunction)array_insert, METH_VARARGS, *************** *** 1409,1429 **** {"read", (PyCFunction)array_fromfile, METH_VARARGS, fromfile_doc}, ! {"remove", (PyCFunction)array_remove, METH_VARARGS, remove_doc}, ! {"reverse", (PyCFunction)array_reverse, METH_VARARGS, reverse_doc}, /* {"sort", (PyCFunction)array_sort, METH_VARARGS, sort_doc},*/ ! {"tofile", (PyCFunction)array_tofile, METH_VARARGS, tofile_doc}, ! {"tolist", (PyCFunction)array_tolist, METH_VARARGS, tolist_doc}, ! {"tostring", (PyCFunction)array_tostring, METH_VARARGS, tostring_doc}, #ifdef Py_USING_UNICODE ! {"tounicode", (PyCFunction)array_tounicode, METH_VARARGS, tounicode_doc}, #endif ! {"write", (PyCFunction)array_tofile, METH_VARARGS, tofile_doc}, {NULL, NULL} /* sentinel */ --- 1376,1396 ---- {"read", (PyCFunction)array_fromfile, METH_VARARGS, fromfile_doc}, ! {"remove", (PyCFunction)array_remove, METH_O, remove_doc}, ! {"reverse", (PyCFunction)array_reverse, METH_NOARGS, reverse_doc}, /* {"sort", (PyCFunction)array_sort, METH_VARARGS, sort_doc},*/ ! {"tofile", (PyCFunction)array_tofile, METH_O, tofile_doc}, ! {"tolist", (PyCFunction)array_tolist, METH_NOARGS, tolist_doc}, ! {"tostring", (PyCFunction)array_tostring, METH_NOARGS, tostring_doc}, #ifdef Py_USING_UNICODE ! {"tounicode", (PyCFunction)array_tounicode, METH_NOARGS, tounicode_doc}, #endif ! {"write", (PyCFunction)array_tofile, METH_O, tofile_doc}, {NULL, NULL} /* sentinel */ *************** *** 1445,1449 **** if (typecode == 'c' || typecode == 'u') { - PyObject *t_empty = PyTuple_New(0); PyOS_snprintf(buf, sizeof(buf), "array('%c', ", typecode); s = PyString_FromString(buf); --- 1412,1415 ---- *************** *** 1451,1460 **** if (typecode == 'c') #endif ! v = array_tostring(a, t_empty); #ifdef Py_USING_UNICODE else ! v = array_tounicode(a, t_empty); #endif - Py_DECREF(t_empty); t = PyObject_Repr(v); Py_XDECREF(v); --- 1417,1425 ---- if (typecode == 'c') #endif ! v = array_tostring(a, NULL); #ifdef Py_USING_UNICODE else ! v = array_tounicode(a, NULL); #endif t = PyObject_Repr(v); Py_XDECREF(v); Index: cStringIO.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cStringIO.c,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** cStringIO.c 1 Sep 2002 15:06:26 -0000 2.38 --- cStringIO.c 3 Jan 2003 08:24:58 -0000 2.39 *************** *** 88,95 **** static PyObject * ! IO_flush(IOobject *self, PyObject *args) { UNLESS (IO__opencheck(self)) return NULL; - UNLESS (PyArg_ParseTuple(args, ":flush")) return NULL; Py_INCREF(Py_None); --- 88,94 ---- static PyObject * ! IO_flush(IOobject *self, PyObject *unused) { UNLESS (IO__opencheck(self)) return NULL; Py_INCREF(Py_None); *************** *** 116,120 **** UNLESS (IO__opencheck(self)) return NULL; ! UNLESS (PyArg_ParseTuple(args,"|O:getval",&use_pos)) return NULL; if (PyObject_IsTrue(use_pos)) { --- 115,119 ---- UNLESS (IO__opencheck(self)) return NULL; ! UNLESS (PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL; if (PyObject_IsTrue(use_pos)) { *************** *** 130,137 **** static PyObject * ! IO_isatty(IOobject *self, PyObject *args) { ! ! UNLESS (PyArg_ParseTuple(args, ":isatty")) return NULL; ! Py_INCREF(Py_False); return Py_False; --- 129,133 ---- static PyObject * ! IO_isatty(IOobject *self, PyObject *unused) { Py_INCREF(Py_False); return Py_False; *************** *** 244,251 **** static PyObject * ! IO_reset(IOobject *self, PyObject *args) { UNLESS (IO__opencheck(self)) return NULL; - UNLESS (PyArg_ParseTuple(args, ":reset")) return NULL; self->pos = 0; --- 240,246 ---- static PyObject * ! IO_reset(IOobject *self, PyObject *unused) { UNLESS (IO__opencheck(self)) return NULL; self->pos = 0; *************** *** 258,265 **** static PyObject * ! IO_tell(IOobject *self, PyObject *args) { UNLESS (IO__opencheck(self)) return NULL; - UNLESS (PyArg_ParseTuple(args, ":tell")) return NULL; return PyInt_FromLong(self->pos); --- 253,259 ---- static PyObject * ! IO_tell(IOobject *self, PyObject *unused) { UNLESS (IO__opencheck(self)) return NULL; return PyInt_FromLong(self->pos); *************** *** 380,387 **** static PyObject * ! O_close(Oobject *self, PyObject *args) { ! ! UNLESS (PyArg_ParseTuple(args, ":close")) return NULL; ! if (self->buf != NULL) free(self->buf); self->buf = NULL; --- 374,378 ---- static PyObject * ! O_close(Oobject *self, PyObject *unused) { if (self->buf != NULL) free(self->buf); self->buf = NULL; *************** *** 401,406 **** static PyObject *joiner = NULL; - UNLESS (PyArg_ParseTuple(args, "O:writelines", &args)) return NULL; - if (!joiner) { PyObject *empty_string = PyString_FromString(""); --- 392,395 ---- *************** *** 429,447 **** static struct PyMethodDef O_methods[] = { /* Common methods: */ ! {"flush", (PyCFunction)IO_flush, METH_VARARGS, IO_flush__doc__}, {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__}, ! {"isatty", (PyCFunction)IO_isatty, METH_VARARGS, IO_isatty__doc__}, {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__}, {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__}, {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__}, ! {"reset", (PyCFunction)IO_reset, METH_VARARGS, IO_reset__doc__}, ! {"tell", (PyCFunction)IO_tell, METH_VARARGS, IO_tell__doc__}, {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__}, /* Read-write StringIO specific methods: */ ! {"close", (PyCFunction)O_close, METH_VARARGS, O_close__doc__}, {"seek", (PyCFunction)O_seek, METH_VARARGS, O_seek__doc__}, {"write", (PyCFunction)O_write, METH_VARARGS, O_write__doc__}, ! {"writelines", (PyCFunction)O_writelines, METH_VARARGS, O_writelines__doc__}, {NULL, NULL} /* sentinel */ }; --- 418,436 ---- static struct PyMethodDef O_methods[] = { /* Common methods: */ ! {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__}, {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__}, ! {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__}, {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__}, {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__}, {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__}, ! {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__}, ! {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__}, {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__}, /* Read-write StringIO specific methods: */ ! {"close", (PyCFunction)O_close, METH_NOARGS, O_close__doc__}, {"seek", (PyCFunction)O_seek, METH_VARARGS, O_seek__doc__}, {"write", (PyCFunction)O_write, METH_VARARGS, O_write__doc__}, ! {"writelines", (PyCFunction)O_writelines, METH_O, O_writelines__doc__}, {NULL, NULL} /* sentinel */ }; *************** *** 528,535 **** static PyObject * ! I_close(Iobject *self, PyObject *args) { ! ! UNLESS (PyArg_ParseTuple(args, ":close")) return NULL; ! Py_XDECREF(self->pbuf); self->pbuf = NULL; --- 517,521 ---- static PyObject * ! I_close(Iobject *self, PyObject *unused) { Py_XDECREF(self->pbuf); self->pbuf = NULL; *************** *** 563,578 **** static struct PyMethodDef I_methods[] = { /* Common methods: */ ! {"flush", (PyCFunction)IO_flush, METH_VARARGS, IO_flush__doc__}, {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__}, ! {"isatty", (PyCFunction)IO_isatty, METH_VARARGS, IO_isatty__doc__}, {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__}, {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__}, {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__}, ! {"reset", (PyCFunction)IO_reset, METH_VARARGS, IO_reset__doc__}, ! {"tell", (PyCFunction)IO_tell, METH_VARARGS, IO_tell__doc__}, {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__}, /* Read-only StringIO specific methods: */ ! {"close", (PyCFunction)I_close, METH_VARARGS, O_close__doc__}, {"seek", (PyCFunction)I_seek, METH_VARARGS, O_seek__doc__}, {NULL, NULL} --- 549,564 ---- static struct PyMethodDef I_methods[] = { /* Common methods: */ ! {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__}, {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__}, ! {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__}, {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__}, {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__}, {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__}, ! {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__}, ! {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__}, {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__}, /* Read-only StringIO specific methods: */ ! {"close", (PyCFunction)I_close, METH_NOARGS, O_close__doc__}, {"seek", (PyCFunction)I_seek, METH_VARARGS, O_seek__doc__}, {NULL, NULL} *************** *** 675,679 **** PyObject *s=0; ! if (!PyArg_ParseTuple(args, "|O:StringIO", &s)) return NULL; if (s) return newIobject(s); --- 661,665 ---- PyObject *s=0; ! if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL; if (s) return newIobject(s); Index: operator.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/operator.c,v retrieving revision 2.25 retrieving revision 2.26 diff -C2 -d -r2.25 -r2.26 *** operator.c 29 Dec 2002 16:31:07 -0000 2.25 --- operator.c 3 Jan 2003 08:24:58 -0000 2.26 *************** *** 11,17 **** '__' are also provided for convenience."); ! #define spam1(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \ ! PyObject *a1; \ ! if(! PyArg_UnpackTuple(a,#OP,1,1,&a1)) return NULL; \ return AOP(a1); } --- 11,15 ---- '__' are also provided for convenience."); ! #define spam1(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \ return AOP(a1); } *************** *** 40,46 **** return Py_None; } ! #define spami(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \ ! PyObject *a1; long r; \ ! if(! PyArg_UnpackTuple(a,#OP,1,1,&a1)) return NULL; \ if(-1 == (r=AOP(a1))) return NULL; \ return PyBool_FromLong(r); } --- 38,43 ---- return Py_None; } ! #define spami(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \ ! long r; \ if(-1 == (r=AOP(a1))) return NULL; \ return PyBool_FromLong(r); } *************** *** 156,172 **** #undef spam1 #undef spam2 #define spam1(OP,DOC) {#OP, OP, METH_VARARGS, PyDoc_STR(DOC)}, #define spam2(OP,ALTOP,DOC) {#OP, op_##OP, METH_VARARGS, DOC}, \ {#ALTOP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)}, static struct PyMethodDef operator_methods[] = { ! spam1(isCallable, "isCallable(a) -- Same as callable(a).") ! spam1(isNumberType, "isNumberType(a) -- Return True if a has a numeric type, False otherwise.") ! spam1(isSequenceType, "isSequenceType(a) -- Return True if a has a sequence type, False otherwise.") ! spam1(truth, "truth(a) -- Return True if a is true, False otherwise.") spam2(contains,__contains__, --- 153,174 ---- #undef spam1 #undef spam2 + #undef spam1o + #undef spam1o #define spam1(OP,DOC) {#OP, OP, METH_VARARGS, PyDoc_STR(DOC)}, #define spam2(OP,ALTOP,DOC) {#OP, op_##OP, METH_VARARGS, DOC}, \ {#ALTOP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)}, + #define spam1o(OP,DOC) {#OP, OP, METH_O, PyDoc_STR(DOC)}, + #define spam2o(OP,ALTOP,DOC) {#OP, op_##OP, METH_O, DOC}, \ + {#ALTOP, op_##OP, METH_O, PyDoc_STR(DOC)}, static struct PyMethodDef operator_methods[] = { ! spam1o(isCallable, "isCallable(a) -- Same as callable(a).") ! spam1o(isNumberType, "isNumberType(a) -- Return True if a has a numeric type, False otherwise.") ! spam1o(isSequenceType, "isSequenceType(a) -- Return True if a has a sequence type, False otherwise.") ! spam1o(truth, "truth(a) -- Return True if a is true, False otherwise.") spam2(contains,__contains__, *************** *** 178,182 **** spam1(countOf, "countOf(a, b) -- Return the number of times b occurs in a.") ! spam1(isMappingType, "isMappingType(a) -- Return True if a has a mapping type, False otherwise.") --- 180,184 ---- spam1(countOf, "countOf(a, b) -- Return the number of times b occurs in a.") ! spam1o(isMappingType, "isMappingType(a) -- Return True if a has a mapping type, False otherwise.") *************** *** 188,199 **** spam2(truediv,__truediv__, "truediv(a, b) -- Same as a / b when __future__.division is in effect.") spam2(mod,__mod__, "mod(a, b) -- Same as a % b.") ! spam2(neg,__neg__, "neg(a) -- Same as -a.") ! spam2(pos,__pos__, "pos(a) -- Same as +a.") ! spam2(abs,__abs__, "abs(a) -- Same as abs(a).") ! spam2(inv,__inv__, "inv(a) -- Same as ~a.") ! spam2(invert,__invert__, "invert(a) -- Same as ~a.") spam2(lshift,__lshift__, "lshift(a, b) -- Same as a << b.") spam2(rshift,__rshift__, "rshift(a, b) -- Same as a >> b.") ! spam2(not_,__not__, "not_(a) -- Same as not a.") spam2(and_,__and__, "and_(a, b) -- Same as a & b.") spam2(xor,__xor__, "xor(a, b) -- Same as a ^ b.") --- 190,201 ---- spam2(truediv,__truediv__, "truediv(a, b) -- Same as a / b when __future__.division is in effect.") spam2(mod,__mod__, "mod(a, b) -- Same as a % b.") ! spam2o(neg,__neg__, "neg(a) -- Same as -a.") ! spam2o(pos,__pos__, "pos(a) -- Same as +a.") ! spam2o(abs,__abs__, "abs(a) -- Same as abs(a).") ! spam2o(inv,__inv__, "inv(a) -- Same as ~a.") ! spam2o(invert,__invert__, "invert(a) -- Same as ~a.") spam2(lshift,__lshift__, "lshift(a, b) -- Same as a << b.") spam2(rshift,__rshift__, "rshift(a, b) -- Same as a >> b.") ! spam2o(not_,__not__, "not_(a) -- Same as not a.") spam2(and_,__and__, "and_(a, b) -- Same as a & b.") spam2(xor,__xor__, "xor(a, b) -- Same as a ^ b.") From mwh@users.sourceforge.net Fri Jan 3 10:25:24 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Fri, 03 Jan 2003 02:25:24 -0800 Subject: [Python-checkins] python/dist/src/Lib/compiler transformer.py,1.35,1.36 Message-ID: <E18UP12-0007iL-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/compiler In directory sc8-pr-cvs1:/tmp/cvs-serv29464 Modified Files: transformer.py Log Message: Remove debugging prints. Index: transformer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/transformer.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** transformer.py 31 Dec 2002 18:17:42 -0000 1.35 --- transformer.py 3 Jan 2003 10:25:20 -0000 1.36 *************** *** 651,655 **** elt = nodelist[0] t = elt[0] - print "source", nodelist[-1] node = self.com_node(nodelist[-1]) # need to handle (unary op)constant here... --- 651,654 ---- *************** *** 658,662 **** node.lineno = elt[2] elif t == token.MINUS: - print node node = UnarySub(node) node.lineno = elt[2] --- 657,660 ---- From rhettinger@users.sourceforge.net Fri Jan 3 10:41:54 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 03 Jan 2003 02:41:54 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.98,1.99 Message-ID: <E18UPH0-0000kO-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv2793 Modified Files: whatsnew23.tex Log Message: Add contributor. Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -d -r1.98 -r1.99 *** whatsnew23.tex 2 Jan 2003 23:50:18 -0000 1.98 --- whatsnew23.tex 3 Jan 2003 10:41:50 -0000 1.99 *************** *** 1885,1888 **** --- 1885,1889 ---- For more information, refer to the \ulink{module's reference documentation}{http://www.python.org/dev/doc/devel/lib/module-datetime.html}. + (Contributed by Tim Peters.) From jvr@users.sourceforge.net Fri Jan 3 11:18:58 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Fri, 03 Jan 2003 03:18:58 -0800 Subject: [Python-checkins] python/dist/src/Modules zipimport.c,1.7,1.8 Message-ID: <E18UPqs-0004i1-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv15788/Modules Modified Files: zipimport.c Log Message: Fix for bug #661136 Lesson learned: kids should not be allowed to use API's starting with an underscore :-/ zipimport in 2.3a1 is even more broken than I thought: I attemped to _PyString_Resize a string created by PyString_FromStringAndSize, which fails for strings with length 0 or 1 since the latter returns an interned string in those cases. This would cause a SystemError with empty source files (and no matching pyc) in the zip archive. I rewrote the offending code to simply allocate a new buffer and avoid _PyString_Resize altogether. Added a test that would've caught the problem. Index: zipimport.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zipimport.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** zipimport.c 2 Jan 2003 12:55:48 -0000 1.7 --- zipimport.c 3 Jan 2003 11:18:55 -0000 1.8 *************** *** 907,911 **** } ! if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4), mtime)) { if (Py_VerboseFlag) PySys_WriteStderr("# %s has bad mtime\n", --- 907,912 ---- } ! if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4), ! mtime)) { if (Py_VerboseFlag) PySys_WriteStderr("# %s has bad mtime\n", *************** *** 935,955 **** normalize_line_endings(PyObject *source) { ! char *q, *p = PyString_AsString(source); ! int length = PyString_Size(source) + 1; PyObject *fixed_source; ! fixed_source = PyString_FromStringAndSize(p, length); ! if (fixed_source == NULL) return NULL; ! ! q = PyString_AsString(fixed_source); /* replace "\r\n?" by "\n" */ ! for (;;) { if (*p == '\r') { *q++ = '\n'; ! if (*(p + 1) == '\n') { p++; - length--; - } } else --- 936,956 ---- normalize_line_endings(PyObject *source) { ! char *buf, *q, *p = PyString_AsString(source); PyObject *fixed_source; ! /* one char extra for trailing \n and one for terminating \0 */ ! buf = PyMem_Malloc(PyString_Size(source) + 2); ! if (buf == NULL) { ! PyErr_SetString(PyExc_MemoryError, ! "zipimport: no memory to allocate " ! "source buffer"); return NULL; ! } /* replace "\r\n?" by "\n" */ ! for (q = buf;;) { if (*p == '\r') { *q++ = '\n'; ! if (*(p + 1) == '\n') p++; } else *************** *** 961,965 **** *q++ = '\n'; /* add trailing \n */ *q = '\0'; ! _PyString_Resize(&fixed_source, length); return fixed_source; } --- 962,967 ---- *q++ = '\n'; /* add trailing \n */ *q = '\0'; ! fixed_source = PyString_FromString(buf); ! PyMem_Free(buf); return fixed_source; } From jvr@users.sourceforge.net Fri Jan 3 11:18:58 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Fri, 03 Jan 2003 03:18:58 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_zipimport.py,1.2,1.3 Message-ID: <E18UPqs-0004i4-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv15788/Lib/test Modified Files: test_zipimport.py Log Message: Fix for bug #661136 Lesson learned: kids should not be allowed to use API's starting with an underscore :-/ zipimport in 2.3a1 is even more broken than I thought: I attemped to _PyString_Resize a string created by PyString_FromStringAndSize, which fails for strings with length 0 or 1 since the latter returns an interned string in those cases. This would cause a SystemError with empty source files (and no matching pyc) in the zip archive. I rewrote the offending code to simply allocate a new buffer and avoid _PyString_Resize altogether. Added a test that would've caught the problem. Index: test_zipimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zipimport.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_zipimport.py 2 Jan 2003 12:55:48 -0000 1.2 --- test_zipimport.py 3 Jan 2003 11:18:56 -0000 1.3 *************** *** 57,63 **** mod = __import__(".".join(modules), globals(), locals(), ["__dummy__"]) ! file = mod.get_file() ! self.assertEquals(file, os.path.join(TEMP_ZIP, ! os.sep.join(modules) + expected_ext)) finally: z.close() --- 57,64 ---- mod = __import__(".".join(modules), globals(), locals(), ["__dummy__"]) ! if expected_ext: ! file = mod.get_file() ! self.assertEquals(file, os.path.join(TEMP_ZIP, ! os.sep.join(modules) + expected_ext)) finally: z.close() *************** *** 101,104 **** --- 102,109 ---- TESTMOD + pyc_ext: (NOW, test_pyc)} self.doTest(pyc_ext, files, TESTMOD) + + def testEmptyPy(self): + files = {TESTMOD + ".py": (NOW, "")} + self.doTest(None, files, TESTMOD) def testBadMagic(self): From jvr@users.sourceforge.net Fri Jan 3 11:24:33 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Fri, 03 Jan 2003 03:24:33 -0800 Subject: [Python-checkins] python/dist/src/Modules zipimport.c,1.6.2.1,1.6.2.2 Message-ID: <E18UPwH-0005Aq-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv19816/Modules Modified Files: Tag: r23a1-branch zipimport.c Log Message: Backported fix for bug #661136 to the 2.3a1 release branch. Index: zipimport.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zipimport.c,v retrieving revision 1.6.2.1 retrieving revision 1.6.2.2 diff -C2 -d -r1.6.2.1 -r1.6.2.2 *** zipimport.c 2 Jan 2003 15:19:27 -0000 1.6.2.1 --- zipimport.c 3 Jan 2003 11:24:31 -0000 1.6.2.2 *************** *** 907,911 **** } ! if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4), mtime)) { if (Py_VerboseFlag) PySys_WriteStderr("# %s has bad mtime\n", --- 907,912 ---- } ! if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4), ! mtime)) { if (Py_VerboseFlag) PySys_WriteStderr("# %s has bad mtime\n", *************** *** 935,955 **** normalize_line_endings(PyObject *source) { ! char *q, *p = PyString_AsString(source); ! int length = PyString_Size(source) + 1; PyObject *fixed_source; ! fixed_source = PyString_FromStringAndSize(p, length); ! if (fixed_source == NULL) return NULL; ! ! q = PyString_AsString(fixed_source); /* replace "\r\n?" by "\n" */ ! for (;;) { if (*p == '\r') { *q++ = '\n'; ! if (*(p + 1) == '\n') { p++; - length--; - } } else --- 936,956 ---- normalize_line_endings(PyObject *source) { ! char *buf, *q, *p = PyString_AsString(source); PyObject *fixed_source; ! /* one char extra for trailing \n and one for terminating \0 */ ! buf = PyMem_Malloc(PyString_Size(source) + 2); ! if (buf == NULL) { ! PyErr_SetString(PyExc_MemoryError, ! "zipimport: no memory to allocate " ! "source buffer"); return NULL; ! } /* replace "\r\n?" by "\n" */ ! for (q = buf;;) { if (*p == '\r') { *q++ = '\n'; ! if (*(p + 1) == '\n') p++; } else *************** *** 961,965 **** *q++ = '\n'; /* add trailing \n */ *q = '\0'; ! _PyString_Resize(&fixed_source, length); return fixed_source; } --- 962,967 ---- *q++ = '\n'; /* add trailing \n */ *q = '\0'; ! fixed_source = PyString_FromString(buf); ! PyMem_Free(buf); return fixed_source; } From jvr@users.sourceforge.net Fri Jan 3 11:24:33 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Fri, 03 Jan 2003 03:24:33 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_zipimport.py,1.1.2.1,1.1.2.2 Message-ID: <E18UPwH-0005As-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv19816/Lib/test Modified Files: Tag: r23a1-branch test_zipimport.py Log Message: Backported fix for bug #661136 to the 2.3a1 release branch. Index: test_zipimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zipimport.py,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** test_zipimport.py 2 Jan 2003 15:24:38 -0000 1.1.2.1 --- test_zipimport.py 3 Jan 2003 11:24:31 -0000 1.1.2.2 *************** *** 57,63 **** mod = __import__(".".join(modules), globals(), locals(), ["__dummy__"]) ! file = mod.get_file() ! self.assertEquals(file, os.path.join(TEMP_ZIP, ! os.sep.join(modules) + expected_ext)) finally: z.close() --- 57,64 ---- mod = __import__(".".join(modules), globals(), locals(), ["__dummy__"]) ! if expected_ext: ! file = mod.get_file() ! self.assertEquals(file, os.path.join(TEMP_ZIP, ! os.sep.join(modules) + expected_ext)) finally: z.close() *************** *** 101,104 **** --- 102,109 ---- TESTMOD + pyc_ext: (NOW, test_pyc)} self.doTest(pyc_ext, files, TESTMOD) + + def testEmptyPy(self): + files = {TESTMOD + ".py": (NOW, "")} + self.doTest(None, files, TESTMOD) def testBadMagic(self): From akuchling@users.sourceforge.net Fri Jan 3 15:24:40 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Fri, 03 Jan 2003 07:24:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils dist.py,1.60,1.61 Message-ID: <E18UTge-0006M9-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/distutils In directory sc8-pr-cvs1:/tmp/cvs-serv23946 Modified Files: dist.py Log Message: [Patch #658094] PEP 301 implementation Add 'classifiers' keyword to DistributionMetadata Index: dist.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/dist.py,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** dist.py 19 Nov 2002 13:12:27 -0000 1.60 --- dist.py 3 Jan 2003 15:24:36 -0000 1.61 *************** *** 94,97 **** --- 94,99 ---- ('platforms', None, "print the list of platforms"), + ('classifiers', None, + "print the list of classifiers"), ('keywords', None, "print the list of keywords"), *************** *** 635,638 **** --- 637,642 ---- if opt in ['keywords', 'platforms']: print string.join(value, ',') + elif opt == 'classifiers': + print string.join(value, '\n') else: print value *************** *** 963,967 **** "license", "description", "long_description", "keywords", "platforms", "fullname", "contact", ! "contact_email", "licence") def __init__ (self): --- 967,971 ---- "license", "description", "long_description", "keywords", "platforms", "fullname", "contact", ! "contact_email", "licence", "classifiers") def __init__ (self): *************** *** 978,981 **** --- 982,986 ---- self.keywords = None self.platforms = None + self.classifiers = None def write_pkg_info (self, base_dir): *************** *** 1004,1007 **** --- 1009,1015 ---- pkg_info.write('Platform: %s\n' % platform ) + for classifier in self.get_classifiers(): + pkg_info.write('Classifier: %s\n' % classifier ) + pkg_info.close() *************** *** 1059,1062 **** --- 1067,1073 ---- def get_platforms(self): return self.platforms or ["UNKNOWN"] + + def get_classifiers(self): + return self.classifiers or [] # class DistributionMetadata From theller@python.net Fri Jan 3 15:56:48 2003 From: theller@python.net (Thomas Heller) Date: 03 Jan 2003 16:56:48 +0100 Subject: [Python-checkins] python/dist/src/Lib/distutils dist.py,1.60,1.61 In-Reply-To: <E18UTge-0006M9-00@sc8-pr-cvs1.sourceforge.net> References: <E18UTge-0006M9-00@sc8-pr-cvs1.sourceforge.net> Message-ID: <65t6xm4f.fsf@python.net> akuchling@users.sourceforge.net writes: > Update of /cvsroot/python/python/dist/src/Lib/distutils > In directory sc8-pr-cvs1:/tmp/cvs-serv23946 > > Modified Files: > dist.py > Log Message: > [Patch #658094] PEP 301 implementation > Add 'classifiers' keyword to DistributionMetadata Is PEP 301 accepted? Thomas From akuchling@users.sourceforge.net Fri Jan 3 15:42:17 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Fri, 03 Jan 2003 07:42:17 -0800 Subject: [Python-checkins] python/dist/src/Doc/dist dist.tex,1.47,1.48 Message-ID: <E18UTxh-0000P4-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/dist In directory sc8-pr-cvs1:/tmp/cvs-serv1225 Modified Files: dist.tex Log Message: [Patch #658093 ] Documentation support for PEP 301 Add two sections to this manual about package meta-data and about registering packages Index: dist.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/dist/dist.tex,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** dist.tex 12 Dec 2002 19:35:00 -0000 1.47 --- dist.tex 3 Jan 2003 15:42:14 -0000 1.48 *************** *** 283,287 **** a couple of dozen modules split into (so far) two packages; an explicit list of every module would be tedious to generate and difficult to ! maintain. Note that any pathnames (files or directories) supplied in the setup --- 283,288 ---- a couple of dozen modules split into (so far) two packages; an explicit list of every module would be tedious to generate and difficult to ! maintain. For more information on the additional meta-data, see ! section~\ref{meta-data}. Note that any pathnames (files or directories) supplied in the setup *************** *** 681,684 **** --- 682,753 ---- string should be given as the directory. + \subsection{Additional meta-data} + \label{meta-data} + + The setup script may include additional meta-data beyond the name and + version. This information includes: + + \begin{tableiii}{l|l|c}{code}% + {Meta-Data}{Description}{Notes} + \lineiii{name}{the name of the package}{(1)} + \lineiii{version}{the version of this release}{(1)} + \lineiii{author}{package author's name}{(2)} + \lineiii{author_email}{email address of the package author}{(2)} + \lineiii{maintainer}{package maintainer's name}{(2)} + \lineiii{maintainer_email}{email address of the package maintainer}{(2)} + \lineiii{home_page}{a URL}{(1)} + \lineiii{license}{the terms the package is released under}{} + \lineiii{description}{a short, summary description of the package}{} + \lineiii{long_description}{a longer description of the package}{} + \lineiii{keywords}{some keywords appropriate to the package}{} + \lineiii{platform}{a list of the target platforms}{} + \lineiii{classifiers}{a list of Trove classifiers}{(2)} + \end{tableiii} + + \noindent Notes: + \begin{description} + \item[(1)] these fields are required + \item[(2)] either the author or the maintainer must be nominated + \item[(3)] should not be used if your package is to be compatible with + Python versions prior to 2.2.3 or 2.3. The list is available from the + PyPI website. + \end{description} + + \option{classifiers} are specified in a python list: + + \begin{verbatim} + setup(... + classifiers = [ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Environment :: Web Environment', + 'Intended Audience :: End Users/Desktop', + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Python Software Foundation License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Programming Language :: Python', + 'Topic :: Communications :: Email', + 'Topic :: Office/Business', + 'Topic :: Software Development :: Bug Tracking', + ], + ... + ) + \end{verbatim} + + If you wish to include classifiers in your \file{setup.py} file and also + wish to remain backwards-compatible with Python releases prior to 2.2.3, + then you can include the following code fragment in your \file{setup.py} + before the \code{setup()} call. + + \begin{verbatim} + # patch distutils if it can't cope with the "classifiers" keyword + if sys.version < '2.2.3': + from distutils.dist import DistributionMetadata + DistributionMetadata.classifiers = None + \end{verbatim} + \section{Writing the Setup Configuration File} *************** *** 1395,1402 **** documentation for the \code{IShellLink} interface. ! \section{Examples} ! \label{examples} \subsection{Pure Python distribution (by module)} \label{pure-mod} --- 1464,1523 ---- documentation for the \code{IShellLink} interface. ! \section{Registering with the Package Index} ! \label{package-index} ! ! The Python Package Index (PyPI) holds meta-data describing distributions ! packaged with distutils. The distutils command \command{register} is ! used to submit your distribution's meta-data to the index. It is invoked ! as follows: + \begin{verbatim} + python setup.py register + \end{verbatim} + + Distutils will respond with the following prompt: + + \begin{verbatim} + running register + We need to know who you are, so please choose either: + 1. use your existing login, + 2. register as a new user, + 3. have the server generate a new password for you (and email it to you), or + 4. quit + Your selection [default 1]: + \end{verbatim} + \noindent Note: if your username and password are saved locally, you will + not see this menu. + + If you have not registered with PyPI, then you will need to do so now. You + should choose option 2, and enter your details as required. Soon after + submitting your details, you will receive an email which will be used to + confirm your registration. + + Once you are registered, you may choose option 1 from the menu. You will + be prompted for your PyPI username and password, and \command{register} + will then submit your meta-data to the index. + + You may submit any number of versions of your distribution to the index. If + you alter the meta-data for a particular version, you may submit it again + and the index will be updated. + + PyPI holds a record for each (name, version) combination submitted. The + first user to submit information for a given name is designated the Owner + of that name. They may submit changes through the \command{register} + command or through the web interface. They may also designate other users + as Owners or Maintainers. Maintainers may edit the package information, but + not designate other Owners or Maintainers. + + By default PyPI will list all versions of a given package. To hide certain + versions, the Hidden property should be set to yes. This must be edited + through the web interface. + + + + \section{Examples} + \label{examples} + \subsection{Pure Python distribution (by module)} \label{pure-mod} From akuchlin@mems-exchange.org Fri Jan 3 16:10:06 2003 From: akuchlin@mems-exchange.org (Andrew Kuchling) Date: Fri, 3 Jan 2003 11:10:06 -0500 Subject: [Python-checkins] python/dist/src/Lib/distutils dist.py,1.60,1.61 In-Reply-To: <65t6xm4f.fsf@python.net> References: <E18UTge-0006M9-00@sc8-pr-cvs1.sourceforge.net> <65t6xm4f.fsf@python.net> Message-ID: <20030103161006.GA21582@ute.mems-exchange.org> On Fri, Jan 03, 2003 at 04:56:48PM +0100, Thomas Heller wrote: >Is PEP 301 accepted? Quoting the BDFL via Richard Jones: ''' This only affects distutils, right? I'm firmly staying out of distutils design and implementation issues. If AMK thinks this is a good idea, I follow his lead in this matter. So consider this a +0 from me. Is that good enough? I really don't want to have read the PEP (no time), and I really don't want to Pronounce on something I haven't read, so that's probably all you'll get out of me. OK? (If not, I'll dive in more deeply.) ''' I think the register.py implementation is OK, so I committed it now so it can get wider exposure before 2.3alpha2. That's the most important part to get right, because we can rewrite the web interface to the catalog whenever we like. I'm going to send notes to the Distutil and Catalog SIGs, and to python-dev and python-list about this checkin to encourage feedback about it. --amk (www.amk.ca) Thou hast made the Furies cry, Orpheus. They will never forgive you for that. -- Queen Persephone, in SANDMAN: "The Song of Orpheus" From montanaro@users.sourceforge.net Fri Jan 3 16:17:11 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 03 Jan 2003 08:17:11 -0800 Subject: [Python-checkins] python/dist/src README,1.162,1.163 Message-ID: <E18UUVT-0005QY-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv20844 Modified Files: README Log Message: update info about binutils 2.13 breakage on Solaris. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.162 retrieving revision 1.163 diff -C2 -d -r1.162 -r1.163 *** README 31 Dec 2002 01:50:07 -0000 1.162 --- README 3 Jan 2003 16:17:08 -0000 1.163 *************** *** 272,277 **** -zcombreloc option which creates broken shared libraries on Solaris. binutils 2.12 works, and the binutils maintainers ! are aware of the problem, so binutils 2.13.1 will probably fix ! this problem. When the dynamic loader complains about errors finding shared --- 272,277 ---- -zcombreloc option which creates broken shared libraries on Solaris. binutils 2.12 works, and the binutils maintainers ! are aware of the problem. Binutils 2.13.1 only partially fixed ! things. It appears that 2.13.2 solves the problem completely. When the dynamic loader complains about errors finding shared From akuchling@users.sourceforge.net Fri Jan 3 16:24:30 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Fri, 03 Jan 2003 08:24:30 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.99,1.100 Message-ID: <E18UUcY-0006RO-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv24737 Modified Files: whatsnew23.tex Log Message: Add SSL support for imaplib; add empty PEP301 section Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.99 retrieving revision 1.100 diff -C2 -d -r1.99 -r1.100 *** whatsnew23.tex 3 Jan 2003 10:41:50 -0000 1.99 --- whatsnew23.tex 3 Jan 2003 16:24:28 -0000 1.100 *************** *** 703,706 **** --- 703,718 ---- %====================================================================== + \section{PEP 301: Package Index and Metadata for Distutils\label{section-pep301}} + + XXX This section needs to be written. + + \begin{seealso} + + \seepep{301}{Package Index and Metadata for Distutils}{Written and implemented by Richard Jones.} + + \end{seealso} + + + %====================================================================== \section{PEP 302: New Import Hooks \label{section-pep302}} *************** *** 1288,1291 **** --- 1300,1306 ---- (Contributed by Kevin O'Connor.) + + \item The \module{imaplib} module now supports IMAP over SSL. + (Contributed by Piers Lauder and Tino Lange.) \item Two new functions in the \module{math} module, From akuchling@users.sourceforge.net Fri Jan 3 15:29:30 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Fri, 03 Jan 2003 07:29:30 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils/command register.py,NONE,1.1 Message-ID: <E18UTlK-00073M-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory sc8-pr-cvs1:/tmp/cvs-serv26801 Added Files: register.py Log Message: [Patch #658094 ] PEP 301 implementation Add the 'register' distutils command --- NEW FILE: register.py --- """distutils.command.register Implements the Distutils 'register' command (register with the repository). """ # created 2002/10/21, Richard Jones __revision__ = "$Id: register.py,v 1.1 2003/01/03 15:29:28 akuchling Exp $" import sys, os, string, urllib2, getpass, urlparse import StringIO, ConfigParser from distutils.core import Command from distutils.errors import * class register(Command): description = "register the distribution with the repository" # XXX must update this to python.org before 2.3final! DEFAULT_REPOSITORY = 'http://www.amk.ca/cgi-bin/pypi.cgi' user_options = [ ('repository=', 'r', "url of repository [default: %s]"%DEFAULT_REPOSITORY), ('verify', None, 'verify the package metadata for correctness'), ('list-classifiers', None, 'list the valid Trove classifiers'), ('verbose', None, 'display full response from server'), ] boolean_options = ['verify', 'verbose', 'list-classifiers'] def initialize_options(self): self.repository = None self.verify = 0 self.verbose = 0 self.list_classifiers = 0 def finalize_options(self): if self.repository is None: self.repository = self.DEFAULT_REPOSITORY def run(self): self.check_metadata() if self.verify: self.verify_metadata() elif self.list_classifiers: self.classifiers() else: self.send_metadata() def check_metadata(self): """Ensure that all required elements of meta-data (name, version, URL, (author and author_email) or (maintainer and maintainer_email)) are supplied by the Distribution object; warn if any are missing. """ metadata = self.distribution.metadata missing = [] for attr in ('name', 'version', 'url'): if not (hasattr(metadata, attr) and getattr(metadata, attr)): missing.append(attr) if missing: self.warn("missing required meta-data: " + string.join(missing, ", ")) if metadata.author: if not metadata.author_email: self.warn("missing meta-data: if 'author' supplied, " + "'author_email' must be supplied too") elif metadata.maintainer: if not metadata.maintainer_email: self.warn("missing meta-data: if 'maintainer' supplied, " + "'maintainer_email' must be supplied too") else: self.warn("missing meta-data: either (author and author_email) " + "or (maintainer and maintainer_email) " + "must be supplied") def classifiers(self): ''' Fetch the list of classifiers from the server. ''' response = urllib2.urlopen(self.repository+'?:action=list_classifiers') print response.read() def verify_metadata(self): ''' Send the metadata to the package index server to be checked. ''' # send the info to the server and report the result (code, result) = self.post_to_server(self.build_post_data('verify')) print 'Server response (%s): %s'%(code, result) def send_metadata(self): ''' Send the metadata to the package index server. Well, do the following: 1. figure who the user is, and then 2. send the data as a Basic auth'ed POST. First we try to read the username/password from $HOME/.pypirc, which is a ConfigParser-formatted file with a section [server-login] containing username and password entries (both in clear text). Eg: [server-login] username: fred password: sekrit Otherwise, to figure who the user is, we offer the user three choices: 1. use existing login, 2. register as a new user, or 3. set the password to a random string and email the user. ''' choice = 'x' username = password = '' # see if we can short-cut and get the username/password from the # config config = None if os.environ.has_key('HOME'): rc = os.path.join(os.environ['HOME'], '.pypirc') if os.path.exists(rc): print 'Using PyPI login from %s'%rc config = ConfigParser.ConfigParser() config.read(rc) username = config.get('server-login', 'username') password = config.get('server-login', 'password') choice = '1' # get the user's login info choices = '1 2 3 4'.split() while choice not in choices: print '''We need to know who you are, so please choose either: 1. use your existing login, 2. register as a new user, 3. have the server generate a new password for you (and email it to you), or 4. quit Your selection [default 1]: ''', choice = raw_input() if not choice: choice = '1' elif choice not in choices: print 'Please choose one of the four options!' if choice == '1': # get the username and password while not username: username = raw_input('Username: ') while not password: password = getpass.getpass('Password: ') # set up the authentication auth = urllib2.HTTPPasswordMgr() host = urlparse.urlparse(self.repository)[1] auth.add_password('pypi', host, username, password) # send the info to the server and report the result code, result = self.post_to_server(self.build_post_data('submit'), auth) print 'Server response (%s): %s'%(code, result) # possibly save the login if os.environ.has_key('HOME') and config is None and code == 200: rc = os.path.join(os.environ['HOME'], '.pypirc') print 'I can store your PyPI login so future submissions will be faster.' print '(the login will be stored in %s)'%rc choice = 'X' while choice.lower() not in 'yn': choice = raw_input('Save your login (y/N)?') if not choice: choice = 'n' if choice.lower() == 'y': f = open(rc, 'w') f.write('[server-login]\nusername:%s\npassword:%s\n'%( username, password)) f.close() try: os.chmod(rc, 0600) except: pass elif choice == '2': data = {':action': 'user'} data['name'] = data['password'] = data['email'] = '' data['confirm'] = None while not data['name']: data['name'] = raw_input('Username: ') while data['password'] != data['confirm']: while not data['password']: data['password'] = getpass.getpass('Password: ') while not data['confirm']: data['confirm'] = getpass.getpass(' Confirm: ') if data['password'] != data['confirm']: data['password'] = '' data['confirm'] = None print "Password and confirm don't match!" while not data['email']: data['email'] = raw_input(' EMail: ') code, result = self.post_to_server(data) if code != 200: print 'Server response (%s): %s'%(code, result) else: print 'You will receive an email shortly.' print 'Follow the instructions in it to complete registration.' elif choice == '3': data = {':action': 'password_reset'} data['email'] = '' while not data['email']: data['email'] = raw_input('Your email address: ') code, result = self.post_to_server(data) print 'Server response (%s): %s'%(code, result) def build_post_data(self, action): # figure the data to send - the metadata plus some additional # information used by the package server meta = self.distribution.metadata data = { ':action': action, 'metadata_version' : '1.0', 'name': meta.get_name(), 'version': meta.get_version(), 'summary': meta.get_description(), 'home_page': meta.get_url(), 'author': meta.get_contact(), 'author_email': meta.get_contact_email(), 'license': meta.get_licence(), 'description': meta.get_long_description(), 'keywords': meta.get_keywords(), 'platform': meta.get_platforms(), } if hasattr(meta, 'classifiers'): data['classifiers'] = meta.get_classifiers() return data def post_to_server(self, data, auth=None): ''' Post a query to the server, and return a string response. ''' # Build up the MIME payload for the urllib2 POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary end_boundary = sep_boundary + '--' body = StringIO.StringIO() for key, value in data.items(): # handle multiple entries for the same name if type(value) != type([]): value = [value] for value in value: value = str(value) body.write(sep_boundary) body.write('\nContent-Disposition: form-data; name="%s"'%key) body.write("\n\n") body.write(value) if value and value[-1] == '\r': body.write('\n') # write an extra newline (lurve Macs) body.write(end_boundary) body.write("\n") body = body.getvalue() # build the Request headers = { 'Content-type': 'multipart/form-data; boundary=%s'%boundary, 'Content-length': str(len(body)) } req = urllib2.Request(self.repository, body, headers) # handle HTTP and include the Basic Auth handler opener = urllib2.build_opener( urllib2.HTTPBasicAuthHandler(password_mgr=auth) ) data = '' try: result = opener.open(req) except urllib2.HTTPError, e: if self.verbose: data = e.fp.read() result = e.code, e.msg except urllib2.URLError, e: result = 500, str(e) else: if self.verbose: data = result.read() result = 200, 'OK' if self.verbose: print '-'*75, data, '-'*75 return result From montanaro@users.sourceforge.net Fri Jan 3 16:26:25 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 03 Jan 2003 08:26:25 -0800 Subject: [Python-checkins] python/dist/src README,1.163,1.164 Message-ID: <E18UUeP-0006hZ-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv25733 Modified Files: README Log Message: qualify known Solaris versions related to the binutils breakage. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.163 retrieving revision 1.164 diff -C2 -d -r1.163 -r1.164 *** README 3 Jan 2003 16:17:08 -0000 1.163 --- README 3 Jan 2003 16:26:23 -0000 1.164 *************** *** 272,277 **** -zcombreloc option which creates broken shared libraries on Solaris. binutils 2.12 works, and the binutils maintainers ! are aware of the problem. Binutils 2.13.1 only partially fixed ! things. It appears that 2.13.2 solves the problem completely. When the dynamic loader complains about errors finding shared --- 272,280 ---- -zcombreloc option which creates broken shared libraries on Solaris. binutils 2.12 works, and the binutils maintainers ! are aware of the problem. Binutils 2.13.1 only partially ! fixed things. It appears that 2.13.2 solves the problem ! completely. This problem is known to occur with Solaris 2.7 ! and 2.8, but may also affect earlier and later versions of the ! OS. When the dynamic loader complains about errors finding shared From gvanrossum@users.sourceforge.net Fri Jan 3 16:33:53 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 03 Jan 2003 08:33:53 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.594,1.595 Message-ID: <E18UUld-0007hy-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29601 Modified Files: NEWS Log Message: Mention that imaplib now supports SSL -- this wasn't noted before. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.594 retrieving revision 1.595 diff -C2 -d -r1.594 -r1.595 *** NEWS 3 Jan 2003 03:30:21 -0000 1.594 --- NEWS 3 Jan 2003 16:33:49 -0000 1.595 *************** *** 553,556 **** --- 553,558 ---- ------- + - imaplib.py now supports SSL (Tino Lange and Piers Lauder). + - Freeze's modulefinder.py has been moved to the standard library; slightly improved so it will issue less false missing submodule From guido@python.org Fri Jan 3 16:34:49 2003 From: guido@python.org (Guido van Rossum) Date: Fri, 03 Jan 2003 11:34:49 -0500 Subject: [Python-checkins] python/dist/src/Lib/distutils dist.py,1.60,1.61 In-Reply-To: Your message of "03 Jan 2003 16:56:48 +0100." <65t6xm4f.fsf@python.net> References: <E18UTge-0006M9-00@sc8-pr-cvs1.sourceforge.net> <65t6xm4f.fsf@python.net> Message-ID: <200301031634.h03GYnt13349@odiug.zope.com> > Is PEP 301 accepted? I don't know or care much about this, but I've given it a +0; I presume that means yes. --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one@users.sourceforge.net Fri Jan 3 16:46:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 08:46:56 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime doc.txt,1.80,1.81 Message-ID: <E18UUyG-0000ti-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv2958 Modified Files: doc.txt Log Message: To save pointless duplicate work, I won't maintain the plain-text version of the datetime docs anymore. Index: doc.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v retrieving revision 1.80 retrieving revision 1.81 diff -C2 -d -r1.80 -r1.81 *** doc.txt 2 Jan 2003 21:17:19 -0000 1.80 --- doc.txt 3 Jan 2003 16:46:53 -0000 1.81 *************** *** 1,2 **** --- 1,14 ---- + ************************************************************************** + !!! THIS FILE IS NO LONGER MAINTAINED !!! + ************************************************************************** + + When Python 2.3 is released, datetime docs will be in Python's Library + Reference Manual. Before then, you can browse the development docs: + + http://www.python.org/dev/doc/devel/lib/module-datetime.html + ************************************************************************** + + + TODO/OPEN ========= From akuchling@users.sourceforge.net Fri Jan 3 16:52:29 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Fri, 03 Jan 2003 08:52:29 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.100,1.101 Message-ID: <E18UV3d-0001bE-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv6023 Modified Files: whatsnew23.tex Log Message: Write PEP 301 section Mention difference between 2.2.2 and 2.3 True and False Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -d -r1.100 -r1.101 *** whatsnew23.tex 3 Jan 2003 16:24:28 -0000 1.100 --- whatsnew23.tex 3 Jan 2003 16:52:27 -0000 1.101 *************** *** 544,548 **** A Boolean type was added to Python 2.3. Two new constants were added to the \module{__builtin__} module, \constant{True} and ! \constant{False}. The type object for this new type is named \class{bool}; the constructor for it takes any Python value and converts it to \constant{True} or \constant{False}. --- 544,553 ---- A Boolean type was added to Python 2.3. Two new constants were added to the \module{__builtin__} module, \constant{True} and ! \constant{False}. (\constant{True} and ! \constant{False} constants were added to the built-ins ! in Python 2.2.2, but the 2.2.2 versions simply have integer values of ! 1 and 0 and aren't a different type.) ! ! The type object for this new type is named \class{bool}; the constructor for it takes any Python value and converts it to \constant{True} or \constant{False}. *************** *** 705,709 **** \section{PEP 301: Package Index and Metadata for Distutils\label{section-pep301}} ! XXX This section needs to be written. \begin{seealso} --- 710,746 ---- \section{PEP 301: Package Index and Metadata for Distutils\label{section-pep301}} ! Support for the long-requested Python catalog makes its first ! appearance in 2.3. ! ! The core component is the new Distutil \samp{register} command. ! Running \code{python setup.py register} will collect up the metadata ! describing a package, such as its name, version, maintainer, ! description, \&c., and sends it to a central catalog server. ! Currently the catalog can be browsed at ! \url{http://www.amk.ca/cgi-bin/pypi.cgi}, but it will move to ! some hostname in the \code{python.org} domain before the final version ! of 2.3 is released. ! ! To make the catalog a bit more useful, a new optional ! \samp{classifiers} keyword argument has been added to the Distutils ! \function{setup()} function. A list of ! \citetitle[http://www.tuxedo.org/\%7Eesr/trove/]{Trove}-style strings can be supplied to help classify the software. ! ! Here's an example \file{setup.py} with classifiers: ! ! \begin{verbatim} ! setup (name = "Quixote", ! version = "0.5.1", ! description = "A highly Pythonic Web application framework", ! ... ! classifiers= ['Topic :: Internet :: WWW/HTTP :: Dynamic Content', ! 'Environment :: No Input/Output (Daemon)', ! 'Intended Audience :: Developers'], ! ... ! ) ! \end{verbatim} ! ! The full list of classifiers can be obtained by running ! \code{python setup.py register --list-classifiers}. \begin{seealso} From nnorwitz@users.sourceforge.net Fri Jan 3 18:02:01 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 03 Jan 2003 10:02:01 -0800 Subject: [Python-checkins] python/dist/src/Lib macpath.py,1.42,1.43 ntpath.py,1.53,1.54 os2emxpath.py,1.8,1.9 posixpath.py,1.56,1.57 Message-ID: <E18UW8v-0001is-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5625/Lib Modified Files: macpath.py ntpath.py os2emxpath.py posixpath.py Log Message: Fix SF #659228, 'realpath' function missing from os.path Also added realpath = abspath for os2emx, similar to windows/mac which also don't really implement realpath. Backport candidate, I think? Index: macpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/macpath.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** macpath.py 31 Dec 2002 13:11:53 -0000 1.42 --- macpath.py 3 Jan 2003 18:01:55 -0000 1.43 *************** *** 8,12 **** "getatime","getctime", "islink","exists","isdir","isfile", "walk","expanduser","expandvars","normpath","abspath", ! "supports_unicode_filenames"] # Normalize the case of a pathname. Dummy in Posix, but <s>.lower() here. --- 8,12 ---- "getatime","getctime", "islink","exists","isdir","isfile", "walk","expanduser","expandvars","normpath","abspath", ! "realpath","supports_unicode_filenames"] # Normalize the case of a pathname. Dummy in Posix, but <s>.lower() here. Index: ntpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ntpath.py,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** ntpath.py 31 Dec 2002 13:11:53 -0000 1.53 --- ntpath.py 3 Jan 2003 18:01:56 -0000 1.54 *************** *** 14,18 **** "getatime","getctime", "islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath","splitunc", ! "supports_unicode_filenames"] # Normalize the case of a pathname and map slashes to backslashes. --- 14,18 ---- "getatime","getctime", "islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath","splitunc", ! "realpath","supports_unicode_filenames"] # Normalize the case of a pathname and map slashes to backslashes. Index: os2emxpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os2emxpath.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** os2emxpath.py 31 Dec 2002 13:11:54 -0000 1.8 --- os2emxpath.py 3 Jan 2003 18:01:57 -0000 1.9 *************** *** 13,17 **** "getatime","getctime", "islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath","splitunc", ! "supports_unicode_filenames"] # Normalize the case of a pathname and map slashes to backslashes. --- 13,17 ---- "getatime","getctime", "islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath","splitunc", ! "realpath","supports_unicode_filenames"] # Normalize the case of a pathname and map slashes to backslashes. *************** *** 405,408 **** --- 405,411 ---- path = join(os.getcwd(), path) return normpath(path) + + # realpath is a no-op on systems without islink support + realpath = abspath supports_unicode_filenames = False Index: posixpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/posixpath.py,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** posixpath.py 31 Dec 2002 13:11:54 -0000 1.56 --- posixpath.py 3 Jan 2003 18:01:57 -0000 1.57 *************** *** 18,22 **** "getatime","getctime","islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath", ! "samefile","sameopenfile","samestat","supports_unicode_filenames"] # Normalize the case of a pathname. Trivial in Posix, string.lower on Mac. --- 18,23 ---- "getatime","getctime","islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath", ! "samefile","sameopenfile","samestat", ! "realpath","supports_unicode_filenames"] # Normalize the case of a pathname. Trivial in Posix, string.lower on Mac. From gward@users.sourceforge.net Fri Jan 3 18:02:19 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Fri, 03 Jan 2003 10:02:19 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.595,1.596 Message-ID: <E18UW9D-0001lT-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv6745 Modified Files: NEWS Log Message: Mention ossaudiodev. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.595 retrieving revision 1.596 diff -C2 -d -r1.595 -r1.596 *** NEWS 3 Jan 2003 16:33:49 -0000 1.595 --- NEWS 3 Jan 2003 18:02:15 -0000 1.596 *************** *** 550,553 **** --- 550,558 ---- bug #623464. + - The linuxaudiodev module is now deprecated; it is being replaced by + ossaudiodev. The interface has been extended to cover a lot more of + OSS (see www.opensound.com), including most DSP ioctls and the + OSS mixer API. Documentation forthcoming in 2.3a2. + Library ------- From gward@users.sourceforge.net Fri Jan 3 18:03:24 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Fri, 03 Jan 2003 10:03:24 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.101,1.102 Message-ID: <E18UWAG-0001vB-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv7343 Modified Files: whatsnew23.tex Log Message: Spread the blame (err, I mean credit) for ossaudiodev around a bit. Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -d -r1.101 -r1.102 *** whatsnew23.tex 3 Jan 2003 16:52:27 -0000 1.101 --- whatsnew23.tex 3 Jan 2003 18:03:21 -0000 1.102 *************** *** 1390,1394 **** used on platforms other than Linux, and the interface has also been tidied and brought up to date in various ways. (Contributed by Greg ! Ward.) \item The parser objects provided by the \module{pyexpat} module --- 1390,1394 ---- used on platforms other than Linux, and the interface has also been tidied and brought up to date in various ways. (Contributed by Greg ! Ward and Nicholas FitzRoy-Dale.) \item The parser objects provided by the \module{pyexpat} module From nnorwitz@users.sourceforge.net Fri Jan 3 18:12:32 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 03 Jan 2003 10:12:32 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.596,1.597 Message-ID: <E18UWJ6-000341-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv11566/Misc Modified Files: NEWS Log Message: Fix SF #659228, 'realpath' function missing from os.path Also added realpath = abspath for os2emx, similar to windows/mac which also don't really implement realpath. Backport candidate, I think? Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.596 retrieving revision 1.597 diff -C2 -d -r1.596 -r1.597 *** NEWS 3 Jan 2003 18:02:15 -0000 1.596 --- NEWS 3 Jan 2003 18:12:28 -0000 1.597 *************** *** 39,43 **** ------- ! TBD Tools/Demos --- 39,46 ---- ------- ! - realpath is now exported when doing from poxixpath import *. ! It is also exported for ntpath, macpath, and os2emxpath. ! See SF bug #659228. ! Tools/Demos From loewis@users.sourceforge.net Fri Jan 3 19:16:17 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Fri, 03 Jan 2003 11:16:17 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.597,1.598 Message-ID: <E18UXIn-0001qH-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv6773/Misc Modified Files: NEWS Log Message: Allow PyFile_GetLine() to return Unicode objects. Fixes #660165. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.597 retrieving revision 1.598 diff -C2 -d -r1.597 -r1.598 *** NEWS 3 Jan 2003 18:12:28 -0000 1.597 --- NEWS 3 Jan 2003 19:16:12 -0000 1.598 *************** *** 13,16 **** --- 13,18 ---- ----------------- + - raw_input can now return Unicode objects. + - List objects' sort() method now accepts None as the comparison function. Passing None is semantically identical to calling sort() with no From loewis@users.sourceforge.net Fri Jan 3 19:16:18 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Fri, 03 Jan 2003 11:16:18 -0800 Subject: [Python-checkins] python/dist/src/Objects fileobject.c,2.174,2.175 Message-ID: <E18UXIo-0001qW-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv6773/Objects Modified Files: fileobject.c Log Message: Allow PyFile_GetLine() to return Unicode objects. Fixes #660165. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.174 retrieving revision 2.175 diff -C2 -d -r2.174 -r2.175 *** fileobject.c 29 Dec 2002 16:33:11 -0000 2.174 --- fileobject.c 3 Jan 2003 19:16:14 -0000 2.175 *************** *** 1213,1217 **** Py_DECREF(reader); Py_DECREF(args); ! if (result != NULL && !PyString_Check(result)) { Py_DECREF(result); result = NULL; --- 1213,1218 ---- Py_DECREF(reader); Py_DECREF(args); ! if (result != NULL && !PyString_Check(result) && ! !PyUnicode_Check(result)) { Py_DECREF(result); result = NULL; *************** *** 1241,1244 **** --- 1242,1267 ---- } } + #ifdef Py_USING_UNICODE + if (n < 0 && result != NULL && PyUnicode_Check(result)) { + Py_UNICODE *s = PyUnicode_AS_UNICODE(result); + int len = PyUnicode_GET_SIZE(result); + if (len == 0) { + Py_DECREF(result); + result = NULL; + PyErr_SetString(PyExc_EOFError, + "EOF when reading a line"); + } + else if (s[len-1] == '\n') { + if (result->ob_refcnt == 1) + PyUnicode_Resize(&result, len-1); + else { + PyObject *v; + v = PyUnicode_FromUnicode(s, len-1); + Py_DECREF(result); + result = v; + } + } + } + #endif return result; } From doerwalter@users.sourceforge.net Fri Jan 3 19:33:20 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 03 Jan 2003 11:33:20 -0800 Subject: [Python-checkins] python/dist/src/Lib mimetypes.py,1.23,1.24 Message-ID: <E18UXZI-0003jD-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14139 Modified Files: mimetypes.py Log Message: Fix read_mime_types() so that it returns a dict as documented. This fixes a bug reported as http://www.python.org/sf/661630, which was introduced in the patch http://www.python.org/sf/554192. Index: mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimetypes.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** mimetypes.py 6 Sep 2002 16:15:58 -0000 1.23 --- mimetypes.py 3 Jan 2003 19:33:17 -0000 1.24 *************** *** 316,321 **** return None db = MimeTypes() ! db.readfp(f) ! return db.types_map --- 316,321 ---- return None db = MimeTypes() ! db.readfp(f, True) ! return db.types_map[True] From loewis@users.sourceforge.net Fri Jan 3 20:39:38 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Fri, 03 Jan 2003 12:39:38 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.108,1.109 Message-ID: <E18UYbS-0002wa-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv11075 Modified Files: Makefile.pre.in Log Message: Use RUNSHARED for python invocations. Fixes #661408. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.108 retrieving revision 1.109 diff -C2 -d -r1.108 -r1.109 *** Makefile.pre.in 1 Jan 2003 20:07:42 -0000 1.108 --- Makefile.pre.in 3 Jan 2003 20:39:29 -0000 1.109 *************** *** 839,843 **** # This installs IDLE idleinstall: ! SRCDIR=$(srcdir) \ ./$(BUILDPYTHON) $(srcdir)/Tools/idle/setup.py install \ --check-tkinter \ --- 839,843 ---- # This installs IDLE idleinstall: ! SRCDIR=$(srcdir) $(RUNSHARED) \ ./$(BUILDPYTHON) $(srcdir)/Tools/idle/setup.py install \ --check-tkinter \ *************** *** 848,852 **** # This installs a few of the useful scripts in Tools/scripts scriptsinstall: ! SRCDIR=$(srcdir) \ ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \ --prefix=$(prefix) \ --- 848,852 ---- # This installs a few of the useful scripts in Tools/scripts scriptsinstall: ! SRCDIR=$(srcdir) $(RUNSHARED) \ ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/setup.py install \ --prefix=$(prefix) \ From doerwalter@users.sourceforge.net Fri Jan 3 21:02:39 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 03 Jan 2003 13:02:39 -0800 Subject: [Python-checkins] python/dist/src/Lib mimetypes.py,1.24,1.25 Message-ID: <E18UYxj-0005df-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv21579/Lib Modified Files: mimetypes.py Log Message: Pass the strict argument from read() on to readfp(), so the file content ends up in the correct dict. Index: mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimetypes.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** mimetypes.py 3 Jan 2003 19:33:17 -0000 1.24 --- mimetypes.py 3 Jan 2003 21:02:36 -0000 1.25 *************** *** 193,197 **** """ fp = open(filename) ! self.readfp(fp) fp.close() --- 193,197 ---- """ fp = open(filename) ! self.readfp(fp, strict) fp.close() From doerwalter@users.sourceforge.net Fri Jan 3 21:06:49 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 03 Jan 2003 13:06:49 -0800 Subject: [Python-checkins] python/dist/src/Lib mimetypes.py,1.25,1.26 Message-ID: <E18UZ1l-00069q-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv23548/Lib Modified Files: mimetypes.py Log Message: Remove a list comprehension, because a loop over the list is done afterwards anyway, so what the list comp does can be done in the loop. Index: mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimetypes.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** mimetypes.py 3 Jan 2003 21:02:36 -0000 1.25 --- mimetypes.py 3 Jan 2003 21:06:46 -0000 1.26 *************** *** 216,222 **** continue type, suffixes = words[0], words[1:] - suffixes = [ '.' + suff for suff in suffixes ] for suff in suffixes: ! self.add_type(type, suff, strict) def guess_type(url, strict=True): --- 216,221 ---- continue type, suffixes = words[0], words[1:] for suff in suffixes: ! self.add_type(type, '.' + suff, strict) def guess_type(url, strict=True): From gward@users.sourceforge.net Fri Jan 3 21:10:00 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Fri, 03 Jan 2003 13:10:00 -0800 Subject: [Python-checkins] python/dist/src/Doc/ext newtypes.tex,1.19,1.20 Message-ID: <E18UZ4q-0006QA-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/ext In directory sc8-pr-cvs1:/tmp/cvs-serv24667 Modified Files: newtypes.tex Log Message: Grammatical fix: change possessive "it's" to "its". Index: newtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/newtypes.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** newtypes.tex 17 Dec 2002 23:27:41 -0000 1.19 --- newtypes.tex 3 Jan 2003 21:09:57 -0000 1.20 *************** *** 199,203 **** \end{verbatim} ! The \member{ob_size} field of the header is not used; it's presence in the type structure is a historical artifact that is maintained for binary compatibility with extension modules compiled for older --- 199,203 ---- \end{verbatim} ! The \member{ob_size} field of the header is not used; its presence in the type structure is a historical artifact that is maintained for binary compatibility with extension modules compiled for older *************** *** 443,447 **** \member{tp_repr} handler described above is to \function{repr()}; that is, it is called when Python code calls \function{str()} on an ! instance of your object. It's implementation is very similar to the \member{tp_repr} function, but the resulting string is intended for human consumption. If \member{tp_str} is not specified, the --- 443,447 ---- \member{tp_repr} handler described above is to \function{repr()}; that is, it is called when Python code calls \function{str()} on an ! instance of your object. Its implementation is very similar to the \member{tp_repr} function, but the resulting string is intended for human consumption. If \member{tp_str} is not specified, the *************** *** 881,885 **** These functions provide support for the iterator protocol. Any object ! which wishes to support iteration over it's contents (which may be generated during iteration) must implement the \code{tp_iter} handler. Objects which are returned by a \code{tp_iter} handler must --- 881,885 ---- These functions provide support for the iterator protocol. Any object ! which wishes to support iteration over its contents (which may be generated during iteration) must implement the \code{tp_iter} handler. Objects which are returned by a \code{tp_iter} handler must From gward@users.sourceforge.net Fri Jan 3 21:22:10 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Fri, 03 Jan 2003 13:22:10 -0800 Subject: [Python-checkins] python/dist/src/Objects xxobject.c,2.21,2.22 Message-ID: <E18UZGc-0007az-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv29184 Modified Files: xxobject.c Log Message: Grammatical fix in comment. Index: xxobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/xxobject.c,v retrieving revision 2.21 retrieving revision 2.22 diff -C2 -d -r2.21 -r2.22 *** xxobject.c 17 Jul 2002 16:30:38 -0000 2.21 --- xxobject.c 3 Jan 2003 21:22:08 -0000 2.22 *************** *** 3,7 **** If your objects will be called foobar, start by copying this file to foobarobject.c, changing all occurrences of xx to foobar and all ! occurrences of Xx by Foobar. You will probably want to delete all references to 'x_attr' and add your own types of attributes instead. Maybe you want to name your local variables other than --- 3,7 ---- If your objects will be called foobar, start by copying this file to foobarobject.c, changing all occurrences of xx to foobar and all ! occurrences of Xx to Foobar. You will probably want to delete all references to 'x_attr' and add your own types of attributes instead. Maybe you want to name your local variables other than From tim_one@users.sourceforge.net Fri Jan 3 22:27:00 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 14:27:00 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib tzinfo-examples.py,1.2,1.3 Message-ID: <E18UaHM-00059M-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv19643/python/Doc/lib Modified Files: tzinfo-examples.py Log Message: Replaced the flawed "local time" example tzinfo class with the guts of Guido's later Local.py (from the datetime sandbox). Index: tzinfo-examples.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/tzinfo-examples.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** tzinfo-examples.py 2 Jan 2003 21:28:07 -0000 1.2 --- tzinfo-examples.py 3 Jan 2003 22:26:57 -0000 1.3 *************** *** 3,6 **** --- 3,8 ---- ZERO = timedelta(0) + # A UTC class. + class UTC(tzinfo): """UTC""" *************** *** 15,23 **** return ZERO class FixedOffset(tzinfo): """Fixed offset in minutes east from UTC.""" def __init__(self, offset, name): ! self.__offset = offset self.__name = name --- 17,31 ---- return ZERO + utc = UTC() + + # A class building tzinfo objects for fixed-offset time zones. + # Note that FixedOffset(0, "UTC") is a different way to build a + # UTC tzinfo object. + class FixedOffset(tzinfo): """Fixed offset in minutes east from UTC.""" def __init__(self, offset, name): ! self.__offset = timdelta(minutes = offset) self.__name = name *************** *** 31,52 **** return ZERO ! import time ! class LocalTime(tzinfo): ! """Local time as defined by the operating system.""" ! def _isdst(self, dt): ! t = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, ! -1, -1, -1) ! # XXX This may fail for years < 1970 or >= 2038 ! t = time.localtime(time.mktime(t)) ! return t.tm_isdst > 0 def utcoffset(self, dt): if self._isdst(dt): ! return timedelta(seconds=-time.timezone) else: ! return timedelta(seconds=-time.altzone) def tzname(self, dt): ! return time.tzname[self._isdst(dt)] --- 39,78 ---- return ZERO ! # A class capturing the platform's idea of local time. ! import time as _time ! STDOFFSET = timedelta(seconds = -_time.timezone) ! if _time.daylight: ! DSTOFFSET = timedelta(seconds = -_time.altzone) ! else: ! DSTOFFSET = STDOFFSET ! ! DSTDIFF = DSTOFFSET - STDOFFSET ! ! class LocalTimezone(tzinfo): def utcoffset(self, dt): if self._isdst(dt): ! return DSTOFFSET else: ! return STDOFFSET ! ! def dst(self, dt): ! if self._isdst(dt): ! return DSTDIFF ! else: ! return ZERO def tzname(self, dt): ! return _time.tzname[self._isdst(dt)] ! ! def _isdst(self, dt): ! tt = (dt.year, dt.month, dt.day, ! dt.hour, dt.minute, dt.second, ! dt.weekday(), 0, -1) ! stamp = _time.mktime(tt) ! tt = _time.localtime(stamp) ! return tt.tm_isdst > 0 ! ! Local = LocalTimezone() From tim_one@users.sourceforge.net Fri Jan 3 22:35:27 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 14:35:27 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.598,1.599 Message-ID: <E18UaPX-00063r-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv23141/python/Misc Modified Files: NEWS Log Message: Remark about datetime tzinfo examples. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.598 retrieving revision 1.599 diff -C2 -d -r1.598 -r1.599 *** NEWS 3 Jan 2003 19:16:12 -0000 1.598 --- NEWS 3 Jan 2003 22:35:24 -0000 1.599 *************** *** 33,40 **** as 0 instead). ! The tzinfo methods utcoffset() and dst() must return a timedelta object ! (or None) now. In 2.3a1 they could also return an int or long, but that ! was an unhelpfully redundant leftover from an earlier version wherein they couldn't return a timedelta. TOOWTDI. Library --- 33,43 ---- as 0 instead). ! The tzinfo methods utcoffset() and dst() must return a timedelta object ! (or None) now. In 2.3a1 they could also return an int or long, but that ! was an unhelpfully redundant leftover from an earlier version wherein they couldn't return a timedelta. TOOWTDI. + + The example tzinfo class for local time had a bug. It was replaced + by a later example coded by Guido. Library From jackjansen@users.sourceforge.net Fri Jan 3 23:53:48 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 03 Jan 2003 15:53:48 -0800 Subject: [Python-checkins] python/dist/src/Mac ReadMe,1.45.2.1,1.45.2.2 Message-ID: <E18UbdM-0004fY-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Mac In directory sc8-pr-cvs1:/tmp/cvs-serv17938 Modified Files: Tag: r23a1-branch ReadMe Log Message: Updated for 2.3a1 Index: ReadMe =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/ReadMe,v retrieving revision 1.45.2.1 retrieving revision 1.45.2.2 diff -C2 -d -r1.45.2.1 -r1.45.2.2 *** ReadMe 2 Jan 2003 23:09:35 -0000 1.45.2.1 --- ReadMe 3 Jan 2003 23:53:45 -0000 1.45.2.2 *************** *** 1,18 **** ! How to install Python 2.2.1 on your Macintosh ! --------------------------------------------- ! This is a MacPython that can run on classic MacOS (from 8.1 ! onwards) and natively on MacOSX. The installer tries to work out whether you can ! use the Carbon version or not. For Mac OS X users: this version of Python ! does not run from the command line, it is a pure "Mac only" app. Use the standard ! unix Python from the commandline, the two Pythons will be merged in the future. ! You should definitely read the Relnotes file too, and the section below about ! toolbox module reorganization. You should also read :Misc:NEWS, which lists ! the general (non-mac-dependent) new features of this Python release. ! A special note about the active installer: do not background it, it may hang ! your machine. This is a general problem with Vise active installers, MindVision ! are working on it. ------ --- 1,24 ---- ! How to install MacPython-OS9 2.3a1 on your Macintosh ! ---------------------------------------------------- ! This is a MacPython that can run on Mac OS 8.6 with CarbonLib ! installed, Mac OS 9 and Mac OS X. It is the direct successor of MacPython 2.2. ! For Mac OS X users: you are probably better off with the normal unix distribution ! of Python. That version also runs from the commandline, and if you do a framework ! build it will contain all the functionality of this version too. A prebuilt ! version will be available starting with the beta distributions. ! If you are upgrading from a previous MacPython you should read :Misc:NEWS, ! which lists the new features of this Python release. As of this release ! the Mac-specific release notes have been moved to the "Mac" section of ! the general NEWS file. ! ! Two changes since 2.2 deserve special mention: ! - Most Mac-specific modules have moved to :Lib:plat-mac. :Mac:Lib now contains ! only modules that are not shared with MacPython-OSX 2.3. ! - macfs is now a pure Python wrapper module around various modules in the ! Carbon package. For 2.3a1 only this wrapping is incomplete: fsspec.SetDates() ! does not work yet. If you encounter any other problems please report them. ------ *************** *** 29,36 **** now. The documentation is in HTML format, start with index.html. ! This installer installs MacPython for classic PPC MacOS, MacPython for Carbon ! (OS X, OS 9 or OS 8 with CarbonLib installed) or both, depending on your ! configuration. By selecting custom install you can bypass these tests and ! install what you want. If you want 68k support you will have get MacPython 1.5.2. --- 35,40 ---- now. The documentation is in HTML format, start with index.html. ! If you want a MacPython that runs on systems without Carbon support (8.1 ! up to 8.6 without CarbonLib) you should get MacPython 2.2.2. If you want 68k support you will have get MacPython 1.5.2. *************** *** 40,66 **** The optional parts in this distribution are ! - TK+PIL: Tkinter and support modules, plus Imaging, the Python image ! manipulation package (allows you to read, write and display images and ! do lots of operations on them). ! For Carbon MacPython you only get PIL: there is no Tcl/Tk for Carbon yet. ! This is the reason Classic MacPython is also installed on MacOSX: it ! allows you to run Tkinter applications, albeit in the Classic box. - img: another imaging package. Has more file format support and is faster than imaging, but has only limited operations on images. There is a bridge between the packages. - Numeric: the LLNL Numeric Python extension. All sorts of nifty operations ! on matrices and such. This is the most recent version from the ! sourceforge archive. ! Numeric has moved from Extensions to :Lib:site-python, by the way, ! see the release notes. - Developers kit: all header files and some tools and sample projects to get you started on writing Python extensions if you have CodeWarrior. All these except the DevKit are installed with Easy Install. ! After the installer finishes it automatically launches the appropriate ! ConfigurePython applet, to finish configuration of your Python. If you ! run MacOS9 or later (or 8 with CarbonLib installed) you can switch ! back and forth between the classic and Carbon versions of Python by ! running either ConfigurePythonClassic or ConfigurePythonCarbon. Moving your Python installation after installing is generally not a --- 44,61 ---- The optional parts in this distribution are ! - PIL: the Python image manipulation package (allows you to read, write ! and display images and do lots of operations on them). Tkinter is no ! longer supported, a working Carbon version is Tk is not available. - img: another imaging package. Has more file format support and is faster than imaging, but has only limited operations on images. There is a bridge between the packages. - Numeric: the LLNL Numeric Python extension. All sorts of nifty operations ! on matrices and such. This is version 22. - Developers kit: all header files and some tools and sample projects to get you started on writing Python extensions if you have CodeWarrior. All these except the DevKit are installed with Easy Install. ! After the installer finishes it automatically launches the ! ConfigurePython applet, to finish configuration of your Python. Moving your Python installation after installing is generally not a *************** *** 132,136 **** not having a preference file: the symptom is failing to import all sorts of standard modules. If you remove your per-user Python preference files ! (in ~/Library/Preferences) and then run PythonIntpreter once everything should be fine. --- 127,131 ---- not having a preference file: the symptom is failing to import all sorts of standard modules. If you remove your per-user Python preference files ! (in ~/Library/Preferences) and then run PythonInterpreter once everything should be fine. *************** *** 138,148 **** ------------ ! Up to three items are installed in the system folder: the interpreter shared ! libraries PythonCore and PythonCoreCarbon live in the Extensions ! folder and the "Python 2.2.1 Preferences" file in the Python subfolder in the Preferences folder. All the rest of Python lives in the folder you installed in. ! On OSX the libraries are installed in /Library/CFMSupport. The ConfigurePython applets will complain if you have no right to create the libraries there (you need Admin privileges). This has one consequence: you will not be able to --- 133,143 ---- ------------ ! Up to three items are installed in the MacOS 8 or 9 system folder: the interpreter ! shared library PythonCore lives in the Extensions ! folder and the "Python 2.3a1 Preferences" file in the Python subfolder in the Preferences folder. All the rest of Python lives in the folder you installed in. ! On OSX the library is installed in /Library/CFMSupport. The ConfigurePython applets will complain if you have no right to create the libraries there (you need Admin privileges). This has one consequence: you will not be able to *************** *** 156,165 **** Start off at Mac:Demo:index.html. Read at least the first few sections. ! There are also some interesting files in the "Relnotes" folder that may ! contain useful information. There is also a first stab at documentation ! (plus examples) in the Mac:Demo folder. The toplevel Demo folder has ! machine-independent demos. ! The Mac:Lib:test folder also has some programs that show simple ! capabilities of various modules. The ":Mac:scripts" folder has some sample scripts. Some are useful, --- 151,156 ---- Start off at Mac:Demo:index.html. Read at least the first few sections. ! There is also a first stab at documentation (plus examples) in the ! Mac:Demo folder. The toplevel Demo folder has machine-independent demos. The ":Mac:scripts" folder has some sample scripts. Some are useful, *************** *** 188,196 **** are lost and you have to set them again. ! After you are satisfied that 2.2.1 works as expected you can trash anything in the system folder that has "python" in the name and not ! "2.2.1". ! The ConfigurePython... applets will try to detect incompatible preferences files and offer to remove them. This means that re-running ConfigurePython after a second install of the same MacPython version --- 179,187 ---- are lost and you have to set them again. ! After you are satisfied that 2.3a1 works as expected you can trash anything in the system folder that has "python" in the name and not ! "2.3a1". ! The ConfigurePython applet will try to detect incompatible preferences files and offer to remove them. This means that re-running ConfigurePython after a second install of the same MacPython version From jackjansen@users.sourceforge.net Fri Jan 3 23:53:55 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 03 Jan 2003 15:53:55 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo building.html,1.33,1.33.4.1 Message-ID: <E18UbdT-0004gB-00@sc8-pr-cvs1.sourceforge.net> Update of /cvsroot/python/python/dist/src/Mac/Demo In directory sc8-pr-cvs1:/tmp/cvs-serv17970 Modified Files: Tag: r23a1-branch building.html Log Message: Updated for 2.3a1 Index: building.html =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/building.html,v retrieving revision 1.33 retrieving revision 1.33.4.1 diff -C2 -d -r1.33 -r1.33.4.1 *** building.html 30 Jan 2002 10:42:59 -0000 1.33 --- building.html 3 Jan 2003 23:53:52 -0000 1.33.4.1 *************** *** 1,11 **** <HTML> <HEAD> ! <TITLE>Building Mac Python from source !

Building Mac Python from source


! This document explains how to build MacPython from source. This is necessary if you want to make modifications to the Python core. Building Python is not something to be undertaken lightly, you need a reasonable --- 1,11 ---- ! Building MacPython-OS9 from source !

Building MacPython-OS9 from source


! This document explains how to build MacPython-OS9 from source. This is necessary if you want to make modifications to the Python core. Building Python is not something to be undertaken lightly, you need a reasonable *************** *** 24,31 **** released after MacPython. The MacPython homepage will ! hopefully have updated instructions in that case. These instructions are for CW7. ! I am very interested in feedback on this document, send your comments to the Mac Python Special --- 24,32 ---- released after MacPython. The MacPython homepage will ! hopefully have updated instructions in that case. These instructions are for CW7, ! it is rumoured you may encounter some problems with newer versions of CodeWarrior. ! I am interested in feedback on this document, send your comments to the Mac Python Special *************** *** 78,86 **** - - Build first the Tcl library, then - SimpleTcl (test it by typing ls -l in the window you get) - then the Tk library, then SimpleTk (which can again be tested with - ls -l). If this all worked you are all set to try - building Python. -

The organization of the Python source tree

--- 148,151 ---- *************** *** 213,217 ****
Lib:lib-dynload !
This is where the Classic and Carbon dynamically-loaded plugin modules live.
Objects --- 179,187 ----
Lib:lib-dynload !
This is where the dynamically-loaded plugin modules live. ! !
Lib:plat-mac !
This is where most of the Mac-specific modules live. The modules here ! are available both in MacPython-OS9 and MacPython-OSX.
Objects *************** *** 236,240 **** ! All the mac-specific stuff lives in the Mac folder:
Build --- 206,210 ----
! The mac-specific stuff lives in the Mac folder:
Build *************** *** 242,246 **** libraries, shared libraries, executables and plugin modules. All the resulting binaries, except for intermedeate results, are deposited in ! the toplevel folder or the Mac:PlugIns folder (for plugin modules).
Compat --- 212,216 ---- libraries, shared libraries, executables and plugin modules. All the resulting binaries, except for intermedeate results, are deposited in ! the toplevel folder or the :Lib:lib-dynload folder (for plugin modules).
Compat *************** *** 256,262 ****
Lib !
Mac-specific standard modules. The Carbon package ! contains modules specifically needed with various MacOS toolbox ! interface modules, both for Carbon and classic PPC, despite the name.
Modules --- 226,231 ----
Lib !
MacPython-OS9 specific standard modules which are not shared with ! MacPython-OSX.
Modules *************** *** 286,295 ****
OSX !
Specific to unix-Python (also known as MachoPython) on OSX, not used ! by MacPython.
OSXResources !
Specific to unix-Python (also known as MachoPython) on OSX, not used ! by MacPython.
Python --- 255,262 ----
OSX !
Specific to MacPython-OSX, not used by MacPython-OS9.
OSXResources !
Specific to MacPython-OSX, not used by MacPython-OS9.
Python *************** *** 317,335 ****

Building the PPC interpreter

- This is different since 2.1. You are best off using the fullbuild.py - script, see
below.

! First you optionally build the external libraries with buildlibs.prj. Next, ! the projects for ! interpreter and core library are linked together, so ! building the PythonInterpreterClassic and/or PythonInterpreterCarbon target ! in PythonInterpreter.prj ! will result in everything being built. The result, however, is an "Application ! template", (filetype Atmp). If you don't use fullbuild you can manually ! turn either of these into an interpreter by copying it to PythonInterpreter ! and setting the filetype to APPL (with ResEdit or some such).

! Fullbuild does this for you, and the Atmp files is also how ConfigurePythonCarbon ! and ConfigurePythonClassic work their magic.

You will get about 100 warnings on "missing prototype" for the various module init --- 284,305 ----

Building the PPC interpreter

! First you optionally build the external libraries with buildlibs.prj.

! Then, the fullbuild script can be used to build ! everything, but you need a fully-functional interpreter before you can ! use it (and one that isn't rebuilt in the process: you cannot rebuild ! a running program). You could copy the interpreter to a different ! place and use that to run fullbuild. The PythonStandSmall.prj ! project builds an interpreter that is suited to this, and it can also come ! in handy if you need to debug things (which is easier in a static program).

! ! In case you want to build by hand, or in case the fullbuild ! script does not work, here is a breakdown of the various projects.

! ! The projects for interpreter and core library are linked together, so ! building the PythonInterpreter target ! in PythonInterpreter.prj ! will result in the whole core being built, but not the extension modules.

You will get about 100 warnings on "missing prototype" for the various module init *************** *** 337,341 **** override functions from MSL, ignore these too.

! For completeness sake here is a breakdown of the projects:

--- 307,311 ---- override functions from MSL, ignore these too.

! Here is a breakdown of the projects:

*************** *** 343,347 ****
PythonCore
The shared library that contains the bulk of the interpreter and ! its resources. It has targets for PythonCore and PythonCoreCarbon. It is a good idea to immedeately put an alias to this shared library in the Extensions folder of your system --- 313,317 ----
PythonCore
The shared library that contains the bulk of the interpreter and ! its resources. It is a good idea to immedeately put an alias to this shared library in the Extensions folder of your system *************** *** 353,361 ****
PythonInterpeter
The interpreter. This is basically a routine to call out to the ! shared library. Unlike in previous releases the same program is used for ! creating applets (for which formerly PythonApplet was used). There are 4 targets ! in here: two for the classic and carbon templates (which are normally used, and ! converted to PythonInterpreter by the ConfigurePython* applets) and two ! for PythonInterpreter in it's classic and carbon version.

Plugin projects --- 323,327 ----
PythonInterpeter
The interpreter. This is basically a routine to call out to the ! shared library.

Plugin projects *************** *** 379,394 **** BuildApplet.

-

- - The fullbuild script can be used to build - everything, but you need a fully-functional interpreter before you can - use it (and one that isn't rebuilt in the process: you cannot rebuild - a running program). You could copy the interpreter to a different - place and use that to run fullbuild. The PythonStandSmall.prj - project builds an interpreter that is suited to this, and it can also come - in handy if you need to debug things (which is easier in a static program).

- -

- You are all set now, and should read the release notes and ReadMe file from the Mac folder. --- 345,348 ---- *************** *** 412,425 **** conversion".

!

! There is one group of people for whom MacCVS is not the best choice: people with ! checkin rights to the Python repository. You will have to use MacCVS Pro ! (completely unrelated) from www.maccvs.org, because it has working SSH support. !
! ! It is a good idea to disable Quicktime Exchange in the Quicktime ! control panel. Quicktime Exchange will magically map some extensions to ! filetypes, and this can seriously hinder you if, for instance, .bmp ! is not a Windows bitmap file.

The Python sources are checked out from the main --- 366,373 ---- conversion".

! It is a good idea to disable Quicktime Exchange in the Quicktime control ! panel if you are on OS9 or before. Quicktime Exchange will magically map ! some extensions to filetypes, and this can seriously hinder you if, for ! instance, .bmp is not a Windows bitmap file.

The Python sources are checked out from the main *************** *** 436,440 **** it is probably a good idea to first build PythonStandSmall.prj, which builds a fairly minimal interpreter, and then follow the ! fullbuild instructions.

Odds and ends

--- 384,388 ---- it is probably a good idea to first build PythonStandSmall.prj, which builds a fairly minimal interpreter, and then follow the ! fullbuild instructions.

Odds and ends

*************** *** 447,451 **** library to embed Python in another program, if your program can live with using GUSI for I/O. Use PythonCore in stead of your MSL C library ! (or, at the very least, link it before the normal C library).
  • It is possible to build PPC extension --- 395,400 ---- library to embed Python in another program, if your program can live with using GUSI for I/O. Use PythonCore in stead of your MSL C library ! (or, at the very least, link it before the normal C library). Ask for help ! on PythonMac-SIG if you have problems with this.
  • It is possible to build PPC extension From jackjansen@users.sourceforge.net Fri Jan 3 23:54:03 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 03 Jan 2003 15:54:03 -0800 Subject: [Python-checkins] python/dist/src/Mac/Distributions readme.txt,1.8,1.8.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory sc8-pr-cvs1:/tmp/cvs-serv18014 Modified Files: Tag: r23a1-branch readme.txt Log Message: Updated for 2.3a1 Index: readme.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/readme.txt,v retrieving revision 1.8 retrieving revision 1.8.4.1 diff -C2 -d -r1.8 -r1.8.4.1 *** readme.txt 22 May 2002 14:30:37 -0000 1.8 --- readme.txt 3 Jan 2003 23:54:00 -0000 1.8.4.1 *************** *** 3,7 **** These notes are mainly for myself, or for whoever tries to make a MacPython ! distribution when I'm fed up with it. They were last updated for 2.2b1. - Increase fragment version number in PythonCore and PythonCoreCarbon. --- 3,7 ---- These notes are mainly for myself, or for whoever tries to make a MacPython ! distribution when I'm fed up with it. They were last updated for 2.3a1. - Increase fragment version number in PythonCore and PythonCoreCarbon. *************** *** 10,18 **** - Increase version number in _versioncheck.py - Build PythonStandSmall, run once in root folder ! - Update Relnotes, readme's, Demo:build.html ! - Make sure tkresources.rsrc is up-to-date - fullbuild everything with increase-buildno ! - Test both classic and Carbon with test.regrtest ! - Update Numeric and build/install it both with Classic and with Carbon python - Recompile OSAm and possibly other Contrib stuff - mkdistr binary.include --- 10,17 ---- - Increase version number in _versioncheck.py - Build PythonStandSmall, run once in root folder ! - Update NEWS, readme's, Demo:build.html - fullbuild everything with increase-buildno ! - Test with test.regrtest ! - Update Numeric and build/install it - Recompile OSAm and possibly other Contrib stuff - mkdistr binary.include From jackjansen@users.sourceforge.net Fri Jan 3 23:55:22 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 03 Jan 2003 15:55:22 -0800 Subject: [Python-checkins] python/dist/src/Mac/Contrib/osam OSAm.c,1.1.1.1,1.1.1.1.24.1 OSAm.prj,1.3,1.3.4.1 ScriptRunner.c,1.2,1.2.20.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Contrib/osam In directory sc8-pr-cvs1:/tmp/cvs-serv18381 Modified Files: Tag: r23a1-branch OSAm.c OSAm.prj ScriptRunner.c Log Message: Adapted for Carbon-only 2.3. Unfortunately 2 of the methods were too much work to get right, but at least the important ones are there. Index: OSAm.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Contrib/osam/OSAm.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.24.1 diff -C2 -d -r1.1.1.1 -r1.1.1.1.24.1 *** OSAm.c 18 Aug 1998 14:56:35 -0000 1.1.1.1 --- OSAm.c 3 Jan 2003 23:55:17 -0000 1.1.1.1.24.1 *************** *** 50,64 **** DescType typeCode; long dataSize = 0; ! HLock (temp.dataHandle); ! ! dataSize = GetHandleSize (temp.dataHandle); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), dataSize); ! ! AEDisposeDesc (&temp); if (!result) --- 50,62 ---- DescType typeCode; long dataSize = 0; + OSErr err; ! dataSize = AEGetDescDataSize (&temp); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize (NULL, dataSize); ! if (!result) *************** *** 66,72 **** --- 64,77 ---- printf ("OSAm.error Out of memory.\n"); Py_INCREF (Py_None); + AEDisposeDesc (&temp); return Py_None; } + if ( (err=AEGetDescData(&temp, PyString_AS_STRING(result), dataSize)) < 0 ) + { + AEDisposeDesc(&temp); + return PyMac_Error(err); + } + AEDisposeDesc(&temp); return result; } *************** *** 111,125 **** DescType typeCode; long dataSize = 0; ! HLock (temp.dataHandle); ! ! dataSize = GetHandleSize (temp.dataHandle); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), dataSize); ! ! AEDisposeDesc (&temp); if (!result) --- 116,128 ---- DescType typeCode; long dataSize = 0; + OSErr err; ! dataSize = AEGetDescDataSize (&temp); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize (NULL, dataSize); ! if (!result) *************** *** 127,136 **** printf ("OSAm.error Out of memory.\n"); Py_INCREF (Py_None); return Py_None; } return result; } - } --- 130,145 ---- printf ("OSAm.error Out of memory.\n"); Py_INCREF (Py_None); + AEDisposeDesc (&temp); return Py_None; } + if ( (err=AEGetDescData(&temp, PyString_AS_STRING(result), dataSize)) < 0 ) + { + AEDisposeDesc(&temp); + return PyMac_Error(err); + } + AEDisposeDesc(&temp); return result; } } *************** *** 171,185 **** DescType typeCode; long dataSize = 0; ! HLock (temp.dataHandle); ! ! dataSize = GetHandleSize (temp.dataHandle); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), dataSize); ! ! AEDisposeDesc (&temp); if (!result) --- 180,192 ---- DescType typeCode; long dataSize = 0; + OSErr err; ! dataSize = AEGetDescDataSize (&temp); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize (NULL, dataSize); ! if (!result) *************** *** 187,193 **** --- 194,207 ---- printf ("OSAm.error Out of memory.\n"); Py_INCREF (Py_None); + AEDisposeDesc (&temp); return Py_None; } + if ( (err=AEGetDescData(&temp, PyString_AS_STRING(result), dataSize)) < 0 ) + { + AEDisposeDesc(&temp); + return PyMac_Error(err); + } + AEDisposeDesc(&temp); return result; } *************** *** 217,221 **** METH_VARARGS, OSAm_DoCommand__doc__}, ! {"CompileAndSave", (PyCFunction) OSAm_CompileAndSave, --- 231,235 ---- METH_VARARGS, OSAm_DoCommand__doc__}, ! #if 0 {"CompileAndSave", (PyCFunction) OSAm_CompileAndSave, *************** *** 227,230 **** --- 241,245 ---- METH_VARARGS, OSAm_DoCommand__doc__}, + #endif {NULL, (PyCFunction) NULL, 0, NULL} Index: OSAm.prj =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Contrib/osam/OSAm.prj,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 Binary files /tmp/cvsEwJRqg and /tmp/cvsqGhAtm differ Index: ScriptRunner.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Contrib/osam/ScriptRunner.c,v retrieving revision 1.2 retrieving revision 1.2.20.1 diff -C2 -d -r1.2 -r1.2.20.1 *** ScriptRunner.c 3 Aug 2001 13:31:34 -0000 1.2 --- ScriptRunner.c 3 Jan 2003 23:55:19 -0000 1.2.20.1 *************** *** 45,49 **** OSAError LoadScriptingComponent (ComponentInstance * scriptingComponent); ! /* * store the script as a compile script so that OSA --- 45,49 ---- OSAError LoadScriptingComponent (ComponentInstance * scriptingComponent); ! #if 0 /* * store the script as a compile script so that OSA *************** *** 144,147 **** --- 144,148 ---- return err2; } + #endif *************** *** 195,199 **** } ! /* * This routine reads in a saved script file and executes --- 196,200 ---- } ! #if 0 /* * This routine reads in a saved script file and executes *************** *** 292,295 **** --- 293,297 ---- return err2; } + #endif From loewis@users.sourceforge.net Sat Jan 4 00:08:11 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Fri, 03 Jan 2003 16:08:11 -0800 Subject: [Python-checkins] python/dist/src/Lib/lib-tk tkFileDialog.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory sc8-pr-cvs1:/tmp/cvs-serv21984/Lib/lib-tk Modified Files: tkFileDialog.py Log Message: Convert Tcl path objects to strings. Fixes #661357. Provide .string attribute and __unicode for Tcl_Objs. Index: tkFileDialog.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/tkFileDialog.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** tkFileDialog.py 13 Oct 2002 10:28:04 -0000 1.8 --- tkFileDialog.py 4 Jan 2003 00:08:09 -0000 1.9 *************** *** 56,59 **** --- 56,65 ---- # keep directory and filename until next time import os + # convert Tcl path objects to strings + try: + result = result.string + except AttributeError: + # it already is a string + pass path, file = os.path.split(result) self.options["initialdir"] = path From loewis@users.sourceforge.net Sat Jan 4 00:08:11 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Fri, 03 Jan 2003 16:08:11 -0800 Subject: [Python-checkins] python/dist/src/Modules _tkinter.c,1.141,1.142 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv21984/Modules Modified Files: _tkinter.c Log Message: Convert Tcl path objects to strings. Fixes #661357. Provide .string attribute and __unicode for Tcl_Objs. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.141 retrieving revision 1.142 diff -C2 -d -r1.141 -r1.142 *** _tkinter.c 31 Dec 2002 20:29:32 -0000 1.141 --- _tkinter.c 4 Jan 2003 00:08:08 -0000 1.142 *************** *** 685,688 **** --- 685,689 ---- PyObject_HEAD Tcl_Obj *value; + PyObject *string; /* This cannot cause cycles. */ } PyTclObject; *************** *** 699,702 **** --- 700,704 ---- Tcl_IncrRefCount(arg); self->value = arg; + self->string = NULL; return (PyObject*)self; } *************** *** 706,709 **** --- 708,712 ---- { Tcl_DecrRefCount(self->value); + Py_XDECREF(self->string); PyObject_Del(self); } *************** *** 712,718 **** --- 715,774 ---- PyTclObject_str(PyTclObject *self) { + if (self->string && PyString_Check(self->string)) { + Py_INCREF(self->string); + return self->string; + } + /* XXX Could cache value if it is an ASCII string. */ return PyString_FromString(Tcl_GetString(self->value)); } + /* Like _str, but create Unicode if necessary. */ + static PyObject * + PyTclObject_string(PyTclObject *self, void *ignored) + { + char *s; + int i, len; + if (!self->string) { + s = Tcl_GetStringFromObj(self->value, &len); + for (i = 0; i < len; i++) + if (s[i] & 0x80) + break; + #ifdef Py_USING_UNICODE + if (i == len) + /* It is an ASCII string. */ + self->string = PyString_FromStringAndSize(s, len); + else { + self->string = PyUnicode_DecodeUTF8(s, len, "strict"); + if (!self->string) { + PyErr_Clear(); + self->string = PyString_FromStringAndSize(s, len); + } + } + #else + self->string = PyString_FromStringAndSize(s, len); + #endif + if (!self->string) + return NULL; + } + Py_INCREF(self->string); + return self->string; + } + + #ifdef Py_USING_UNICODE + static PyObject * + PyTclObject_unicode(PyTclObject *self, void *ignored) + { + char *s; + int len; + if (self->string && PyUnicode_Check(self->string)) { + Py_INCREF(self->string); + return self->string; + } + /* XXX Could chache result if it is non-ASCII. */ + s = Tcl_GetStringFromObj(self->value, &len); + return PyUnicode_DecodeUTF8(s, len, "strict"); + } + #endif + static PyObject * PyTclObject_repr(PyTclObject *self) *************** *** 732,738 **** --- 788,801 ---- static PyGetSetDef PyTclObject_getsetlist[] = { {"typename", (getter)get_typename, NULL, "name of the Tcl type"}, + {"string", (getter)PyTclObject_string, NULL, "name of the Tcl type"}, {0}, }; + static PyMethodDef PyTclObject_methods[] = { + {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS, + "convert argument to unicode"}, + {0} + }; + statichere PyTypeObject PyTclObject_Type = { PyObject_HEAD_INIT(NULL) *************** *** 765,769 **** 0, /*tp_iter*/ 0, /*tp_iternext*/ ! 0, /*tp_methods*/ 0, /*tp_members*/ PyTclObject_getsetlist, /*tp_getset*/ --- 828,832 ---- 0, /*tp_iter*/ 0, /*tp_iternext*/ ! PyTclObject_methods, /*tp_methods*/ 0, /*tp_members*/ PyTclObject_getsetlist, /*tp_getset*/ From tim_one@users.sourceforge.net Sat Jan 4 00:18:47 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 16:18:47 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.140,1.141 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv25321 Modified Files: datetime.py Log Message: Completed astimezone()'s correctness proof. This also proves we can get the desired compromise behavior during the "problem hour" when DST ends cheaply (but I haven't yet implemented that). Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.140 retrieving revision 1.141 diff -C2 -d -r1.140 -r1.141 *** datetime.py 2 Jan 2003 21:01:19 -0000 1.140 --- datetime.py 4 Jan 2003 00:18:45 -0000 1.141 *************** *** 2008,2019 **** Let ! z' = z + z.d = z + diff ! we can again ask whether ! z'.n - z'.o = x.n - x.o If so, we're done. If not, the tzinfo class is insane, or we're trying to ! convert to the hour that can't be spelled in tz. """ --- 2008,2068 ---- Let ! z' = z + z.d = z + diff [7] ! and we can again ask whether ! z'.n - z'.o = x.n - x.o [8] If so, we're done. If not, the tzinfo class is insane, or we're trying to ! convert to the hour that can't be spelled in tz. This also requires a ! bit of proof. As before, let's compute the difference between the LHS and ! RHS of [8] (and skipping some of the justifications for the kinds of ! substitutions we've done several times already): ! ! diff' = (x.n - x.o) - (z'.n - z'.o) = replacing z'.n via [7] ! (x.n - x.o) - (z.n + diff - z'.o) = replacing diff via [6] ! (x.n - x.o) - (z.n + (x.n - x.o) - (z.n - z.o) - z'.o) = ! x.n - x.o - z.n - x.n + x.o + z.n - z.o + z'.o = cancel x.n ! - x.o - z.n + x.o + z.n - z.o + z'.o = cancel x.o ! - z.n + z.n - z.o + z'.o = cancel z.n ! - z.o + z'.o = #1 twice ! -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo ! z'.d - z.d ! ! So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, ! we've found the UTC-equivalent so are done. ! ! How could they differ? z' = z + z.d [7], so merely moving z' by a dst() ! offset, and starting *from* a time already in DST (we know z.d != 0), would ! have to change the result dst() returns: we start in DST, and moving a ! little further into it takes us out of DST. ! ! There's (only) one sane case where this can happen: at the end of DST, ! there's an hour in UTC with no spelling in a hybrid tzinfo class. In US ! Eastern, that's 6:MM UTC = 1:MM EST = 2:MM EDT. During that hour, on an ! Eastern clock 1:MM is taken as being in daylight time (5:MM UTC), but 2:MM is ! taken as being in standard time (7:MM UTC). There is no local time mapping to ! 6:MM UTC. The local clock jumps from 1:59 back to 1:00 again, and repeats the ! 1:MM hour in standard time. Since that's what the local clock *does*, we want ! to map both UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous ! in local time, but so it goes -- it's the way the local clock works. ! ! When x = 6:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, ! so z=1:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. ! z' = z + z.d = 2:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] ! (correctly) concludes that z' is not UTC-equivalent to x. ! ! Because we know z.d said z was in daylight time (else [5] would have held and ! we would have stopped then), and we know z.d != z'.d (else [8] would have held ! and we we have stopped then), and there are only 2 possible values dst() can ! return in Eastern, it follows that z'.d must be 0 (which it is in the example, ! but the reasoning doesn't depend on the example -- it depends on there being ! two possible dst() outcomes, one zero and the other non-zero). Therefore ! z' must be in standard time, and is not the spelling we want in this case. ! z is in daylight time, and is the spelling we want. Note again that z is ! not UTC-equivalent as far as the hybrid tzinfo class is concerned (because ! it takes z as being in standard time rather than the daylight time we intend ! here), but returning it gives the real-life "local clock repeats an hour" ! behavior when mapping the "unspellable" UTC hour into tz. """ From tim_one@users.sourceforge.net Sat Jan 4 00:27:01 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 16:27:01 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv27470/python/Modules Modified Files: datetimemodule.c Log Message: Completed astimezone()'s correctness proof. This also proves we can get the desired compromise behavior during the "problem hour" when DST ends cheaply (but I haven't yet implemented that). Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** datetimemodule.c 2 Jan 2003 21:28:08 -0000 1.28 --- datetimemodule.c 4 Jan 2003 00:26:59 -0000 1.29 *************** *** 5601,5611 **** Let ! z' = z + z.d = z + diff ! we can again ask whether ! z'.n - z'.o = x.n - x.o If so, we're done. If not, the tzinfo class is insane, or we're trying to ! convert to the hour that can't be spelled in tz. --------------------------------------------------------------------------- */ --- 5601,5660 ---- Let ! z' = z + z.d = z + diff [7] ! and we can again ask whether ! z'.n - z'.o = x.n - x.o [8] If so, we're done. If not, the tzinfo class is insane, or we're trying to ! convert to the hour that can't be spelled in tz. This also requires a ! bit of proof. As before, let's compute the difference between the LHS and ! RHS of [8] (and skipping some of the justifications for the kinds of ! substitutions we've done several times already): ! ! diff' = (x.n - x.o) - (z'.n - z'.o) = replacing z'.n via [7] ! (x.n - x.o) - (z.n + diff - z'.o) = replacing diff via [6] ! (x.n - x.o) - (z.n + (x.n - x.o) - (z.n - z.o) - z'.o) = ! x.n - x.o - z.n - x.n + x.o + z.n - z.o + z'.o = cancel x.n ! - x.o - z.n + x.o + z.n - z.o + z'.o = cancel x.o ! - z.n + z.n - z.o + z'.o = cancel z.n ! - z.o + z'.o = #1 twice ! -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo ! z'.d - z.d ! ! So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, ! we've found the UTC-equivalent so are done. ! ! How could they differ? z' = z + z.d [7], so merely moving z' by a dst() ! offset, and starting *from* a time already in DST (we know z.d != 0), would ! have to change the result dst() returns: we start in DST, and moving a ! little further into it takes us out of DST. ! ! There's (only) one sane case where this can happen: at the end of DST, ! there's an hour in UTC with no spelling in a hybrid tzinfo class. In US ! Eastern, that's 6:MM UTC = 1:MM EST = 2:MM EDT. During that hour, on an ! Eastern clock 1:MM is taken as being in daylight time (5:MM UTC), but 2:MM is ! taken as being in standard time (7:MM UTC). There is no local time mapping to ! 6:MM UTC. The local clock jumps from 1:59 back to 1:00 again, and repeats the ! 1:MM hour in standard time. Since that's what the local clock *does*, we want ! to map both UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous ! in local time, but so it goes -- it's the way the local clock works. ! ! When x = 6:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, ! so z=1:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. ! z' = z + z.d = 2:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] ! (correctly) concludes that z' is not UTC-equivalent to x. ! ! Because we know z.d said z was in daylight time (else [5] would have held and ! we would have stopped then), and we know z.d != z'.d (else [8] would have held ! and we we have stopped then), and there are only 2 possible values dst() can ! return in Eastern, it follows that z'.d must be 0 (which it is in the example, ! but the reasoning doesn't depend on the example -- it depends on there being ! two possible dst() outcomes, one zero and the other non-zero). Therefore ! z' must be in standard time, and is not the spelling we want in this case. ! z is in daylight time, and is the spelling we want. Note again that z is ! not UTC-equivalent as far as the hybrid tzinfo class is concerned (because ! it takes z as being in standard time rather than the daylight time we intend ! here), but returning it gives the real-life "local clock repeats an hour" ! behavior when mapping the "unspellable" UTC hour into tz. --------------------------------------------------------------------------- */ From loewis@users.sourceforge.net Sat Jan 4 00:33:15 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Fri, 03 Jan 2003 16:33:15 -0800 Subject: [Python-checkins] python/dist/src/Modules _tkinter.c,1.142,1.143 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv29019/Modules Modified Files: _tkinter.c Log Message: Wrap doc strings in PyDoc_STRVAR. Fix .string docstring. Provide default macro definitions for older Python releases. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.142 retrieving revision 1.143 diff -C2 -d -r1.142 -r1.143 *** _tkinter.c 4 Jan 2003 00:08:08 -0000 1.142 --- _tkinter.c 4 Jan 2003 00:33:13 -0000 1.143 *************** *** 38,41 **** --- 38,50 ---- #endif + /* Allow using this code in Python 2.[12] */ + #ifndef PyDoc_STRVAR + #define PyDoc_STRVAR(name,str) static char name[] = PyDoc_STR(str) + #endif + + #ifndef PyMODINIT_FUNC + #define PyPyMODINIT_FUNC void + #endif + /* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately, making _tkinter correct for this API means to break earlier *************** *** 724,727 **** --- 733,739 ---- /* Like _str, but create Unicode if necessary. */ + PyDoc_STRVAR(PyTclObject_string__doc__, + "the string representation of this object, either as string or Unicode"); + static PyObject * PyTclObject_string(PyTclObject *self, void *ignored) *************** *** 756,759 **** --- 768,773 ---- #ifdef Py_USING_UNICODE + PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode"); + static PyObject * PyTclObject_unicode(PyTclObject *self, void *ignored) *************** *** 780,783 **** --- 794,799 ---- } + PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); + static PyObject* get_typename(PyTclObject* obj, void* ignored) *************** *** 786,792 **** } static PyGetSetDef PyTclObject_getsetlist[] = { ! {"typename", (getter)get_typename, NULL, "name of the Tcl type"}, ! {"string", (getter)PyTclObject_string, NULL, "name of the Tcl type"}, {0}, }; --- 802,810 ---- } + static PyGetSetDef PyTclObject_getsetlist[] = { ! {"typename", (getter)get_typename, NULL, get_typename__doc__}, ! {"string", (getter)PyTclObject_string, NULL, ! PyTclObject_string__doc__}, {0}, }; *************** *** 794,798 **** static PyMethodDef PyTclObject_methods[] = { {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS, ! "convert argument to unicode"}, {0} }; --- 812,816 ---- static PyMethodDef PyTclObject_methods[] = { {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS, ! PyTclObject_unicode__doc__}, {0} }; From rhettinger@users.sourceforge.net Sat Jan 4 00:37:55 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 03 Jan 2003 16:37:55 -0800 Subject: [Python-checkins] python/dist/src/Objects methodobject.c,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv28624 Modified Files: methodobject.c Log Message: SF Patch #661440: Refactor and streamline PyCFunction_Call Refactor code in PyCFunction_Call giving a modest (tiny) speed boost, a slight improvement in semantics (now detects invalid flag combinations), and (arguably) improved clarity (making it blindingly clear which flag combinations are allowed). All this comes at a cost of a few lines of code duplication. * Folded test for METH_KEYWORDS into the switch/case. * Deferred testing for an empty dictionary until when and where needed. * Make a similar deferral for filling the "size" variable. * Inverted the dictionary test so that the common case falls though instead of making a jump. Index: methodobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -d -r2.42 -r2.43 *** methodobject.c 28 Mar 2002 05:33:33 -0000 2.42 --- methodobject.c 4 Jan 2003 00:37:53 -0000 2.43 *************** *** 63,103 **** PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); ! int flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC); ! int size = PyTuple_GET_SIZE(arg); ! ! if (flags & METH_KEYWORDS) { ! return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); ! } ! if (kw != NULL && PyDict_Size(kw) != 0) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes no keyword arguments", ! f->m_ml->ml_name); ! return NULL; ! } ! switch (flags) { case METH_VARARGS: ! return (*meth)(self, arg); case METH_NOARGS: ! if (size == 0) ! return (*meth)(self, NULL); ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes no arguments (%d given)", ! f->m_ml->ml_name, size); ! return NULL; case METH_O: ! if (size == 1) ! return (*meth)(self, PyTuple_GET_ITEM(arg, 0)); ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes exactly one argument (%d given)", ! f->m_ml->ml_name, size); ! return NULL; case METH_OLDARGS: /* the really old style */ ! if (size == 1) ! arg = PyTuple_GET_ITEM(arg, 0); ! else if (size == 0) ! arg = NULL; ! return (*meth)(self, arg); default: /* should never get here ??? */ --- 63,110 ---- PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); ! int size; ! switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC)) { case METH_VARARGS: ! if (kw == NULL || PyDict_Size(kw) == 0) ! return (*meth)(self, arg); ! break; ! case METH_VARARGS | METH_KEYWORDS: ! return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); case METH_NOARGS: ! if (kw == NULL || PyDict_Size(kw) == 0) { ! size = PyTuple_GET_SIZE(arg); ! if (size == 0) ! return (*meth)(self, NULL); ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes no arguments (%d given)", ! f->m_ml->ml_name, size); ! return NULL; ! } ! break; case METH_O: ! if (kw == NULL || PyDict_Size(kw) == 0) { ! size = PyTuple_GET_SIZE(arg); ! if (size == 1) ! return (*meth)(self, PyTuple_GET_ITEM(arg, 0)); ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes exactly one argument (%d given)", ! f->m_ml->ml_name, size); ! return NULL; ! } ! break; case METH_OLDARGS: /* the really old style */ ! if (kw == NULL || PyDict_Size(kw) == 0) { ! size = PyTuple_GET_SIZE(arg); ! if (size == 1) ! arg = PyTuple_GET_ITEM(arg, 0); ! else if (size == 0) ! arg = NULL; ! return (*meth)(self, arg); ! } ! break; ! case METH_OLDARGS | METH_KEYWORDS: ! return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); default: /* should never get here ??? */ *************** *** 105,108 **** --- 112,118 ---- return NULL; } + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); + return NULL; } From nnorwitz@users.sourceforge.net Sat Jan 4 01:02:27 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 03 Jan 2003 17:02:27 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv4692/Modules Modified Files: datetimemodule.c Log Message: Fix compiler warning Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** datetimemodule.c 4 Jan 2003 00:26:59 -0000 1.29 --- datetimemodule.c 4 Jan 2003 01:02:25 -0000 1.30 *************** *** 684,688 **** if (result < -1439 || result > 1439) { PyErr_Format(PyExc_ValueError, ! "tzinfo.%s() returned %ld; must be in " "-1439 .. 1439", name, result); --- 684,688 ---- if (result < -1439 || result > 1439) { PyErr_Format(PyExc_ValueError, ! "tzinfo.%s() returned %d; must be in " "-1439 .. 1439", name, result); From tim.one@comcast.net Sat Jan 4 01:07:29 2003 From: tim.one@comcast.net (Tim Peters) Date: Fri, 03 Jan 2003 20:07:29 -0500 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.29,1.30 In-Reply-To: Message-ID: [nnorwitz@users.sourceforge.net] > Modified Files: > datetimemodule.c > Log Message: > Fix compiler warning > ! "tzinfo.%s() returned %ld; must be in " > ! "tzinfo.%s() returned %d; must be in " > "-1439 .. 1439", > name, result); Thanks! "result" used to be a long -- I sure wish MSVC whined about stuff like this too. From rhettinger@users.sourceforge.net Sat Jan 4 01:53:40 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 03 Jan 2003 17:53:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libshelve.tex,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv20938 Modified Files: libshelve.tex Log Message: SF bug #651149: Review libshelve.tex when possible Minor fixes to markup, spelling, parameter names, and abbreviations. Index: libshelve.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libshelve.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** libshelve.tex 8 Dec 2002 18:36:23 -0000 1.16 --- libshelve.tex 4 Jan 2003 01:53:38 -0000 1.17 *************** *** 45,49 **** \item The choice of which database package will be used ! (e.g. \refmodule{dbm} or \refmodule{gdbm}) depends on which interface is available. Therefore it is not safe to open the database directly using \refmodule{dbm}. The database is also (unfortunately) subject --- 45,49 ---- \item The choice of which database package will be used ! (such as \refmodule{dbm} or \refmodule{gdbm}) depends on which interface is available. Therefore it is not safe to open the database directly using \refmodule{dbm}. The database is also (unfortunately) subject *************** *** 73,84 **** \begin{classdesc}{Shelf}{dict\optional{, binary=False}} A subclass of \class{UserDict.DictMixin} which stores pickled values in the ! \var{dict} object. If the \var{binary} parameter is \constant{True}, binary pickles will be used. This can provide much more compact storage than plain ! text pickles, depending on the nature of the objects stored in the databse. \end{classdesc} \begin{classdesc}{BsdDbShelf}{dict\optional{, binary=False}} A subclass of \class{Shelf} which exposes \method{first}, \method{next}, ! {}\method{previous}, \method{last} and \method{set_location} which are available in the \module{bsddb} module but not in other database modules. The \var{dict} object passed to the constructor must support those methods. --- 73,84 ---- \begin{classdesc}{Shelf}{dict\optional{, binary=False}} A subclass of \class{UserDict.DictMixin} which stores pickled values in the ! \var{dict} object. If the \var{binary} parameter is \code{True}, binary pickles will be used. This can provide much more compact storage than plain ! text pickles, depending on the nature of the objects stored in the database. \end{classdesc} \begin{classdesc}{BsdDbShelf}{dict\optional{, binary=False}} A subclass of \class{Shelf} which exposes \method{first}, \method{next}, ! \method{previous}, \method{last} and \method{set_location} which are available in the \module{bsddb} module but not in other database modules. The \var{dict} object passed to the constructor must support those methods. *************** *** 89,94 **** \end{classdesc} ! \begin{classdesc}{DbfilenameShelf}{dict\optional{, flag='c'}\optional{, binary=False}} ! A subclass of \class{Shelf} which accepts a filename instead of a dict-like object. The underlying file will be opened using \function{anydbm.open}. By default, the file will be created and opened for both read and write. --- 89,94 ---- \end{classdesc} ! \begin{classdesc}{DbfilenameShelf}{filename\optional{, flag='c'\optional{, binary=False}}} ! A subclass of \class{Shelf} which accepts a \var{filename} instead of a dict-like object. The underlying file will be opened using \function{anydbm.open}. By default, the file will be created and opened for both read and write. From rhettinger@users.sourceforge.net Sat Jan 4 02:16:24 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 03 Jan 2003 18:16:24 -0800 Subject: [Python-checkins] python/dist/src/Python bltinmodule.c,2.269,2.270 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv26614/Python Modified Files: bltinmodule.c Log Message: SF bug #655271: Slightly modify locals() doc Clarify the operation of locals(). Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.269 retrieving revision 2.270 diff -C2 -d -r2.269 -r2.270 *** bltinmodule.c 29 Dec 2002 18:31:19 -0000 2.269 --- bltinmodule.c 4 Jan 2003 02:16:22 -0000 2.270 *************** *** 1042,1046 **** "locals() -> dictionary\n\ \n\ ! Return the dictionary containing the current scope's local variables."); --- 1042,1046 ---- "locals() -> dictionary\n\ \n\ ! Update and return a dictionary containing the current scope's local variables."); From rhettinger@users.sourceforge.net Sat Jan 4 02:16:24 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 03 Jan 2003 18:16:24 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libfuncs.tex,1.126,1.127 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv26614/Doc/lib Modified Files: libfuncs.tex Log Message: SF bug #655271: Slightly modify locals() doc Clarify the operation of locals(). Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -d -r1.126 -r1.127 *** libfuncs.tex 2 Jan 2003 04:54:04 -0000 1.126 --- libfuncs.tex 4 Jan 2003 02:16:22 -0000 1.127 *************** *** 625,629 **** \begin{funcdesc}{locals}{} ! Return a dictionary representing the current local symbol table. \warning{The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the --- 625,629 ---- \begin{funcdesc}{locals}{} ! Update and return a dictionary representing the current local symbol table. \warning{The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the From montanaro@users.sourceforge.net Sat Jan 4 04:05:53 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 03 Jan 2003 20:05:53 -0800 Subject: [Python-checkins] python/dist/src README,1.164,1.165 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv19177 Modified Files: README Log Message: Merged Misc/AtheOS-NOTES into the platform-specific section. Rewrote the bsddb module build note to reflect the inclusion of bsddb3 and the demotion of the old bsddb module. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.164 retrieving revision 1.165 diff -C2 -d -r1.164 -r1.165 *** README 3 Jan 2003 16:26:23 -0000 1.164 --- README 4 Jan 2003 04:05:51 -0000 1.165 *************** *** 595,640 **** versions would be appreciated! ! Configuring the bsddb and dbm modules ! ------------------------------------- ! XXX Shouldn't this section be rewritten now that we use Sleepycat's ! BSDDB 4.0? ! Configuring the bsddb module can sometimes be a bit tricky. This module ! provides a Python interface to the Berkeley DB library. As of this writing ! several versions of the underlying library are in common use (versions 1.85, ! 2.x, 3.x, and 4.x). The file formats across the various versions tend to be ! incompatible. Some Linux distributions install multiple versions by ! default. It is important that compatible versions of header files and ! libraries are used when building bsddb. To make matters worse, version 1.85 ! of Berkeley DB has known bugs in its hash file implementation, but is still ! the most widely available version of the library. Many people build bsddb ! with version 1.85 but aren't aware of the bugs. This affects people using ! the anydbm and dbhash modules because they are both use Berkeley DB's hash ! file format as a side effect of calling bsddb.hashopen. ! To try and remedy this problem, beginning with Python version 2.3 a number ! of changes to the bsddb build process were made. First, and most important, ! the bsddb module will not be built with version 1.85 unless the relevant ! lines in setup.py are uncommented first and no other higher-numbered ! versions are found. Second, matching versions of the library and include ! files must be found. Third, searching is performed in order, starting from ! version 4 and proceeding to version 2 (or version 1 if it is enabled). ! Version-independent libraries and header files (e.g. /usr/lib/libdb.a and ! /usr/include/db.h) are never considered. They must be in version-specific ! directories or have version-specific filenames (e.g. /usr/lib/libdb-3.2.so ! and /usr/include/db3/db_185.h). ! Since the bsddb module is programmed using the Berkeley DB version 1 API, ! the underlying library must be configured with the --enable-compat185 flag. ! Most vendor-provided distributions are so-configured. This is generally ! only an issue if you build Berkeley DB from source. - All this affects the dbm module as well. There are several dbm-compliant - APIs provided by different libraries, including ndbm, gdbm and Berkeley DB. - The build process for dbm would previously use the version 1.85 library, - thus extending the potential hash file corruption to the dbm module as well. - The dbm module will use the library and include files found for the bsddb - module if neither ndbm nor gdbm libraries are found. Configuring threads --- 595,680 ---- versions would be appreciated! ! AtheOS: From Octavian Cerna : ! Before building: ! Make sure you have shared versions of the libraries you ! want to use with Python. You will have to compile them ! yourself, or download precompiled packages. ! Recommended libraries: ! ncurses-4.2 ! readline-4.2a ! zlib-1.1.4 ! ! Build: ! ! $ ./configure --prefix=/usr/python ! $ make ! ! Python is always built as a shared library, otherwise ! dynamic loading would not work. ! ! Testing: ! ! $ make test ! ! Install: ! ! # make install ! # pkgmanager -a /usr/python ! ! ! AtheOS issues: ! ! - large file support: due to a stdio bug in glibc/libio, ! access to large files may not work correctly. fseeko() ! tries to seek to a negative offset. ftello() returns a ! negative offset, it looks like a 32->64bit ! sign-extension issue. The lowlevel functions (open, ! lseek, etc) are OK. ! - sockets: AF_UNIX is defined in the C library and in ! Python, but not implemented in the system. ! - select: poll is available in the C library, but does not ! work (It does not return POLLNVAL for bad fds and ! hangs). ! - posix: statvfs and fstatvfs always return ENOSYS. ! - disabled modules: ! - mmap: not yet implemented in AtheOS ! - nis: broken (on an unconfigured system ! yp_get_default_domain() returns junk instead of ! error) ! - dl: dynamic loading doesn't work via dlopen() ! - resource: getrimit and setrlimit are not yet ! implemented ! ! - if you are getting segmentation faults, you probably are ! low on memory. AtheOS doesn't handle very well an ! out-of-memory condition and simply SEGVs the process. ! ! Tested on: ! ! AtheOS-0.3.7 ! gcc-2.95 ! binutils-2.10 ! make-3.78 ! ! ! Configuring the bsddb and dbm modules ! ------------------------------------- ! ! Beginning with Python version 2.3, the PyBsddb package ! was adopted into Python as the bsddb package, ! exposing a set of package-level functions which provide ! backwards-compatible behavior. Only versions 3.1 through 4.1 of ! Sleepycat's libraries provide the necessary API, so older versions ! aren't supported through this interface. The old bsddb module has ! been retained as bsddb185, though it is not built by default. Users ! wishing to use it will have to tweak Modules/Setup to build it. The ! dbm module will still be built against the Sleepycat libraries if ! other preferred alternatives (ndbm, gdbm) are not found, though ! versions of the Sleepycat library prior to 3.1 are not considered. Configuring threads From montanaro@users.sourceforge.net Sat Jan 4 04:06:58 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 03 Jan 2003 20:06:58 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.132,1.133 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv19350 Modified Files: setup.py Log Message: The bsddb3 library does not build w/ Berkeley DB 3.0. 3.1 is the earliest supported version. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.132 retrieving revision 1.133 diff -C2 -d -r1.132 -r1.133 *** setup.py 1 Jan 2003 20:07:48 -0000 1.132 --- setup.py 4 Jan 2003 04:06:56 -0000 1.133 *************** *** 481,489 **** '/usr/include/db4', )}, ! 'db3': {'libs': ('db-3.3', 'db-3.2', 'db-3.1', 'db-3.0'), 'libdirs': ('/usr/local/BerkeleyDB.3.3/lib', '/usr/local/BerkeleyDB.3.2/lib', '/usr/local/BerkeleyDB.3.1/lib', - '/usr/local/BerkeleyDB.3.0/lib', '/usr/local/lib', '/opt/sfw/lib', --- 481,488 ---- '/usr/include/db4', )}, ! 'db3': {'libs': ('db-3.3', 'db-3.2', 'db-3.1'), 'libdirs': ('/usr/local/BerkeleyDB.3.3/lib', '/usr/local/BerkeleyDB.3.2/lib', '/usr/local/BerkeleyDB.3.1/lib', '/usr/local/lib', '/opt/sfw/lib', *************** *** 493,497 **** '/usr/local/BerkeleyDB.3.2/include', '/usr/local/BerkeleyDB.3.1/include', - '/usr/local/BerkeleyDB.3.0/include', '/usr/local/include/db3', '/opt/sfw/include/db3', --- 492,495 ---- From montanaro@users.sourceforge.net Sat Jan 4 04:12:21 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 03 Jan 2003 20:12:21 -0800 Subject: [Python-checkins] python/dist/src/Misc AtheOS-NOTES,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv20426 Removed Files: AtheOS-NOTES Log Message: Moved this info to the top-level README where all the other platform-specific verbiage lives. --- AtheOS-NOTES DELETED --- From tim_one@users.sourceforge.net Sat Jan 4 04:50:18 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 20:50:18 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.141,1.142 test_datetime.py,1.94,1.95 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv27323 Modified Files: datetime.py test_datetime.py Log Message: A new implementation of astimezone() that does what we agreed on in all cases, plus even tougher tests of that. This implementation follows the correctness proof very closely, and should also be quicker (yes, I wrote the proof before the code, and the code proves the proof ). Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.141 retrieving revision 1.142 diff -C2 -d -r1.141 -r1.142 *** datetime.py 4 Jan 2003 00:18:45 -0000 1.141 --- datetime.py 4 Jan 2003 04:50:16 -0000 1.142 *************** *** 1618,1623 **** microsecond, tzinfo) ! def _inconsistent_utcoffset_error(self): ! raise ValueError("astimezone(): tz.utcoffset() gave " "inconsistent results; cannot convert") --- 1618,1623 ---- microsecond, tzinfo) ! def _inconsistent_dst(self): ! raise ValueError("astimezone(): tz.dst() gave " "inconsistent results; cannot convert") *************** *** 1641,1676 **** # See the long comment block at the end of this file for an # explanation of this algorithm. That it always works requires a ! # pretty intricate proof. otdst = other.dst() if otdst is None: ! raise ValueError("astimezone(): utcoffset() returned a duration " "but dst() returned None") ! total_added_to_other = otoff - otdst - myoff ! if total_added_to_other: ! other += total_added_to_other ! otoff = other.utcoffset() ! if otoff is None: ! self._inconsistent_utcoffset_error() ! # The distance now from self to other is ! # self - other == naive(self) - myoff - (naive(other) - otoff) == ! # naive(self) - myoff - ! # ((naive(self) + total_added_to_other - otoff) == ! # - myoff - total_added_to_other + otoff ! delta = otoff - myoff - total_added_to_other ! ##assert (other == self) == (not delta) # expensive ! if not delta: return other ! # Must have crossed a DST switch point. ! total_added_to_other += delta ! other += delta ! otoff = other.utcoffset() ! if otoff is None: ! self._inconsistent_utcoffset_error() ! ##assert (other == self) == (otoff - myoff == total_added_to_other) ! if otoff - myoff == total_added_to_other: ! return other ! raise ValueError("astimezone(): the source datetimetz can't be " ! "expressed in the target timezone's local time") def isoformat(self, sep='T'): --- 1641,1675 ---- # See the long comment block at the end of this file for an # explanation of this algorithm. That it always works requires a ! # pretty intricate proof. There are many equivalent ways to code ! # up the proof as an algorithm. This way favors calling dst() over ! # calling utcoffset(), because "the usual" utcoffset() calls dst() ! # itself, and calling the latter instead saves a Python-level ! # function call. This way of coding it also follow the proof ! # closely, w/ x=self, y=other, z=other, and z'=another. otdst = other.dst() if otdst is None: ! raise ValueError("astimezone(): utcoffset() returned a duration " "but dst() returned None") ! delta = otoff - otdst - myoff ! if delta: ! other += delta ! otdst = other.dst() ! if otdst is None: ! self._inconsistent_dst() ! if not otdst: return other ! another = other + otdst ! anotherdst = another.dst() ! if anotherdst is None: ! self._inconsistent_dst() ! ! if otdst == anotherdst: ! other = another ! else: ! # This is the "unspellable hour" case, and we *don't* want ! # the DST spelling here. ! pass ! return other def isoformat(self, sep='T'): Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.94 retrieving revision 1.95 diff -C2 -d -r1.94 -r1.95 *** test_datetime.py 2 Jan 2003 21:01:22 -0000 1.94 --- test_datetime.py 4 Jan 2003 04:50:16 -0000 1.95 *************** *** 2607,2611 **** # For better test coverage, we want another flavor of UTC that's west of # the Eastern and Pacific timezones. ! utc_fake = FixedOffset(-12, "UTCfake", 0) class TestTimezoneConversions(unittest.TestCase): --- 2607,2611 ---- # For better test coverage, we want another flavor of UTC that's west of # the Eastern and Pacific timezones. ! utc_fake = FixedOffset(-12*60, "UTCfake", 0) class TestTimezoneConversions(unittest.TestCase): *************** *** 2658,2680 **** # standard time. The hour 1:MM:SS standard time == # 2:MM:SS daylight time can't be expressed in local time. nexthour_utc = asutc + HOUR if dt.date() == dstoff.date() and dt.hour == 1: # We're in the hour before DST ends. The hour after ! # is ineffable. ! # For concreteness, picture Eastern. during is of ! # the form 1:MM:SS, it's daylight time, so that's ! # 5:MM:SS UTC. Adding an hour gives 6:MM:SS UTC. ! # Daylight time ended at 2+4 == 6:00:00 UTC, so ! # 6:MM:SS is (correctly) taken to be standard time. ! # But standard time is at offset -5, and that maps ! # right back to the 1:MM:SS Eastern we started with. ! # That's correct, too, *if* 1:MM:SS were taken as ! # being standard time. But it's not -- on this day ! # it's taken as daylight time. ! self.assertRaises(ValueError, ! nexthour_utc.astimezone, tz) else: ! nexthour_tz = nexthour_utc.astimezone(utc) ! self.assertEqual(nexthour_tz - dt, HOUR) # Check a time that's outside DST. --- 2658,2672 ---- # standard time. The hour 1:MM:SS standard time == # 2:MM:SS daylight time can't be expressed in local time. + # Nevertheless, we want conversion back from UTC to mimic + # the local clock's "repeat an hour" behavior. nexthour_utc = asutc + HOUR + nexthour_tz = nexthour_utc.astimezone(tz) if dt.date() == dstoff.date() and dt.hour == 1: # We're in the hour before DST ends. The hour after ! # is ineffable. We want the conversion back to repeat 1:MM. ! expected_diff = ZERO else: ! expected_diff = HOUR ! self.assertEqual(nexthour_tz - dt, expected_diff) # Check a time that's outside DST. *************** *** 2753,2756 **** --- 2745,2773 ---- got = sixutc.astimezone(Eastern).astimezone(None) self.assertEqual(expected, got) + + # Now on the day DST ends, we want "repeat an hour" behavior. + # UTC 4:MM 5:MM 6:MM 7:MM checking these + # EST 23:MM 0:MM 1:MM 2:MM + # EDT 0:MM 1:MM 2:MM 3:MM + # wall 0:MM 1:MM 1:MM 2:MM against these + for utc in utc_real, utc_fake: + for tz in Eastern, Pacific: + first_std_hour = self.dstoff - timedelta(hours=3) # 23:MM + # Convert that to UTC. + first_std_hour -= tz.utcoffset(None) + # Adjust for possibly fake UTC. + asutc = first_std_hour + utc.utcoffset(None) + # First UTC hour to convert; this is 4:00 when utc=utc_real & + # tz=Eastern. + asutcbase = asutc.replace(tzinfo=utc) + for tzhour in (0, 1, 1, 2): + expectedbase = self.dstoff.replace(hour=tzhour) + for minute in 0, 30, 59: + expected = expectedbase.replace(minute=minute) + asutc = asutcbase.replace(minute=minute) + astz = asutc.astimezone(tz) + self.assertEqual(astz.replace(tzinfo=None), expected) + asutcbase += HOUR + def test_bogus_dst(self): From rhettinger@users.sourceforge.net Sat Jan 4 05:20:36 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 03 Jan 2003 21:20:36 -0800 Subject: [Python-checkins] python/dist/src/Lib random.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv476 Modified Files: random.py Log Message: Remove the random=None nonsense from sample() before it gets set in stone. It was once available so that faster generators could be substituted. Now, that is less necessary and preferrably done via subclassing. Also, clarified and shortened the comments for sample(). Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** random.py 29 Dec 2002 23:03:37 -0000 1.41 --- random.py 4 Jan 2003 05:20:33 -0000 1.42 *************** *** 208,212 **** x[i], x[j] = x[j], x[i] ! def sample(self, population, k, random=None, int=int): """Chooses k unique random elements from a population sequence. --- 208,212 ---- x[i], x[j] = x[j], x[i] ! def sample(self, population, k, int=int): """Chooses k unique random elements from a population sequence. *************** *** 224,251 **** This is especially fast and space efficient for sampling from a large population: sample(xrange(10000000), 60) - - Optional arg random is a 0-argument function returning a random - float in [0.0, 1.0); by default, the standard random.random. """ # Sampling without replacement entails tracking either potential ! # selections (the pool) or previous selections. ! ! # Pools are stored in lists which provide __getitem__ for selection ! # and provide a way to remove selections. But each list.remove() ! # rebuilds the entire list, so it is better to rearrange the list, ! # placing non-selected elements at the head of the list. Tracking ! # the selection pool is only space efficient with small populations. ! # Previous selections are stored in dictionaries which provide ! # __contains__ for detecting repeat selections. Discarding repeats ! # is efficient unless most of the population has already been chosen. ! # So, tracking selections is fast only with small sample sizes. n = len(population) if not 0 <= k <= n: raise ValueError, "sample larger than population" ! if random is None: ! random = self.random result = [None] * k if n < 6 * k: # if n len list takes less space than a k len dict --- 224,244 ---- This is especially fast and space efficient for sampling from a large population: sample(xrange(10000000), 60) """ # Sampling without replacement entails tracking either potential ! # selections (the pool) in a list or previous selections in a ! # dictionary. ! # When the number of selections is small compared to the population, ! # then tracking selections is efficient, requiring only a small ! # dictionary and an occasional reselection. For a larger number of ! # selections, the pool tracking method is preferred since the list takes ! # less space than the dictionary and it doesn't suffer from frequent ! # reselections. n = len(population) if not 0 <= k <= n: raise ValueError, "sample larger than population" ! random = self.random result = [None] * k if n < 6 * k: # if n len list takes less space than a k len dict *************** *** 254,258 **** j = int(random() * (n-i)) result[i] = pool[j] ! pool[j] = pool[n-i-1] else: selected = {} --- 247,251 ---- j = int(random() * (n-i)) result[i] = pool[j] ! pool[j] = pool[n-i-1] # move non-selected item into vacancy else: selected = {} From rhettinger@users.sourceforge.net Sat Jan 4 05:55:13 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 03 Jan 2003 21:55:13 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_random.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv7451 Modified Files: test_random.py Log Message: Test an edge case for sample(). Index: test_random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_random.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_random.py 29 Dec 2002 23:03:38 -0000 1.3 --- test_random.py 4 Jan 2003 05:55:11 -0000 1.4 *************** *** 64,67 **** --- 64,68 ---- self.assertEqual(len(uniq), k) self.failIf(None in uniq) + self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0 def test_gauss(self): From tim_one@users.sourceforge.net Sat Jan 4 06:03:18 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 22:03:18 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv8819/python/Modules Modified Files: datetimemodule.c Log Message: A new implementation of astimezone() that does what we agreed on in all cases, plus even tougher tests of that. This implementation follows the correctness proof very closely, and should also be quicker (yes, I wrote the proof before the code, and the code proves the proof ). Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** datetimemodule.c 4 Jan 2003 01:02:25 -0000 1.30 --- datetimemodule.c 4 Jan 2003 06:03:15 -0000 1.31 *************** *** 4755,4759 **** PyObject *result; PyObject *temp; ! int selfoff, resoff, resdst, total_added_to_result; int none; int delta; --- 4755,4759 ---- PyObject *result; PyObject *temp; ! int selfoff, resoff, dst1, dst2; int none; int delta; *************** *** 4793,4800 **** /* See the long comment block at the end of this file for an * explanation of this algorithm. That it always works requires a ! * pretty intricate proof. */ ! resdst = call_dst(tzinfo, result, &none); ! if (resdst == -1 && PyErr_Occurred()) goto Fail; if (none) { --- 4793,4805 ---- /* See the long comment block at the end of this file for an * explanation of this algorithm. That it always works requires a ! * pretty intricate proof. There are many equivalent ways to code ! * up the proof as an algorithm. This way favors calling dst() over ! * calling utcoffset(), because "the usual" utcoffset() calls dst() ! * itself, and calling the latter instead saves a Python-level ! * function call. This way of coding it also follows the proof ! * closely, w/ x=self, y=result, z=result, and z'=temp. */ ! dst1 = call_dst(tzinfo, result, &none); ! if (dst1 == -1 && PyErr_Occurred()) goto Fail; if (none) { *************** *** 4803,4809 **** goto Fail; } ! total_added_to_result = resoff - resdst - selfoff; ! if (total_added_to_result != 0) { ! mm += total_added_to_result; if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) --- 4808,4814 ---- goto Fail; } ! delta = resoff - dst1 - selfoff; ! if (delta) { ! mm += delta; if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) *************** *** 4815,4870 **** result = temp; ! resoff = call_utcoffset(tzinfo, result, &none); ! if (resoff == -1 && PyErr_Occurred()) goto Fail; if (none) goto Inconsistent; } ! ! /* The distance now from self to result is ! * self - result == naive(self) - selfoff - (naive(result) - resoff) == ! * naive(self) - selfoff - ! * ((naive(self) + total_added_to_result - resoff) == ! * - selfoff - total_added_to_result + resoff. ! */ ! delta = resoff - selfoff - total_added_to_result; ! ! /* Now self and result are the same UTC time iff delta is 0. ! * If it is 0, we're done, although that takes some proving. ! */ ! if (delta == 0) return result; ! total_added_to_result += delta; ! mm += delta; if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; - temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); if (temp == NULL) goto Fail; - Py_DECREF(result); - result = temp; ! resoff = call_utcoffset(tzinfo, result, &none); ! if (resoff == -1 && PyErr_Occurred()) goto Fail; ! if (none) goto Inconsistent; ! if (resoff - selfoff == total_added_to_result) ! /* self and result are the same UTC time */ ! return result; ! ! /* Else there's no way to spell self in zone tzinfo. */ ! PyErr_SetString(PyExc_ValueError, "astimezone(): the source " ! "datetimetz can't be expressed in the target " ! "timezone's local time"); ! goto Fail; Inconsistent: ! PyErr_SetString(PyExc_ValueError, "astimezone(): tz.utcoffset() " ! "gave inconsistent results; cannot convert"); /* fall thru to failure */ --- 4820,4864 ---- result = temp; ! dst1 = call_dst(tzinfo, result, &none); ! if (dst1 == -1 && PyErr_Occurred()) goto Fail; if (none) goto Inconsistent; } ! if (dst1 == 0) return result; ! mm += dst1; if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) goto Fail; temp = new_datetimetz(y, m, d, hh, mm, ss, us, tzinfo); if (temp == NULL) goto Fail; ! dst2 = call_dst(tzinfo, temp, &none); ! if (dst2 == -1 && PyErr_Occurred()) { ! Py_DECREF(temp); goto Fail; ! } ! if (none) { ! Py_DECREF(temp); goto Inconsistent; + } ! if (dst1 == dst2) { ! /* The normal case: we want temp, not result. */ ! Py_DECREF(result); ! result = temp; ! } ! else { ! /* The "unspellable hour" at the end of DST. */ ! Py_DECREF(temp); ! } ! return result; Inconsistent: ! PyErr_SetString(PyExc_ValueError, "astimezone(): tz.dst() gave" ! "inconsistent results; cannot convert"); /* fall thru to failure */ From tim_one@users.sourceforge.net Sat Jan 4 06:03:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 22:03:17 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.599,1.600 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv8819/python/Misc Modified Files: NEWS Log Message: A new implementation of astimezone() that does what we agreed on in all cases, plus even tougher tests of that. This implementation follows the correctness proof very closely, and should also be quicker (yes, I wrote the proof before the code, and the code proves the proof ). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.599 retrieving revision 1.600 diff -C2 -d -r1.599 -r1.600 *** NEWS 3 Jan 2003 22:35:24 -0000 1.599 --- NEWS 4 Jan 2003 06:03:15 -0000 1.600 *************** *** 27,35 **** today() and now() now round system timestamps to the closest ! microsecond . In dt.asdatetime(tz), if tz.utcoffset(dt) returns a duration, ValueError is raised if tz.dst(dt) returns None (2.3a1 treated it ! as 0 instead). The tzinfo methods utcoffset() and dst() must return a timedelta object --- 27,39 ---- today() and now() now round system timestamps to the closest ! microsecond . This repairs an ! irritation most likely seen on Windows systems. In dt.asdatetime(tz), if tz.utcoffset(dt) returns a duration, ValueError is raised if tz.dst(dt) returns None (2.3a1 treated it ! as 0 instead, but a tzinfo subclass wishing to participate in ! time zone conversion has to take a stand on whether it supports ! DST; if you don't care about DST, then code dst() to return 0 minutes, ! meaning that DST is never in effect). The tzinfo methods utcoffset() and dst() must return a timedelta object *************** *** 40,43 **** --- 44,53 ---- The example tzinfo class for local time had a bug. It was replaced by a later example coded by Guido. + + datetimetz.astimezone(tz) no longer raises an exception when the + input datetime has no UTC equivalent in tz. For typical "hybrid" time + zones (a single tzinfo subclass modeling both standard and daylight + time), this case can arise one hour per year, at the hour daylight time + ends. See new docs for details. Library From tim_one@users.sourceforge.net Sat Jan 4 06:03:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 22:03:17 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.28,1.29 tzinfo-examples.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv8819/python/Doc/lib Modified Files: libdatetime.tex tzinfo-examples.py Log Message: A new implementation of astimezone() that does what we agreed on in all cases, plus even tougher tests of that. This implementation follows the correctness proof very closely, and should also be quicker (yes, I wrote the proof before the code, and the code proves the proof ). Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** libdatetime.tex 2 Jan 2003 21:28:07 -0000 1.28 --- libdatetime.tex 4 Jan 2003 06:03:14 -0000 1.29 *************** *** 925,933 **** must return the same result for every \class{datetimetz} \var{dt} ! in a given year with \code{dt.tzinfo==tz} For sane \class{tzinfo} ! subclasses, this expression yields the time zone's "standard offset" ! within the year, which should be the same across all days in the year. ! The implementation of \method{datetimetz.astimezone()} relies on this, ! but cannot detect violations; it's the programmer's responsibility to ensure it. --- 925,933 ---- must return the same result for every \class{datetimetz} \var{dt} ! with \code{dt.tzinfo==tz} For sane \class{tzinfo} subclasses, this ! expression yields the time zone's "standard offset", which should not ! depend on the date or the time, but only on geographic location. The ! implementation of \method{datetimetz.astimezone()} relies on this, but ! cannot detect violations; it's the programmer's responsibility to ensure it. *************** *** 970,973 **** --- 970,1017 ---- \verbatiminput{tzinfo-examples.py} + + Note that there are unavoidable subtleties twice per year in a tzinfo + subclass accounting for both standard and daylight time, at the DST + transition points. For concreteness, consider US Eastern (UTC -0500), + where EDT begins the minute after 1:59 (EST) on the first Sunday in + April, and ends the minute after 1:59 (EDT) on the last Sunday in October: + + \begin{verbatim} + UTC 3:MM 4:MM 5:MM 6:MM 7:MM 8:MM + EST 22:MM 23:MM 0:MM 1:MM 2:MM 3:MM + EDT 23:MM 0:MM 1:MM 2:MM 3:MM 4:MM + + start 22:MM 23:MM 0:MM 1:MM 3:MM 4:MM + + end 23:MM 0:MM 1:MM 1:MM 2:MM 3:MM + \end{verbatim} + + When DST starts (the "start" line), the local wall clock leaps from 1:59 + to 3:00. A wall time of the form 2:MM doesn't really make sense on that + day, so astimezone(Eastern) won't deliver a result with hour=2 on the + day DST begins. How an Eastern class chooses to interpret 2:MM on + that day is its business. The example Eastern class above chose to + consider it as a time in EDT, simply because it "looks like it's + after 2:00", and so synonymous with the EST 1:MM times on that day. + Your Eastern class may wish, for example, to raise an exception instead + when it sees a 2:MM time on the day Eastern begins. + + When DST ends (the "end" line), there's a potentially worse problem: + there's an hour that can't be spelled at all in local wall time, the + hour beginning at the moment DST ends. In this example, that's times of + the form 6:MM UTC on the day daylight time ends. The local wall clock + leaps from 1:59 (daylight time) back to 1:00 (standard time) again. + 1:MM is taken as daylight time (it's "before 2:00"), so maps to 5:MM UTC. + 2:MM is taken as standard time (it's "after 2:00"), so maps to 7:MM UTC. + There is no local time that maps to 6:MM UTC on this day. + + Just as the wall clock does, astimezone(Eastern) maps both UTC hours 5:MM + and 6:MM to Eastern hour 1:MM on this day. However, this result is + ambiguous (there's no way for Eastern to know which repetition of 1:MM + is intended). Applications that can't bear such ambiguity even one hour + per year should avoid using hybrid tzinfo classes; there are no + ambiguities when using UTC, or any other fixed-offset tzinfo subclass + (such as a class representing only EST (fixed offset -5 hours), or only + EDT (fixed offset -4 hours)). Index: tzinfo-examples.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/tzinfo-examples.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** tzinfo-examples.py 3 Jan 2003 22:26:57 -0000 1.3 --- tzinfo-examples.py 4 Jan 2003 06:03:14 -0000 1.4 *************** *** 1,5 **** ! from datetime import tzinfo, timedelta ZERO = timedelta(0) # A UTC class. --- 1,6 ---- ! from datetime import tzinfo, timedelta, datetime ZERO = timedelta(0) + HOUR = timedelta(hours=1) # A UTC class. *************** *** 77,78 **** --- 78,139 ---- Local = LocalTimezone() + + + # A complete implementation of current DST rules for major US time zones. + + def first_sunday_on_or_after(dt): + days_to_go = 6 - dt.weekday() + if days_to_go: + dt += timedelta(days_to_go) + return dt + + # In the US, DST starts at 2am (standard time) on the first Sunday in April. + DSTSTART = datetime(1, 4, 1, 2) + # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct. + # which is the first Sunday on or after Oct 25. + DSTEND = datetime(1, 10, 25, 2) + + class USTimeZone(tzinfo): + + def __init__(self, hours, reprname, stdname, dstname): + self.stdoffset = timedelta(hours=hours) + self.reprname = reprname + self.stdname = stdname + self.dstname = dstname + + def __repr__(self): + return self.reprname + + def tzname(self, dt): + if self.dst(dt): + return self.dstname + else: + return self.stdname + + def utcoffset(self, dt): + return self.stdoffset + self.dst(dt) + + def dst(self, dt): + if dt is None or dt.tzinfo is None: + # An exception may be sensible here, in one or both cases. + # It depends on how you want to treat them. The astimezone() + # implementation always passes a datetimetz with + # dt.tzinfo == self. + return ZERO + assert dt.tzinfo is self + + # Find first Sunday in April & the last in October. + start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year)) + end = first_sunday_on_or_after(DSTEND.replace(year=dt.year)) + + # Can't compare naive to aware objects, so strip the timezone from + # dt first. + if start <= dt.replace(tzinfo=None) < end: + return HOUR + else: + return ZERO + + Eastern = USTimeZone(-5, "Eastern", "EST", "EDT") + Central = USTimeZone(-6, "Central", "CST", "CDT") + Mountain = USTimeZone(-7, "Mountain", "MST", "MDT") + Pacific = USTimeZone(-8, "Pacific", "PST", "PDT") From tim_one@users.sourceforge.net Sat Jan 4 06:03:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 03 Jan 2003 22:03:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv8819/python/Lib/test Modified Files: test_datetime.py Log Message: A new implementation of astimezone() that does what we agreed on in all cases, plus even tougher tests of that. This implementation follows the correctness proof very closely, and should also be quicker (yes, I wrote the proof before the code, and the code proves the proof ). Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** test_datetime.py 2 Jan 2003 21:28:07 -0000 1.21 --- test_datetime.py 4 Jan 2003 06:03:15 -0000 1.22 *************** *** 2593,2597 **** # For better test coverage, we want another flavor of UTC that's west of # the Eastern and Pacific timezones. ! utc_fake = FixedOffset(-12, "UTCfake", 0) class TestTimezoneConversions(unittest.TestCase): --- 2593,2597 ---- # For better test coverage, we want another flavor of UTC that's west of # the Eastern and Pacific timezones. ! utc_fake = FixedOffset(-12*60, "UTCfake", 0) class TestTimezoneConversions(unittest.TestCase): *************** *** 2644,2666 **** # standard time. The hour 1:MM:SS standard time == # 2:MM:SS daylight time can't be expressed in local time. nexthour_utc = asutc + HOUR if dt.date() == dstoff.date() and dt.hour == 1: # We're in the hour before DST ends. The hour after ! # is ineffable. ! # For concreteness, picture Eastern. during is of ! # the form 1:MM:SS, it's daylight time, so that's ! # 5:MM:SS UTC. Adding an hour gives 6:MM:SS UTC. ! # Daylight time ended at 2+4 == 6:00:00 UTC, so ! # 6:MM:SS is (correctly) taken to be standard time. ! # But standard time is at offset -5, and that maps ! # right back to the 1:MM:SS Eastern we started with. ! # That's correct, too, *if* 1:MM:SS were taken as ! # being standard time. But it's not -- on this day ! # it's taken as daylight time. ! self.assertRaises(ValueError, ! nexthour_utc.astimezone, tz) else: ! nexthour_tz = nexthour_utc.astimezone(utc) ! self.assertEqual(nexthour_tz - dt, HOUR) # Check a time that's outside DST. --- 2644,2658 ---- # standard time. The hour 1:MM:SS standard time == # 2:MM:SS daylight time can't be expressed in local time. + # Nevertheless, we want conversion back from UTC to mimic + # the local clock's "repeat an hour" behavior. nexthour_utc = asutc + HOUR + nexthour_tz = nexthour_utc.astimezone(tz) if dt.date() == dstoff.date() and dt.hour == 1: # We're in the hour before DST ends. The hour after ! # is ineffable. We want the conversion back to repeat 1:MM. ! expected_diff = ZERO else: ! expected_diff = HOUR ! self.assertEqual(nexthour_tz - dt, expected_diff) # Check a time that's outside DST. *************** *** 2739,2742 **** --- 2731,2759 ---- got = sixutc.astimezone(Eastern).astimezone(None) self.assertEqual(expected, got) + + # Now on the day DST ends, we want "repeat an hour" behavior. + # UTC 4:MM 5:MM 6:MM 7:MM checking these + # EST 23:MM 0:MM 1:MM 2:MM + # EDT 0:MM 1:MM 2:MM 3:MM + # wall 0:MM 1:MM 1:MM 2:MM against these + for utc in utc_real, utc_fake: + for tz in Eastern, Pacific: + first_std_hour = self.dstoff - timedelta(hours=3) # 23:MM + # Convert that to UTC. + first_std_hour -= tz.utcoffset(None) + # Adjust for possibly fake UTC. + asutc = first_std_hour + utc.utcoffset(None) + # First UTC hour to convert; this is 4:00 when utc=utc_real & + # tz=Eastern. + asutcbase = asutc.replace(tzinfo=utc) + for tzhour in (0, 1, 1, 2): + expectedbase = self.dstoff.replace(hour=tzhour) + for minute in 0, 30, 59: + expected = expectedbase.replace(minute=minute) + asutc = asutcbase.replace(minute=minute) + astz = asutc.astimezone(tz) + self.assertEqual(astz.replace(tzinfo=None), expected) + asutcbase += HOUR + def test_bogus_dst(self): From loewis@users.sourceforge.net Sat Jan 4 08:37:00 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 04 Jan 2003 00:37:00 -0800 Subject: [Python-checkins] python/dist/src/Modules _tkinter.c,1.143,1.144 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6846 Modified Files: _tkinter.c Log Message: Remove appartment check from dooneevent. Fixes #660961. Check whether self is NULL in mainloop. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.143 retrieving revision 1.144 diff -C2 -d -r1.143 -r1.144 *** _tkinter.c 4 Jan 2003 00:33:13 -0000 1.143 --- _tkinter.c 4 Jan 2003 08:36:57 -0000 1.144 *************** *** 2417,2424 **** return NULL; ! CHECK_TCL_APPARTMENT; quitMainLoop = 0; - self->dispatching = 1; while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && --- 2417,2434 ---- return NULL; ! if (!self && !tcl_lock) { ! /* We don't have the Tcl lock since Tcl is threaded. */ ! PyErr_SetString(PyExc_RuntimeError, ! "_tkinter.mainloop not supported " ! "for threaded Tcl"); ! return NULL; ! } ! ! if (self) { ! CHECK_TCL_APPARTMENT; ! self->dispatching = 1; ! } quitMainLoop = 0; while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && *************** *** 2428,2432 **** #ifdef WITH_THREAD ! if (self->threaded) { /* Allow other Python threads to run. */ ENTER_TCL --- 2438,2442 ---- #ifdef WITH_THREAD ! if (self && self->threaded) { /* Allow other Python threads to run. */ ENTER_TCL *************** *** 2450,2454 **** if (PyErr_CheckSignals() != 0) { ! self->dispatching = 0; return NULL; } --- 2460,2465 ---- if (PyErr_CheckSignals() != 0) { ! if (self) ! self->dispatching = 0; return NULL; } *************** *** 2456,2460 **** break; } ! self->dispatching = 0; quitMainLoop = 0; --- 2467,2472 ---- break; } ! if (self) ! self->dispatching = 0; quitMainLoop = 0; *************** *** 2477,2481 **** if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags)) return NULL; - CHECK_TCL_APPARTMENT; ENTER_TCL --- 2489,2492 ---- From loewis@users.sourceforge.net Sat Jan 4 08:55:01 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 04 Jan 2003 00:55:01 -0800 Subject: [Python-checkins] python/dist/src/Modules _tkinter.c,1.144,1.145 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv10964 Modified Files: _tkinter.c Log Message: Fix typo. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.144 retrieving revision 1.145 diff -C2 -d -r1.144 -r1.145 *** _tkinter.c 4 Jan 2003 08:36:57 -0000 1.144 --- _tkinter.c 4 Jan 2003 08:54:59 -0000 1.145 *************** *** 44,48 **** #ifndef PyMODINIT_FUNC ! #define PyPyMODINIT_FUNC void #endif --- 44,48 ---- #ifndef PyMODINIT_FUNC ! #define PyMODINIT_FUNC void #endif From rhettinger@users.sourceforge.net Sat Jan 4 09:26:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 04 Jan 2003 01:26:35 -0800 Subject: [Python-checkins] python/dist/src/Lib random.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv18677 Modified Files: random.py Log Message: Correct long standing bugs in the methods for random distributions. The range of u=random() is [0,1), so log(u) and 1/x can fail. Fix by setting u=1-random() or by reselecting for a usable value. Will backport. Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** random.py 4 Jan 2003 05:20:33 -0000 1.42 --- random.py 4 Jan 2003 09:26:32 -0000 1.43 *************** *** 283,287 **** while True: u1 = random() ! u2 = random() z = NV_MAGICCONST*(u1-0.5)/u2 zz = z*z/4.0 --- 283,287 ---- while True: u1 = random() ! u2 = 1.0 - random() z = NV_MAGICCONST*(u1-0.5)/u2 zz = z*z/4.0 *************** *** 423,427 **** while True: u1 = random() ! u2 = random() v = _log(u1/(1.0-u1))/ainv x = alpha*_exp(v) --- 423,429 ---- while True: u1 = random() ! if not 1e-7 < u1 < .9999999: ! continue ! u2 = 1.0 - random() v = _log(u1/(1.0-u1))/ainv x = alpha*_exp(v) *************** *** 555,559 **** # Jain, pg. 495 ! u = self.random() return 1.0 / pow(u, 1.0/alpha) --- 557,561 ---- # Jain, pg. 495 ! u = 1.0 - self.random() return 1.0 / pow(u, 1.0/alpha) *************** *** 568,572 **** # Jain, pg. 499; bug fix courtesy Bill Arms ! u = self.random() return alpha * pow(-_log(u), 1.0/beta) --- 570,574 ---- # Jain, pg. 499; bug fix courtesy Bill Arms ! u = 1.0 - self.random() return alpha * pow(-_log(u), 1.0/beta) From rhettinger@users.sourceforge.net Sat Jan 4 09:30:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 04 Jan 2003 01:30:35 -0800 Subject: [Python-checkins] python/dist/src/Lib random.py,1.26.6.7,1.26.6.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv20008 Modified Files: Tag: release22-maint random.py Log Message: Correct long standing bugs in the methods for random distributions. The range of u=random() is [0,1), so log(u) and 1/x can fail. Fix by setting u=1-random() or by reselecting for a usable value. Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.26.6.7 retrieving revision 1.26.6.8 diff -C2 -d -r1.26.6.7 -r1.26.6.8 *** random.py 5 Oct 2002 14:42:52 -0000 1.26.6.7 --- random.py 4 Jan 2003 09:30:32 -0000 1.26.6.8 *************** *** 400,404 **** while 1: u1 = random() ! u2 = random() z = NV_MAGICCONST*(u1-0.5)/u2 zz = z*z/4.0 --- 400,404 ---- while 1: u1 = random() ! u2 = 1.0 - random() z = NV_MAGICCONST*(u1-0.5)/u2 zz = z*z/4.0 *************** *** 536,540 **** while 1: u1 = random() ! u2 = random() v = _log(u1/(1.0-u1))/ainv x = alpha*_exp(v) --- 536,542 ---- while 1: u1 = random() ! if not 1e-7 < u1 < .9999999: ! continue ! u2 = 1.0 - random() v = _log(u1/(1.0-u1))/ainv x = alpha*_exp(v) *************** *** 668,672 **** # Jain, pg. 495 ! u = self.random() return 1.0 / pow(u, 1.0/alpha) --- 670,674 ---- # Jain, pg. 495 ! u = 1.0 - self.random() return 1.0 / pow(u, 1.0/alpha) *************** *** 681,685 **** # Jain, pg. 499; bug fix courtesy Bill Arms ! u = self.random() return alpha * pow(-_log(u), 1.0/beta) --- 683,687 ---- # Jain, pg. 499; bug fix courtesy Bill Arms ! u = 1.0 - self.random() return alpha * pow(-_log(u), 1.0/beta) From gvanrossum@users.sourceforge.net Sat Jan 4 14:02:58 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sat, 04 Jan 2003 06:02:58 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.142,1.143 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv27395 Modified Files: datetime.py Log Message: Another useful URL. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.142 retrieving revision 1.143 diff -C2 -d -r1.142 -r1.143 *** datetime.py 4 Jan 2003 04:50:16 -0000 1.142 --- datetime.py 4 Jan 2003 14:02:55 -0000 1.143 *************** *** 11,14 **** --- 11,16 ---- ftp://elsie.nci.nih.gov/pub/ + Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm + """ From gvanrossum@users.sourceforge.net Sat Jan 4 14:11:42 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sat, 04 Jan 2003 06:11:42 -0800 Subject: [Python-checkins] python/dist/src/Lib mimetypes.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv30080 Modified Files: mimetypes.py Log Message: Add Shockwave Flash. (backport candidate?) Index: mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimetypes.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** mimetypes.py 3 Jan 2003 21:06:46 -0000 1.26 --- mimetypes.py 4 Jan 2003 14:11:38 -0000 1.27 *************** *** 431,434 **** --- 431,435 ---- '.sv4cpio': 'application/x-sv4cpio', '.sv4crc' : 'application/x-sv4crc', + '.swf' : 'application/x-shockwave-flash', '.t' : 'application/x-troff', '.tar' : 'application/x-tar', From jvr@users.sourceforge.net Sat Jan 4 16:26:28 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Sat, 04 Jan 2003 08:26:28 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSX/PythonLauncher doscript.m,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSX/PythonLauncher In directory sc8-pr-cvs1:/tmp/cvs-serv13076 Modified Files: doscript.m Log Message: correct comment (and add newline at end) Index: doscript.m =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSX/PythonLauncher/doscript.m,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** doscript.m 31 Jul 2002 13:15:59 -0000 1.1 --- doscript.m 4 Jan 2003 16:26:26 -0000 1.2 *************** *** 101,105 **** } ! /* send the event to the Finder */ err = AESend(&theAEvent, &theReply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); --- 101,105 ---- } ! /* send the command event to Terminal.app */ err = AESend(&theAEvent, &theReply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); *************** *** 116,118 **** AEDisposeDesc(&theReply); return err; ! } \ No newline at end of file --- 116,118 ---- AEDisposeDesc(&theReply); return err; ! } From tim_one@users.sourceforge.net Sat Jan 4 18:17:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 04 Jan 2003 10:17:38 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.600,1.601 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv13081/Misc Modified Files: NEWS Log Message: datetime_from_timet_and_us(): ignore leap seconds if the platform localtime()/gmtime() insists on delivering them, + associated doc changes. Redid the docs for datetimtez.astimezone(). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.600 retrieving revision 1.601 diff -C2 -d -r1.600 -r1.601 *** NEWS 4 Jan 2003 06:03:15 -0000 1.600 --- NEWS 4 Jan 2003 18:17:36 -0000 1.601 *************** *** 51,54 **** --- 51,60 ---- ends. See new docs for details. + The constructors building a datetime from a timestamp could raise + ValueError if the platform C localtime()/gmtime() inserted "leap + seconds". Leap seconds are ignored now. On such platforms, it's + possible to have timestamps that differ by a second, yet where + datetimes constructed from them are equal. + Library ------- From tim_one@users.sourceforge.net Sat Jan 4 18:17:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 04 Jan 2003 10:17:38 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv13081/Modules Modified Files: datetimemodule.c Log Message: datetime_from_timet_and_us(): ignore leap seconds if the platform localtime()/gmtime() insists on delivering them, + associated doc changes. Redid the docs for datetimtez.astimezone(). Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** datetimemodule.c 4 Jan 2003 06:03:15 -0000 1.31 --- datetimemodule.c 4 Jan 2003 18:17:36 -0000 1.32 *************** *** 2832,2836 **** tm = f(&timet); ! if (tm) result = PyObject_CallFunction(cls, "iiiiiii", tm->tm_year + 1900, --- 2832,2844 ---- tm = f(&timet); ! if (tm) { ! /* The platform localtime/gmtime may insert leap seconds, ! * indicated by tm->tm_sec > 59. We don't care about them, ! * except to the extent that passing them on to the datetime ! * constructor would raise ValueError for a reason that ! * made no sense to the user. ! */ ! if (tm->tm_sec > 59) ! tm->tm_sec = 59; result = PyObject_CallFunction(cls, "iiiiiii", tm->tm_year + 1900, *************** *** 2841,2844 **** --- 2849,2853 ---- tm->tm_sec, us); + } else PyErr_SetString(PyExc_ValueError, From tim_one@users.sourceforge.net Sat Jan 4 18:17:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 04 Jan 2003 10:17:38 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv13081/Doc/lib Modified Files: libdatetime.tex Log Message: datetime_from_timet_and_us(): ignore leap seconds if the platform localtime()/gmtime() insists on delivering them, + associated doc changes. Redid the docs for datetimtez.astimezone(). Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** libdatetime.tex 4 Jan 2003 06:03:14 -0000 1.29 --- libdatetime.tex 4 Jan 2003 18:17:36 -0000 1.30 *************** *** 315,320 **** values supported by the platform C \cfunction{localtime()} function. It's common for this to be restricted to years from 1970 ! through 2038. ! \end{methoddesc} \begin{methoddesc}{fromordinal}{ordinal} --- 315,321 ---- values supported by the platform C \cfunction{localtime()} function. It's common for this to be restricted to years from 1970 ! through 2038. Note that on non-POSIX systems that include leap ! seconds in their notion of a timestamp, leap seconds are ignored by ! \method{fromtimestamp()}. \begin{methoddesc}{fromordinal}{ordinal} *************** *** 547,550 **** --- 548,556 ---- \cfunction{localtime()} function. It's common for this to be restricted to years in 1970 through 2038. + Note that on non-POSIX systems that include leap seconds in their + notion of a timestamp, leap seconds are ignored by + \method{fromtimestamp()}, and then it's possible to have two timestamps + differing by a second that yield identical \class{datetime} objects. + \end{methoddesc} See also \method{utcfromtimestamp()}. \end{methoddesc} *************** *** 989,1002 **** When DST starts (the "start" line), the local wall clock leaps from 1:59 to 3:00. A wall time of the form 2:MM doesn't really make sense on that ! day, so astimezone(Eastern) won't deliver a result with hour=2 on the ! day DST begins. How an Eastern class chooses to interpret 2:MM on ! that day is its business. The example Eastern class above chose to consider it as a time in EDT, simply because it "looks like it's after 2:00", and so synonymous with the EST 1:MM times on that day. Your Eastern class may wish, for example, to raise an exception instead ! when it sees a 2:MM time on the day Eastern begins. When DST ends (the "end" line), there's a potentially worse problem: ! there's an hour that can't be spelled at all in local wall time, the hour beginning at the moment DST ends. In this example, that's times of the form 6:MM UTC on the day daylight time ends. The local wall clock --- 995,1010 ---- When DST starts (the "start" line), the local wall clock leaps from 1:59 to 3:00. A wall time of the form 2:MM doesn't really make sense on that ! day, so \code{astimezone(Eastern)} won't deliver a result with ! \code{hour==2} on the ! day DST begins. How an Eastern instance chooses to interpret 2:MM on ! that day is its business. The example Eastern implementation above ! chose to consider it as a time in EDT, simply because it "looks like it's after 2:00", and so synonymous with the EST 1:MM times on that day. Your Eastern class may wish, for example, to raise an exception instead ! when it sees a 2:MM time on the day EDT begins. When DST ends (the "end" line), there's a potentially worse problem: ! there's an hour that can't be spelled unambiguously in local wall time, the hour beginning at the moment DST ends. In this example, that's times of the form 6:MM UTC on the day daylight time ends. The local wall clock *************** *** 1006,1014 **** There is no local time that maps to 6:MM UTC on this day. ! Just as the wall clock does, astimezone(Eastern) maps both UTC hours 5:MM and 6:MM to Eastern hour 1:MM on this day. However, this result is ambiguous (there's no way for Eastern to know which repetition of 1:MM ! is intended). Applications that can't bear such ambiguity even one hour ! per year should avoid using hybrid tzinfo classes; there are no ambiguities when using UTC, or any other fixed-offset tzinfo subclass (such as a class representing only EST (fixed offset -5 hours), or only --- 1014,1023 ---- There is no local time that maps to 6:MM UTC on this day. ! Just as the wall clock does, \code{astimezone(Eastern)} maps both UTC ! hours 5:MM and 6:MM to Eastern hour 1:MM on this day. However, this result is ambiguous (there's no way for Eastern to know which repetition of 1:MM ! is intended). Applications that can't bear such ambiguity ! should avoid using hybrid tzinfo classes; there are no ambiguities when using UTC, or any other fixed-offset tzinfo subclass (such as a class representing only EST (fixed offset -5 hours), or only *************** *** 1355,1371 **** \begin{methoddesc}{astimezone}{tz} ! Return a \class{datetimetz} with new tzinfo member \var{tz}. \var{tz} ! must be \code{None}, or an instance of a \class{tzinfo} subclass. If ! \var{tz} is \code{None}, self is naive, or \code{tz.utcoffset(self)} returns \code{None}, \code{self.astimezone(tz)} is equivalent to \code{self.replace(tzinfo=tz)}: a new timezone object is attached ! without any conversion of date or time fields. If self is aware and ! \code{tz.utcoffset(self)} does not return \code{None}, the date and ! time fields are adjusted so that the result is local time in timezone ! tz, representing the same UTC time as self. ! XXX [The treatment of endcases remains unclear: for DST-aware ! classes, one hour per year has two spellings in local time, and ! another hour has no spelling in local time.] XXX \end{methoddesc} --- 1364,1385 ---- \begin{methoddesc}{astimezone}{tz} ! Return a \class{datetimetz} object with new \membar{tzinfo} member ! \var{tz}. ! \var{tz} must be \code{None}, or an instance of a \class{tzinfo} subclass. ! If \var{tz} is \code{None}, \var{self} is naive, \code{tz.utcoffset(self)} returns \code{None}, + or \code{self.tzinfo}\ is \var{tz}, \code{self.astimezone(tz)} is equivalent to \code{self.replace(tzinfo=tz)}: a new timezone object is attached ! without any conversion of date or time fields. Else \code{self.tzinfo} ! and \var{tz} must implement the \method{utcoffset()} and \method{dst()} ! \class{tzinfo} methods, and the date and time fields are adjusted so ! that the result is local time in time zone \var{tz}, representing the ! same UTC time as \var{self}: after \code{astz = dt.astimezone(tz)}, ! \code{astz - astz.utcoffset()} will usually have the same date and time ! members as \code{dt - dt.utcoffset()}. The discussion of class ! \class{tzinfo} explains the cases at Daylight Saving Time ! transition boundaries where this cannot be achieved (an issue only if ! \var{tz} models both standard and daylight time). \end{methoddesc} From tim_one@users.sourceforge.net Sat Jan 4 18:25:26 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 04 Jan 2003 10:25:26 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.143,1.144 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv16038 Modified Files: datetime.py Log Message: Clamp out leap seconds on non-POSIX platforms. datetimes can't represent them, and fromtimestamp() could raise a baffling ValueError if the platform localtime()/gmtime() returned one. Note that this means it's possible, on a non-POSIX platform, to have timestamps that differ by a second, yet map to identical datetime objects. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.143 retrieving revision 1.144 diff -C2 -d -r1.143 -r1.144 *** datetime.py 4 Jan 2003 14:02:55 -0000 1.143 --- datetime.py 4 Jan 2003 18:25:23 -0000 1.144 *************** *** 1285,1288 **** --- 1285,1289 ---- y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) us = int(round((t % 1.0) * 1000000)) + ss = min(ss, 59) # clamp out leap seconds if the platform has them return cls(y, m, d, hh, mm, ss, us) fromtimestamp = classmethod(fromtimestamp) *************** *** 1303,1306 **** --- 1304,1308 ---- y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t) us = int((t % 1.0) * 1000000) + ss = min(ss, 59) # clamp out leap seconds if the platform has them return cls(y, m, d, hh, mm, ss, us) utcfromtimestamp = classmethod(utcfromtimestamp) *************** *** 1552,1555 **** --- 1554,1558 ---- y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) us = int((t % 1.0) * 1000000) + ss = min(ss, 59) # clamp out leap seconds if the platform has them return cls(y, m, d, hh, mm, ss, us, tzinfo) fromtimestamp = classmethod(fromtimestamp) From tim_one@users.sourceforge.net Sat Jan 4 18:36:11 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 04 Jan 2003 10:36:11 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime doc.txt,1.81,1.82 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv19983 Modified Files: doc.txt Log Message: This is getting far enough out of synch with the LaTeX docs that it's going to do more harm than good: deleted the content, just leaving the URL to the Python docs. Index: doc.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v retrieving revision 1.81 retrieving revision 1.82 diff -C2 -d -r1.81 -r1.82 *** doc.txt 3 Jan 2003 16:46:53 -0000 1.81 --- doc.txt 4 Jan 2003 18:36:09 -0000 1.82 *************** *** 8,1303 **** http://www.python.org/dev/doc/devel/lib/module-datetime.html ************************************************************************** - - - - TODO/OPEN - ========= - - The Python implementation is missing docstrings in many places. - - [...1267 lines suppressed...] - All objects are immutable, so accessors are read-only. All macros - return ints: - - For date, datetime, and datetimetz instances: - PyDateTime_GET_YEAR(o) - PyDateTime_GET_MONTH(o) - PyDateTime_GET_DAY(o) - - For datetime and datetimetz instances: - PyDateTime_DATE_GET_HOUR(o) - PyDateTime_DATE_GET_MINUTE(o) - PyDateTime_DATE_GET_SECOND(o) - PyDateTime_DATE_GET_MICROSECOND(o) - - For time and timetz instances: - PyDateTime_TIME_GET_HOUR(o) - PyDateTime_TIME_GET_MINUTE(o) - PyDateTime_TIME_GET_SECOND(o) - PyDateTime_TIME_GET_MICROSECOND(o) --- 8,9 ---- From jvr@users.sourceforge.net Sat Jan 4 21:44:23 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Sat, 04 Jan 2003 13:44:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac terminalcommand.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv11864 Added Files: terminalcommand.py Log Message: module to run commands in a Terminal.app window --- NEW FILE: terminalcommand.py --- """terminalcommand.py -- A minimal interface to Terminal.app. To run a shell command in a new Terminal.app window: import terminalcommand terminalcommand.run("ls -l") No result is returned; it is purely meant as a quick way to run a script with a decent input/output window. """ # # This module is a fairly straightforward translation of Jack Jansen's # Mac/OSX/PythonLauncher/doscript.m. # import time import os from Carbon import AE from Carbon.AppleEvents import * TERMINAL_SIG = "trmx" START_TERMINAL = "/usr/bin/open /Applications/Utilities/Terminal.app" SEND_MODE = kAENoReply # kAEWaitReply hangs when run from Terminal.app itself def run(command): """Run a shell command in a new Terminal.app window.""" termAddress = AE.AECreateDesc(typeApplSignature, TERMINAL_SIG) theEvent = AE.AECreateAppleEvent(kAEMiscStandards, kAEActivate, termAddress, kAutoGenerateReturnID, kAnyTransactionID) try: theEvent.AESend(SEND_MODE, kAENormalPriority, kAEDefaultTimeout) except AE.Error, why: if why[0] != -600: # Terminal.app not yet running raise os.system(START_TERMINAL) time.sleep(1) theEvent.AESend(SEND_MODE, kAENormalPriority, kAEDefaultTimeout) theEvent = AE.AECreateAppleEvent(kAECoreSuite, kAEDoScript, termAddress, kAutoGenerateReturnID, kAnyTransactionID) commandDesc = AE.AECreateDesc(typeChar, command) theEvent.AEPutParamDesc(kAECommandClass, commandDesc) theEvent.AESend(SEND_MODE, kAENormalPriority, kAEDefaultTimeout) if __name__ == "__main__": run("ls -l") From gward@users.sourceforge.net Sat Jan 4 21:54:28 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sat, 04 Jan 2003 13:54:28 -0800 Subject: [Python-checkins] python/dist/src/Lib optparse.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14428 Modified Files: optparse.py Log Message: Tweak __version__ -- the current code is between Optik 1.4 and 1.4.1. Index: optparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/optparse.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** optparse.py 14 Nov 2002 22:00:19 -0000 1.1 --- optparse.py 4 Jan 2003 21:54:26 -0000 1.2 *************** *** 43,47 **** import textwrap ! __version__ = "1.4" class OptParseError (Exception): --- 43,47 ---- import textwrap ! __version__ = "1.4+" class OptParseError (Exception): From jackjansen@users.sourceforge.net Sun Jan 5 00:13:56 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sat, 04 Jan 2003 16:13:56 -0800 Subject: [Python-checkins] python/dist/src/Mac/Distributions binary.include,1.22,1.22.2.1 dev.exclude,1.10,1.10.2.1 dev.include,1.27,1.27.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory sc8-pr-cvs1:/tmp/cvs-serv24869 Modified Files: Tag: r23a1-branch binary.include dev.exclude dev.include Log Message: Getting closer to a 2.3a1 distribution. Index: binary.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/binary.include,v retrieving revision 1.22 retrieving revision 1.22.2.1 diff -C2 -d -r1.22 -r1.22.2.1 *** binary.include 6 Sep 2002 23:33:50 -0000 1.22 --- binary.include 5 Jan 2003 00:13:54 -0000 1.22.2.1 *************** *** 3,6 **** --- 3,7 ---- (':BuildApplet', None) (':BuildApplication', None) + (':ConfigurePython', '') (':Demo', '') (':Demo:cwilib', None) *************** *** 112,116 **** (':Mac:Contrib:PythonDetector:PythonDetector', '') (':Mac:Contrib:PythonDetector:readme.txt', '') - (':Mac:Contrib:PythonScript', '') (':Mac:Contrib:Sherlock', '') (':Mac:Contrib:Tabcleaner', '') --- 113,116 ---- *************** *** 139,143 **** (':Mac:ReadMe~0', None) (':Mac:ReadmeSource', None) - (':Mac:Relnotes', ':Relnotes:') (':Mac:Resources', None) (':Mac:TODO', None) --- 139,142 ---- *************** *** 169,172 **** --- 168,172 ---- (':PythonCarbonStandalone', None) (':PythonCoreCarbon', '') + (':PythonInterpreter', '') (':PythonStandCarbon', None) (':PythonStandSmall', None) *************** *** 206,209 **** (':setup.py', None) (':site-packages', None) - (':ConfigurePython', '') - (':PythonInterpreter', '') --- 206,207 ---- Index: dev.exclude =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/dev.exclude,v retrieving revision 1.10 retrieving revision 1.10.2.1 diff -C2 -d -r1.10 -r1.10.2.1 *** dev.exclude 6 Sep 2002 23:33:54 -0000 1.10 --- dev.exclude 5 Jan 2003 00:13:54 -0000 1.10.2.1 *************** *** 6,9 **** --- 6,10 ---- *.hqx *.idb + *.pch *.pyc *.pyo *************** *** 12,15 **** --- 13,17 ---- *.xSYM *Icon + *_pch *~[0-9] .#* *************** *** 19,22 **** CVS [(]*[)] - *.pch - *_pch --- 21,22 ---- Index: dev.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/dev.include,v retrieving revision 1.27 retrieving revision 1.27.2.1 diff -C2 -d -r1.27 -r1.27.2.1 *** dev.include 6 Sep 2002 23:34:00 -0000 1.27 --- dev.include 5 Jan 2003 00:13:54 -0000 1.27.2.1 *************** *** 7,11 **** (':Demo', None) (':Demo:embed', ':Demo:embed') - (':Demo:extend', ':Demo:extend') (':Demo:pysvr', ':Demo:pysvr') (':Doc', None) --- 7,10 ---- *************** *** 71,84 **** (':Mac:Build:PythonInterpreter.old.mcp', None) (':Mac:Build:PythonStandSmall.mcp', None) - (':Mac:Build:PythonStandSmall.mcp~0', None) - (':Mac:Build:PythonStandSmall.mcp~1', None) (':Mac:Build:PythonStandSmall.old.mcp', None) (':Mac:Build:PythonStandalone.mcp', None) - (':Mac:Build:PythonStandalone.mcp~0', None) - (':Mac:Build:PythonStandalone.mcp~1', None) (':Mac:Build:Qt.carbon.mcp.exp', None) - (':Mac:Build:Qt.carbon.mcp.xml~0', None) (':Mac:Build:Qt.mcp.exp', None) - (':Mac:Build:Qt.mcp.xml~0', None) (':Mac:Build:Snd.carbon.mcp.exp', None) (':Mac:Build:Snd.carbon.mcp.xml', None) --- 70,77 ---- *************** *** 99,102 **** --- 92,98 ---- (':Mac:Build:_AE.mcp.exp', None) (':Mac:Build:_AE.mcp.xml', None) + (':Mac:Build:_AH.carbon.mcp', None) + (':Mac:Build:_AH.carbon.mcp.exp', None) + (':Mac:Build:_AH.carbon.mcp.xml', None) (':Mac:Build:_App.carbon.mcp', None) (':Mac:Build:_App.carbon.mcp.exp', None) *************** *** 150,156 **** --- 146,158 ---- (':Mac:Build:_Fm.mcp.exp', None) (':Mac:Build:_Fm.mcp.xml', None) + (':Mac:Build:_Help.carbon.mcp', None) + (':Mac:Build:_Help.carbon.mcp.exp', None) + (':Mac:Build:_Help.carbon.mcp.xml', None) (':Mac:Build:_Help.mcp', None) (':Mac:Build:_Help.mcp.exp', None) (':Mac:Build:_Help.mcp.xml', None) + (':Mac:Build:_IBCarbon.carbon.mcp', None) + (':Mac:Build:_IBCarbon.carbon.mcp.exp', None) + (':Mac:Build:_IBCarbon.carbon.mcp.xml', None) (':Mac:Build:_Icn.carbon.mcp', None) (':Mac:Build:_Icn.carbon.mcp.exp', None) *************** *** 292,295 **** --- 294,300 ---- (':Mac:Build:pyexpat.mcp.exp', None) (':Mac:Build:pyexpat.mcp.xml', None) + (':Mac:Build:pygusiconfig.carbon.lib', None) + (':Mac:Build:pygusiconfig.smcarbon.lib', None) + (':Mac:Build:temp_delete_me', None) (':Mac:Build:waste.carbon.mcp', None) (':Mac:Build:waste.carbon.mcp.exp', None) *************** *** 301,313 **** (':Mac:Build:xx.carbon.mcp.exp', '') (':Mac:Build:xx.carbon.mcp.xml', '') - (':Mac:Build:xx.mcp', '') - (':Mac:Build:xx.mcp.exp', '') - (':Mac:Build:xx.mcp.xml', None) (':Mac:Build:xxsubtype.carbon.mcp', None) (':Mac:Build:xxsubtype.carbon.mcp.exp', None) (':Mac:Build:xxsubtype.carbon.mcp.xml', None) - (':Mac:Build:xxsubtype.mcp', None) - (':Mac:Build:xxsubtype.mcp.exp', None) - (':Mac:Build:xxsubtype.mcp.xml', None) (':Mac:Build:zlib.carbon.mcp', None) (':Mac:Build:zlib.carbon.mcp.exp', None) --- 306,312 ---- *************** *** 373,376 **** --- 372,376 ---- (':Mac:MPW', None) (':Mac:Modules', None) + (':Mac:OSX', None) (':Mac:OSX:Makefile', None) (':Mac:OSX:README', None) *************** *** 395,398 **** --- 395,399 ---- (':Mac:Resources:pythonpath.r', '') (':Mac:Resources:tkpython.rsrc', None) + (':Mac:Resources:tkpython.rsrc-', None) (':Mac:Resources:version.r', None) (':Mac:TODO', None) *************** *** 416,419 **** --- 417,421 ---- (':Mac:mwerks:mwerks_nscarbon_config.h', '') (':Mac:mwerks:mwerks_shcarbon_config.h', '') + (':Mac:mwerks:mwerks_smcarbon_config.h', '') (':Mac:mwerks:mwerks_thrcarbonsm_config.h', None) (':Mac:mwerks:mwerks_threadsmall_config.h', '') *************** *** 441,444 **** --- 443,447 ---- (':Modules:_localemodule.c', None) (':Modules:_sre.c', None) + (':Modules:_ssl.c', None) (':Modules:_testcapimodule.c', None) (':Modules:_tkinter.c', None) *************** *** 467,470 **** --- 470,474 ---- (':Modules:dlmodule.c', None) (':Modules:errnomodule.c', None) + (':Modules:expat', None) (':Modules:fcntlmodule.c', None) (':Modules:flmodule.c', None) *************** *** 519,522 **** --- 523,527 ---- (':Modules:signalmodule.c', None) (':Modules:socketmodule.c', None) + (':Modules:socketmodule.h', None) (':Modules:soundex.c', None) (':Modules:sre.h', None) *************** *** 583,586 **** --- 588,592 ---- (':Tools:compiler', None) (':Tools:faqwiz', None) + (':Tools:framer', None) (':Tools:freeze', '') (':Tools:i18n', None) *************** *** 606,628 **** (':setup.py', None) (':site-packages', None) ! (':Mac:Build:_IBCarbon.carbon.mcp.xml', None) ! (':Mac:Build:_IBCarbon.carbon.mcp.exp', None) ! (':Mac:Build:_IBCarbon.carbon.mcp', None) ! (':Mac:Build:_Help.carbon.mcp.xml', None) ! (':Mac:Build:_Help.carbon.mcp.exp', None) ! (':Mac:Build:_Help.carbon.mcp', None) ! (':Mac:Build:_AH.carbon.mcp.xml', None) ! (':Mac:Build:_AH.carbon.mcp.exp', None) ! (':Mac:Build:_AH.carbon.mcp', None) ! (':Mac:Build:temp_delete_me', None) ! (':Mac:Build:pygusiconfig.smcarbon.lib', None) ! (':Mac:Build:pygusiconfig.carbon.lib', None) ! (':Mac:mwerks:mwerks_carbonpyexpat_config.h', '') ! (':Mac:mwerks:mwerks_pyexpat_config.h', '') ! (':Mac:mwerks:mwerks_smcarbon_config.h', '') ! (':Mac:OSX', None) ! (':Modules:_ssl.c', None) ! (':Modules:socketmodule.h', None) ! (':Mac:Resources:tkpython.rsrc-', None) ! (':Modules:expat', None) ! (':Tools:framer', None) --- 612,631 ---- (':setup.py', None) (':site-packages', None) ! (':Mac:Build:_Folder.carbon.mcp.xml', None) ! (':Mac:Build:_Folder.carbon.mcp.exp', None) ! (':Mac:Build:_Folder.carbon.mcp', None) ! (':Mac:Build:_File.carbon.mcp.xml', None) ! (':Mac:Build:_File.carbon.mcp.exp', None) ! (':Mac:Build:_File.carbon.mcp', None) ! (':Mac:Build:_Alias.carbon.mcp.xml', None) ! (':Mac:Build:_Alias.carbon.mcp.exp', None) ! (':Mac:Build:_Alias.carbon.mcp', None) ! (':Modules:zipimport.c', None) ! (':Modules:ossaudiodev.c', None) ! (':Modules:datetimemodule.c', None) ! (':Modules:bz2module.c', None) ! (':Modules:_randommodule.c', None) ! (':Modules:_bsddb.c', None) ! (':Mac:Build:datetime.carbon.mcp.xml', None) ! (':Mac:Build:datetime.carbon.mcp.exp', None) ! (':Mac:Build:datetime.carbon.mcp', None) From jackjansen@users.sourceforge.net Sun Jan 5 00:14:19 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sat, 04 Jan 2003 16:14:19 -0800 Subject: [Python-checkins] python/dist/src/Mac/Distributions/(vise) Python 2.3.vct,1.4,1.4.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions/(vise) In directory sc8-pr-cvs1:/tmp/cvs-serv24914 Modified Files: Tag: r23a1-branch Python 2.3.vct Log Message: Getting closer to a 2.3a1 distribution. Index: Python 2.3.vct =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/(vise)/Python 2.3.vct,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -C2 -d -r1.4 -r1.4.2.1 Binary files /tmp/cvseNQqj2 and /tmp/cvsKGWJj0 differ From jackjansen@users.sourceforge.net Sun Jan 5 00:16:37 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sat, 04 Jan 2003 16:16:37 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac FrameWork.py,1.1,1.1.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv25776 Modified Files: Tag: r23a1-branch FrameWork.py Log Message: Squashed another case of the 32-bit warning. Index: FrameWork.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/FrameWork.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -C2 -d -r1.1 -r1.1.2.1 *** FrameWork.py 30 Dec 2002 22:04:20 -0000 1.1 --- FrameWork.py 5 Jan 2003 00:16:34 -0000 1.1.2.1 *************** *** 646,650 **** if not reply: return ! id = (reply & 0xffff0000) >> 16 item = reply & 0xffff if not window: --- 646,650 ---- if not reply: return ! id = (reply >> 16) & 0xffff item = reply & 0xffff if not window: From jackjansen@users.sourceforge.net Sun Jan 5 00:17:20 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sat, 04 Jan 2003 16:17:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_zipimport.py,1.1.2.2,1.1.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25930 Modified Files: Tag: r23a1-branch test_zipimport.py Log Message: Various tweaks to make the test work on the Mac. Index: test_zipimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zipimport.py,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** test_zipimport.py 3 Jan 2003 11:24:31 -0000 1.1.2.2 --- test_zipimport.py 5 Jan 2003 00:17:17 -0000 1.1.2.3 *************** *** 16,20 **** def make_pyc(co, mtime): data = marshal.dumps(co) ! pyc = imp.get_magic() + struct.pack(" Update of /cvsroot/python/python/dist/src/Mac In directory sc8-pr-cvs1:/tmp/cvs-serv26267 Modified Files: Tag: r23a1-branch ReadMe Log Message: Updated. Index: ReadMe =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/ReadMe,v retrieving revision 1.45.2.2 retrieving revision 1.45.2.3 diff -C2 -d -r1.45.2.2 -r1.45.2.3 *** ReadMe 3 Jan 2003 23:53:45 -0000 1.45.2.2 --- ReadMe 5 Jan 2003 00:18:16 -0000 1.45.2.3 *************** *** 85,93 **** the next release. - test_pep263 crashes with a syntax error. This will be fixed in the next release. - test_socket fails, this problem is being investigated. ! test_strptime fails, this problem is being investigated. Three tests will fail on MacOS9 with MemoryErrors: --- 85,93 ---- the next release. test_socket fails, this problem is being investigated. ! test_strptime and test_time fail, this problem is being investigated. ! ! test_unicode fails, this problem is being investigated. Three tests will fail on MacOS9 with MemoryErrors: From jackjansen@users.sourceforge.net Sun Jan 5 00:17:56 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sat, 04 Jan 2003 16:17:56 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.115,1.115.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv26074 Modified Files: Tag: r23a1-branch regrtest.py Log Message: Updated the list of expected skips for MacPython-OS9. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.115 retrieving revision 1.115.2.1 diff -C2 -d -r1.115 -r1.115.2.1 *** regrtest.py 31 Dec 2002 11:26:50 -0000 1.115 --- regrtest.py 5 Jan 2003 00:17:52 -0000 1.115.2.1 *************** *** 596,600 **** --- 596,603 ---- """ test_al + test_atexit test_bsddb + test_bsddb3 + test_bz2 test_cd test_cl *************** *** 604,607 **** --- 607,611 ---- test_dbm test_dl + test_email_codecs test_fcntl test_fork1 *************** *** 613,623 **** --- 617,631 ---- test_locale test_mmap + test_mpz test_nis test_ntpath test_openpty + test_ossaudiodev test_poll + test_popen test_popen2 test_pty test_pwd + test_resource test_signal test_socketserver From rhettinger@users.sourceforge.net Sun Jan 5 01:08:36 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 04 Jan 2003 17:08:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_random.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv8267 Modified Files: test_random.py Log Message: Add a test case. Index: test_random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_random.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_random.py 4 Jan 2003 05:55:11 -0000 1.4 --- test_random.py 5 Jan 2003 01:08:34 -0000 1.5 *************** *** 183,186 **** --- 183,204 ---- self.gen.seed(seed) + class TestDistributions(unittest.TestCase): + def test_zeroinputs(self): + # Verify that distributions can handle a series of zero inputs' + g = random.Random() + x = [g.random() for i in xrange(50)] + [0.0]*5 + g.random = x[:].pop; g.uniform(1,10) + g.random = x[:].pop; g.paretovariate(1.0) + g.random = x[:].pop; g.expovariate(1.0) + g.random = x[:].pop; g.weibullvariate(1.0, 1.0) + g.random = x[:].pop; g.normalvariate(0.0, 1.0) + g.random = x[:].pop; g.gauss(0.0, 1.0) + g.random = x[:].pop; g.lognormvariate(0.0, 1.0) + g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0) + g.random = x[:].pop; g.gammavariate(0.01, 1.0) + g.random = x[:].pop; g.gammavariate(1.0, 1.0) + g.random = x[:].pop; g.gammavariate(200.0, 1.0) + g.random = x[:].pop; g.betavariate(3.0, 3.0) + class TestModule(unittest.TestCase): def testMagicConstants(self): *************** *** 200,203 **** --- 218,222 ---- for testclass in (WichmannHill_TestBasicOps, MersenneTwister_TestBasicOps, + TestDistributions, TestModule): suite.addTest(unittest.makeSuite(testclass)) From tim_one@users.sourceforge.net Sun Jan 5 02:10:33 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 04 Jan 2003 18:10:33 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime2.py,NONE,1.1 test_datetime2.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv23119 Added Files: datetime2.py test_datetime2.py Log Message: A rewrite that renames datetimetz to datetime, timetz to time, and gets rid of the old datetime and time. Works great, saves some code, saves more brain cells. --- NEW FILE: datetime2.py --- """Concrete date/time and related types -- prototype implemented in Python. See http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage See also http://dir.yahoo.com/Reference/calendars/ For a primer on DST, including many current DST rules, see http://webexhibits.org/daylightsaving/ For more about DST than you ever wanted to know, see ftp://elsie.nci.nih.gov/pub/ Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm """ import time as _time import math as _math [...1756 lines suppressed...] Because we know z.d said z was in daylight time (else [5] would have held and we would have stopped then), and we know z.d != z'.d (else [8] would have held and we we have stopped then), and there are only 2 possible values dst() can return in Eastern, it follows that z'.d must be 0 (which it is in the example, but the reasoning doesn't depend on the example -- it depends on there being two possible dst() outcomes, one zero and the other non-zero). Therefore z' must be in standard time, and is not the spelling we want in this case. z is in daylight time, and is the spelling we want. Note again that z is not UTC-equivalent as far as the hybrid tzinfo class is concerned (because it takes z as being in standard time rather than the daylight time we intend here), but returning it gives the real-life "local clock repeats an hour" behavior when mapping the "unspellable" UTC hour into tz. """ def _test(): import test_datetime2 test_datetime2.test_main() if __name__ == "__main__": _test() --- NEW FILE: test_datetime2.py --- """Test date/time type. See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ import sys import unittest from datetime2 import MINYEAR, MAXYEAR from datetime2 import timedelta from datetime2 import tzinfo from datetime2 import time from datetime2 import date, datetime # XXX The test suite uncovered a bug in Python 2.2.2: if x and y are # XXX instances of new-style classes (like date and time) that both # XXX define __cmp__, and x is compared to y, and one of the __cmp__ # XXX implementations raises an exception, the exception can get dropped [...2795 lines suppressed...] lastrc = None while True: r.run(s) if 1: # change to 0, under a debug build, for some leak detection break gc.collect() if gc.garbage: raise SystemError("gc.garbage not empty after test run: %r" % gc.garbage) if hasattr(sys, 'gettotalrefcount'): thisrc = sys.gettotalrefcount() print >> sys.stderr, '*' * 10, 'total refs:', thisrc, if lastrc: print >> sys.stderr, 'delta:', thisrc - lastrc else: print >> sys.stderr lastrc = thisrc if __name__ == "__main__": test_main() From tim_one@users.sourceforge.net Sun Jan 5 07:22:46 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 04 Jan 2003 23:22:46 -0800 Subject: [Python-checkins] python/dist/src/Objects methodobject.c,2.43,2.44 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv29396/python/Objects Modified Files: methodobject.c Log Message: PyCFunction_Call(): Combined two switch cases w/ identical bodies. Index: methodobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v retrieving revision 2.43 retrieving revision 2.44 diff -C2 -d -r2.43 -r2.44 *** methodobject.c 4 Jan 2003 00:37:53 -0000 2.43 --- methodobject.c 5 Jan 2003 07:22:44 -0000 2.44 *************** *** 71,74 **** --- 71,75 ---- break; case METH_VARARGS | METH_KEYWORDS: + case METH_OLDARGS | METH_KEYWORDS: return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); case METH_NOARGS: *************** *** 105,112 **** } break; - case METH_OLDARGS | METH_KEYWORDS: - return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); default: - /* should never get here ??? */ PyErr_BadInternalCall(); return NULL; --- 106,110 ---- *************** *** 268,272 **** int i, n; PyObject *v; ! n = 0; for (c = chain; c != NULL; c = c->link) { --- 266,270 ---- int i, n; PyObject *v; ! n = 0; for (c = chain; c != NULL; c = c->link) { From rhettinger@users.sourceforge.net Sun Jan 5 09:20:09 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 05 Jan 2003 01:20:09 -0800 Subject: [Python-checkins] python/dist/src/Lib random.py,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv21100 Modified Files: random.py Log Message: Move the statistical tests for four distributions into the unittest suite. Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** random.py 4 Jan 2003 09:26:32 -0000 1.43 --- random.py 5 Jan 2003 09:20:06 -0000 1.44 *************** *** 753,757 **** _test_generator(N, 'lognormvariate(0.0, 1.0)') _test_generator(N, 'cunifvariate(0.0, 1.0)') - _test_generator(N, 'expovariate(1.0)') _test_generator(N, 'vonmisesvariate(0.0, 1.0)') _test_generator(N, 'gammavariate(0.01, 1.0)') --- 753,756 ---- *************** *** 766,771 **** _test_generator(N, 'gauss(0.0, 1.0)') _test_generator(N, 'betavariate(3.0, 3.0)') - _test_generator(N, 'paretovariate(1.0)') - _test_generator(N, 'weibullvariate(1.0, 1.0)') _test_generator(N, '_sample_generator(50, 5)') # expected s.d.: 14.4 _test_generator(N, '_sample_generator(50, 45)') # expected s.d.: 14.4 --- 765,768 ---- From rhettinger@users.sourceforge.net Sun Jan 5 09:20:09 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 05 Jan 2003 01:20:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_random.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv21100/test Modified Files: test_random.py Log Message: Move the statistical tests for four distributions into the unittest suite. Index: test_random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_random.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_random.py 5 Jan 2003 01:08:34 -0000 1.5 --- test_random.py 5 Jan 2003 09:20:06 -0000 1.6 *************** *** 4,7 **** --- 4,8 ---- import random import time + from math import log, exp, sqrt, pi from test import test_support *************** *** 183,186 **** --- 184,199 ---- self.gen.seed(seed) + _gammacoeff = (0.9999999999995183, 676.5203681218835, -1259.139216722289, + 771.3234287757674, -176.6150291498386, 12.50734324009056, + -0.1385710331296526, 0.9934937113930748e-05, 0.1659470187408462e-06) + + def gamma(z, cof=_gammacoeff, g=7): + z -= 1.0 + sum = cof[0] + for i in xrange(1,len(cof)): + sum += cof[i] / (z+i) + z += 0.5 + return (z+g)**z / exp(z+g) * sqrt(2*pi) * sum + class TestDistributions(unittest.TestCase): def test_zeroinputs(self): *************** *** 200,203 **** --- 213,244 ---- g.random = x[:].pop; g.gammavariate(200.0, 1.0) g.random = x[:].pop; g.betavariate(3.0, 3.0) + + def test_avg_std(self): + # Use integration to test distribution average and standard deviation. + # Only works for distributions which do not consume variates in pairs + g = random.Random() + N = 5000 + x = [i/float(N) for i in xrange(1,N)] + for variate, args, mu, sigmasqrd in [ + (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12), + (g.expovariate, (1.5,), 1/1.5, 1/1.5**2), + (g.paretovariate, (5.0,), 5.0/(5.0-1), + 5.0/((5.0-1)**2*(5.0-2))), + (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0), + gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]: + g.random = x[:].pop + y = [] + for i in xrange(len(x)): + try: + y.append(variate(*args)) + except IndexError: + pass + s1 = s2 = 0 + for e in y: + s1 += e + s2 += (e - mu) ** 2 + N = len(y) + self.assertAlmostEqual(s1/N, mu, 2) + self.assertAlmostEqual(s2/(N-1), sigmasqrd, 2) class TestModule(unittest.TestCase): From nnorwitz@users.sourceforge.net Sun Jan 5 18:15:25 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 10:15:25 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_logging.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv13590/Lib/test Modified Files: test_logging.py Log Message: At least one Solaris box in the snake farm only supports "C" locale. Adding try/except allows the test to pass Index: test_logging.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_logging.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_logging.py 2 Jan 2003 14:56:39 -0000 1.1 --- test_logging.py 5 Jan 2003 18:15:23 -0000 1.2 *************** *** 30,34 **** import logging, logging.handlers, logging.config ! locale.setlocale(locale.LC_ALL, '') BANNER = "-- %-10s %-6s ---------------------------------------------------\n" --- 30,38 ---- import logging, logging.handlers, logging.config ! try: ! locale.setlocale(locale.LC_ALL, '') ! except ValueError: ! # this happens on a Solaris box which only supports "C" locale ! pass BANNER = "-- %-10s %-6s ---------------------------------------------------\n" From jvr@users.sourceforge.net Sun Jan 5 19:44:13 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Sun, 05 Jan 2003 11:44:13 -0800 Subject: [Python-checkins] python/dist/src/Lib shutil.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv9567 Modified Files: shutil.py Log Message: - squashed bare except in rmtree() - improved readability of rmtree; removed silly apply() Index: shutil.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/shutil.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** shutil.py 30 Oct 2002 05:44:50 -0000 1.25 --- shutil.py 5 Jan 2003 19:44:11 -0000 1.26 *************** *** 128,142 **** cmdtuples = [] _build_cmdtuple(path, cmdtuples) ! for cmd in cmdtuples: try: ! apply(cmd[0], (cmd[1],)) ! except: exc = sys.exc_info() if ignore_errors: pass elif onerror is not None: ! onerror(cmd[0], cmd[1], exc) else: ! raise exc[0], (exc[1][0], exc[1][1] + ' removing '+cmd[1]) # Helper for rmtree() --- 128,142 ---- cmdtuples = [] _build_cmdtuple(path, cmdtuples) ! for func, arg in cmdtuples: try: ! func(arg) ! except OSError: exc = sys.exc_info() if ignore_errors: pass elif onerror is not None: ! onerror(func, arg, exc) else: ! raise exc[0], (exc[1][0], exc[1][1] + ' removing '+arg) # Helper for rmtree() From nnorwitz@users.sourceforge.net Sun Jan 5 22:20:53 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 14:20:53 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.106,1.107 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv26570/Doc/lib Modified Files: libos.tex Log Message: Fix a typo Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.106 retrieving revision 1.107 diff -C2 -d -r1.106 -r1.107 *** libos.tex 27 Dec 2002 10:21:19 -0000 1.106 --- libos.tex 5 Jan 2003 22:20:51 -0000 1.107 *************** *** 919,923 **** non-zero fractions depends on the system. ! Future Python releases will change the default of this settings; applications that cannot deal with floating point time stamps can then use this function to turn the feature off. --- 919,923 ---- non-zero fractions depends on the system. ! Future Python releases will change the default of this setting; applications that cannot deal with floating point time stamps can then use this function to turn the feature off. From jackjansen@users.sourceforge.net Sun Jan 5 23:06:47 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:06:47 -0800 Subject: [Python-checkins] python/dist/src/Lib _strptime.py,1.8,1.8.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv9558 Modified Files: Tag: r23a1-branch _strptime.py Log Message: Patch #662053 by Brett Cannon: make strftime work on Mac OS 9. Index: _strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/_strptime.py,v retrieving revision 1.8 retrieving revision 1.8.2.1 diff -C2 -d -r1.8 -r1.8.2.1 *** _strptime.py 30 Dec 2002 22:23:12 -0000 1.8 --- _strptime.py 5 Jan 2003 23:06:44 -0000 1.8.2.1 *************** *** 259,269 **** # '3' needed for when no leading zero. ('2', '%w'), ('10', '%I')): ! try: ! # Done this way to deal with possible lack of locale info ! # manifesting itself as the empty string (i.e., Swedish's ! # lack of AM/PM info). current_format = current_format.replace(old, new) - except ValueError: - pass time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0)) if time.strftime(directive, time_tuple).find('00'): --- 259,268 ---- # '3' needed for when no leading zero. ('2', '%w'), ('10', '%I')): ! # Must deal with possible lack of locale info ! # manifesting itself as the empty string (e.g., Swedish's ! # lack of AM/PM info) or a platform returning a tuple of empty ! # strings (e.g., MacOS 9 having timezone as ('','')). ! if old: current_format = current_format.replace(old, new) time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0)) if time.strftime(directive, time_tuple).find('00'): *************** *** 352,356 **** def __seqToRE(self, to_convert, directive): ! """Convert a list to a regex string for matching directive.""" def sorter(a, b): """Sort based on length. --- 351,355 ---- def __seqToRE(self, to_convert, directive): ! """Convert a list to a regex string for matching a directive.""" def sorter(a, b): """Sort based on length. *************** *** 371,374 **** --- 370,378 ---- to_convert = to_convert[:] # Don't want to change value in-place. + for value in to_convert: + if value != '': + break + else: + return '' to_convert.sort(sorter) regex = '|'.join(to_convert) *************** *** 474,478 **** if locale_time.timezone[0] == locale_time.timezone[1]: pass #Deals with bad locale setup where timezone info is ! # the same; first found on FreeBSD 4.4 -current elif locale_time.timezone[0].lower() == found_zone: tz = 0 --- 478,482 ---- if locale_time.timezone[0] == locale_time.timezone[1]: pass #Deals with bad locale setup where timezone info is ! # the same; first found on FreeBSD 4.4. elif locale_time.timezone[0].lower() == found_zone: tz = 0 From jackjansen@users.sourceforge.net Sun Jan 5 23:06:59 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:06:59 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_strptime.py,1.8,1.8.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv9632 Modified Files: Tag: r23a1-branch test_strptime.py Log Message: Patch #662053 by Brett Cannon: make strftime work on Mac OS 9. Index: test_strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_strptime.py,v retrieving revision 1.8 retrieving revision 1.8.2.1 diff -C2 -d -r1.8 -r1.8.2.1 *** test_strptime.py 26 Dec 2002 16:19:52 -0000 1.8 --- test_strptime.py 5 Jan 2003 23:06:55 -0000 1.8.2.1 *************** *** 125,128 **** --- 125,136 ---- self.assertRaises(TypeError, _strptime.LocaleTime, timezone=range(3)) + def test_unknowntimezone(self): + # Handle timezone set to ('','') properly. + # Fixes bug #661354 + locale_time = _strptime.LocaleTime(timezone=('','')) + self.failUnless("%Z" not in locale_time.LC_date, + "when timezone == ('',''), string.replace('','%Z') is " + "occuring") + class TimeRETests(unittest.TestCase): """Tests for TimeRE.""" *************** *** 181,190 **** for directive in ('a','A','b','B','c','d','H','I','j','m','M','p','S', 'U','w','W','x','X','y','Y','Z','%'): ! compiled = self.time_re.compile("%%%s"% directive) ! found = compiled.match(time.strftime("%%%s" % directive)) self.failUnless(found, "Matching failed on '%s' using '%s' regex" % ! (time.strftime("%%%s" % directive), compiled.pattern)) class StrptimeTests(unittest.TestCase): """Tests for _strptime.strptime.""" --- 189,205 ---- for directive in ('a','A','b','B','c','d','H','I','j','m','M','p','S', 'U','w','W','x','X','y','Y','Z','%'): ! compiled = self.time_re.compile("%" + directive) ! found = compiled.match(time.strftime("%" + directive)) self.failUnless(found, "Matching failed on '%s' using '%s' regex" % ! (time.strftime("%" + directive), compiled.pattern)) + def test_blankpattern(self): + # Make sure when tuple or something has no values no regex is generated. + # Fixes bug #661354 + test_locale = _strptime.LocaleTime(timezone=('','')) + self.failUnless(_strptime.TimeRE(test_locale).pattern("%Z") == '', + "with timezone == ('',''), TimeRE().pattern('%Z') != ''") + class StrptimeTests(unittest.TestCase): """Tests for _strptime.strptime.""" *************** *** 263,267 **** # When gmtime() is used with %Z, entire result of strftime() is empty. # Check for equal timezone names deals with bad locale info when this ! # occurs; first found in FreeBSD 4.4 -current time_tuple = time.localtime() strf_output = time.strftime("%Z") #UTC does not have a timezone --- 278,282 ---- # When gmtime() is used with %Z, entire result of strftime() is empty. # Check for equal timezone names deals with bad locale info when this ! # occurs; first found in FreeBSD 4.4. time_tuple = time.localtime() strf_output = time.strftime("%Z") #UTC does not have a timezone *************** *** 385,389 **** def test_all_julian_days(self): eq = self.assertEqual - # XXX: should 0 be accepted? for i in range(1, 367): # use 2004, since it is a leap year, we have 366 days --- 400,403 ---- From jackjansen@users.sourceforge.net Sun Jan 5 23:07:43 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:07:43 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_unicode.py,1.74,1.74.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv9982 Modified Files: Tag: r23a1-branch test_unicode.py Log Message: Skip exception-propagation test if encoding isn't ascii. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.74 retrieving revision 1.74.2.1 diff -C2 -d -r1.74 -r1.74.2.1 *** test_unicode.py 29 Dec 2002 19:44:06 -0000 1.74 --- test_unicode.py 5 Jan 2003 23:07:39 -0000 1.74.2.1 *************** *** 435,444 **** vereq((u'' in u'abc'), True) vereq(('' in u'abc'), True) ! try: ! u'\xe2' in 'g\xe2teau' ! except UnicodeError: ! pass ! else: ! print '*** contains operator does not propagate UnicodeErrors' print 'done.' --- 435,445 ---- vereq((u'' in u'abc'), True) vereq(('' in u'abc'), True) ! if sys.getdefaultencoding() == 'ascii': ! try: ! u'\xe2' in 'g\xe2teau' ! except UnicodeError: ! pass ! else: ! print '*** contains operator does not propagate UnicodeErrors' print 'done.' From jackjansen@users.sourceforge.net Sun Jan 5 23:08:45 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:08:45 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_frozen.py,1.3,1.3.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv10405 Modified Files: Tag: r23a1-branch test_frozen.py Log Message: On the Mac the frozen import that should fail actually succeeds, and we know it, so skip the test in stead of confusing the end user. Index: test_frozen.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_frozen.py,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -C2 -d -r1.3 -r1.3.2.1 *** test_frozen.py 1 Nov 2002 11:33:00 -0000 1.3 --- test_frozen.py 5 Jan 2003 23:08:42 -0000 1.3.2.1 *************** *** 19,26 **** raise TestFailed, "import __phello__.spam failed:" + str(x) ! try: ! import __phello__.foo ! except ImportError: ! pass ! else: ! raise TestFailed, "import __phello__.foo should have failed" --- 19,27 ---- raise TestFailed, "import __phello__.spam failed:" + str(x) ! if sys.platform != "mac": # On the Mac this import does succeed. ! try: ! import __phello__.foo ! except ImportError: ! pass ! else: ! raise TestFailed, "import __phello__.foo should have failed" From jackjansen@users.sourceforge.net Sun Jan 5 23:10:18 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:10:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.28,1.28.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv11197 Modified Files: Tag: r23a1-branch test_email.py Log Message: The attachment test needs to open the email message in binary (and on the Mac it will fail if this isn't done). This doesn't feel to me like the right fix (I think the email package itself should be fixed) but at least this gets MacPython-OS9 2.3a1 out the door. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.28 retrieving revision 1.28.2.1 diff -C2 -d -r1.28 -r1.28.2.1 *** test_email.py 30 Dec 2002 19:14:38 -0000 1.28 --- test_email.py 5 Jan 2003 23:10:14 -0000 1.28.2.1 *************** *** 51,57 **** ! def openfile(filename): path = os.path.join(os.path.dirname(landmark), 'data', filename) ! return open(path, 'r') --- 51,57 ---- ! def openfile(filename, mode='r'): path = os.path.join(os.path.dirname(landmark), 'data', filename) ! return open(path, mode) *************** *** 1884,1888 **** def test_crlf_separation(self): eq = self.assertEqual ! fp = openfile('msg_26.txt') try: msg = Parser().parse(fp) --- 1884,1888 ---- def test_crlf_separation(self): eq = self.assertEqual ! fp = openfile('msg_26.txt', 'rb') try: msg = Parser().parse(fp) From jackjansen@users.sourceforge.net Sun Jan 5 23:10:52 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:10:52 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts ConfigurePython.py,1.41,1.41.10.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv11454 Modified Files: Tag: r23a1-branch ConfigurePython.py Log Message: Ripped out all the non-Carbon support. Index: ConfigurePython.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/ConfigurePython.py,v retrieving revision 1.41 retrieving revision 1.41.10.1 diff -C2 -d -r1.41 -r1.41.10.1 *** ConfigurePython.py 7 Dec 2001 16:06:59 -0000 1.41 --- ConfigurePython.py 5 Jan 2003 23:10:49 -0000 1.41.10.1 *************** *** 161,167 **** MacOS.splash(SPLASH_COPYCORE) if verbose: ! print "Copying PythonCore..." n = 0 - n = n + mkcorealias('PythonCore', 'PythonCore') n = n + mkcorealias('PythonCoreCarbon', 'PythonCoreCarbon') if n == 0: --- 161,166 ---- MacOS.splash(SPLASH_COPYCORE) if verbose: ! print "Copying PythonCoreCarbon..." n = 0 n = n + mkcorealias('PythonCoreCarbon', 'PythonCoreCarbon') if n == 0: *************** *** 171,200 **** print "Warning: PythonCore not copied to Extensions folder" print " (Applets will not work unless run from the Python folder)" - if sys.argv[0][-7:] == 'Classic': - do_classic = 1 - elif sys.argv[0][-6:] == 'Carbon': - do_classic = 0 - else: - print "I don't know the sys.argv[0] function", sys.argv[0] - if verbose: - print "Configure classic or carbon - ", - rv = string.strip(sys.stdin.readline()) - while rv and rv != "classic" and rv != "carbon": - print "Configure classic or carbon - ", - rv = string.strip(sys.stdin.readline()) - if rv == "classic": - do_classic = 1 - elif rv == "carbon": - do_classic = 0 - else: - return - else: - sys.exit(1) - if do_classic: - MacOS.splash(SPLASH_COPYCLASSIC) - buildcopy(sys.prefix, None, [("PythonInterpreterClassic", "PythonInterpreter")]) - else: - MacOS.splash(SPLASH_COPYCARBON) - buildcopy(sys.prefix, None, [("PythonInterpreterCarbon", "PythonInterpreter")]) MacOS.splash(SPLASH_BUILDAPPLETS) buildapplet(sys.prefix, None, APPLET_LIST) --- 170,173 ---- From jackjansen@users.sourceforge.net Sun Jan 5 23:11:51 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:11:51 -0800 Subject: [Python-checkins] python/dist/src/Mac ReadMe,1.45.2.3,1.45.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac In directory sc8-pr-cvs1:/tmp/cvs-serv11938 Modified Files: Tag: r23a1-branch ReadMe Log Message: These were the file versions used to build MacPYthon-OS9 2.3a1 (barring disasters). Index: ReadMe =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/ReadMe,v retrieving revision 1.45.2.3 retrieving revision 1.45.2.4 diff -C2 -d -r1.45.2.3 -r1.45.2.4 *** ReadMe 5 Jan 2003 00:18:16 -0000 1.45.2.3 --- ReadMe 5 Jan 2003 23:11:48 -0000 1.45.2.4 *************** *** 76,93 **** Python and "import test.regrtest ; test.regrtest.main()". ! test_frozen will fail in MacPython because of different handling on ! frozen modules. This should not be a problem in normal use. ! ! test_email fails with "AssertionError: 2042 != 2". This will be fixed in ! the next release. ! ! test_httplib fails with an unexpected output error. This will be fixed in ! the next release. test_socket fails, this problem is being investigated. - - test_strptime and test_time fail, this problem is being investigated. - - test_unicode fails, this problem is being investigated. Three tests will fail on MacOS9 with MemoryErrors: --- 76,83 ---- Python and "import test.regrtest ; test.regrtest.main()". ! test_httplib fails with an unexpected output error, ! this problem is being investigated. test_socket fails, this problem is being investigated. Three tests will fail on MacOS9 with MemoryErrors: From jackjansen@users.sourceforge.net Sun Jan 5 23:12:23 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:12:23 -0800 Subject: [Python-checkins] python/dist/src/Mac/Build PythonStandSmall.mcp,1.47.2.1,1.47.2.2 PythonCore.mcp,1.41.2.1,1.41.2.2 PythonInterpreter.mcp,1.21.2.1,1.21.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory sc8-pr-cvs1:/tmp/cvs-serv12013 Modified Files: Tag: r23a1-branch PythonStandSmall.mcp PythonCore.mcp PythonInterpreter.mcp Log Message: These were the file versions used to build MacPYthon-OS9 2.3a1 (barring disasters). Index: PythonStandSmall.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonStandSmall.mcp,v retrieving revision 1.47.2.1 retrieving revision 1.47.2.2 diff -C2 -d -r1.47.2.1 -r1.47.2.2 Binary files /tmp/cvsLz0Rfx and /tmp/cvsSvfUtV differ Index: PythonCore.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.mcp,v retrieving revision 1.41.2.1 retrieving revision 1.41.2.2 diff -C2 -d -r1.41.2.1 -r1.41.2.2 Binary files /tmp/cvs2g4w4A and /tmp/cvskBQhn1 differ Index: PythonInterpreter.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonInterpreter.mcp,v retrieving revision 1.21.2.1 retrieving revision 1.21.2.2 diff -C2 -d -r1.21.2.1 -r1.21.2.2 Binary files /tmp/cvsbAhmxJ and /tmp/cvsuVzNPk differ From jackjansen@users.sourceforge.net Sun Jan 5 23:12:38 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:12:38 -0800 Subject: [Python-checkins] python/dist/src/Mac/Distributions src.include,1.7,1.7.12.1 readme.txt,1.8.4.1,1.8.4.2 src.exclude,1.7,1.7.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory sc8-pr-cvs1:/tmp/cvs-serv12291 Modified Files: Tag: r23a1-branch src.include readme.txt src.exclude Log Message: These were the file versions used to build MacPYthon-OS9 2.3a1 (barring disasters). Index: src.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/src.include,v retrieving revision 1.7 retrieving revision 1.7.12.1 diff -C2 -d -r1.7 -r1.7.12.1 *** src.include 30 Oct 2001 22:41:43 -0000 1.7 --- src.include 5 Jan 2003 23:12:35 -0000 1.7.12.1 *************** *** 1,2 **** --- 1,3 ---- + (':.DS_Store', None) (':BeOS', None) (':BuildApplet', None) *************** *** 12,21 **** (':Extensions:Pmw', None) (':Extensions:PyDOM', None) - (':Extensions:README', '') - (':Extensions:README.TOO', '') (':Extensions:audio', None) - (':Extensions:example', '') - (':Extensions:example2', '') - (':Extensions:example3', '') (':Extensions:img', '') (':Extensions:midi', None) --- 13,17 ---- *************** *** 30,33 **** --- 26,30 ---- (':LICENSE', '') (':Lib', '') + (':Mac:.DS_Store', None) (':Mac:Build', '') (':Mac:Build:PythonAppletCFM68K', None) *************** *** 42,45 **** --- 39,43 ---- (':Mac:Contrib', '') (':Mac:Demo', '') + (':Mac:Distributions:(vise)', None) (':Mac:Distributions:68k-shared.exclude', None) (':Mac:Distributions:68k-shared.include', None) *************** *** 68,72 **** (':Mac:ReadMe-dev', None) (':Mac:ReadMe-src', ':ReadMe-src') - (':Mac:Relnotes', ':Relnotes:') (':Mac:Resources', '') (':Mac:TODO', None) --- 66,69 ---- *************** *** 78,82 **** (':Mac:Tools:bruce', None) (':Mac:Tools:macfreeze', '') - (':Mac:Unsupported', '') (':Mac:Wastemods', '') (':Mac:_checkversion.py', None) --- 75,78 ---- *************** *** 85,89 **** (':Mac:mwerks:projects', None) (':Mac:scripts', '') - (':Mac:tclmods', '') (':Misc', '') (':Modules', '') --- 81,84 ---- *************** *** 91,95 **** (':PC', None) (':PCbuild', None) - (':PLAN.txt', '') (':Parser', '') (':PlugIns', None) --- 86,89 ---- *************** *** 142,144 **** (':setup.py', None) (':site-packages', None) ! (':Mac:Distributions:(vise)', None) --- 136,138 ---- (':setup.py', None) (':site-packages', None) ! (':Tools:framer', '') Index: readme.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/readme.txt,v retrieving revision 1.8.4.1 retrieving revision 1.8.4.2 diff -C2 -d -r1.8.4.1 -r1.8.4.2 *** readme.txt 3 Jan 2003 23:54:00 -0000 1.8.4.1 --- readme.txt 5 Jan 2003 23:12:35 -0000 1.8.4.2 *************** *** 33,38 **** add the missing stuff. Make sure of all settings for the new files (esp. "where" and "gestalt" are easy to miss). ! - test on virgin systems (OSX, OS9, OS8 without Carbon). Make sure to test ! tkinter too. - Remove the local installation so you don't get confused by it. - checkin everything except PythonX.Y.vct. --- 33,37 ---- add the missing stuff. Make sure of all settings for the new files (esp. "where" and "gestalt" are easy to miss). ! - test on virgin systems (both OS9 and OSX). - Remove the local installation so you don't get confused by it. - checkin everything except PythonX.Y.vct. Index: src.exclude =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/src.exclude,v retrieving revision 1.7 retrieving revision 1.7.12.1 diff -C2 -d -r1.7 -r1.7.12.1 *** src.exclude 30 Oct 2001 22:41:39 -0000 1.7 --- src.exclude 5 Jan 2003 23:12:36 -0000 1.7.12.1 *************** *** 9,12 **** --- 9,13 ---- *.lib *.pyc + *.pyo *.slb *.xMAP *************** *** 20,22 **** PyIDE-src [(]*[)] - *.pyo --- 21,22 ---- From jackjansen@users.sourceforge.net Sun Jan 5 23:13:22 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:13:22 -0800 Subject: [Python-checkins] python/dist/src/Mac/Distributions/(vise) Python 2.3.vct,1.4.2.1,1.4.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions/(vise) In directory sc8-pr-cvs1:/tmp/cvs-serv12380 Modified Files: Tag: r23a1-branch Python 2.3.vct Log Message: These were the file versions used to build MacPYthon-OS9 2.3a1 (barring disasters). Index: Python 2.3.vct =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/(vise)/Python 2.3.vct,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -C2 -d -r1.4.2.1 -r1.4.2.2 Binary files /tmp/cvslePz6N and /tmp/cvsKRw7Fy differ From jackjansen@users.sourceforge.net Sun Jan 5 23:13:36 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:13:36 -0800 Subject: [Python-checkins] python/dist/src/Mac/Include macbuildno.h,1.25,1.25.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory sc8-pr-cvs1:/tmp/cvs-serv12760 Modified Files: Tag: r23a1-branch macbuildno.h Log Message: These were the file versions used to build MacPYthon-OS9 2.3a1 (barring disasters). Index: macbuildno.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/macbuildno.h,v retrieving revision 1.25 retrieving revision 1.25.4.1 diff -C2 -d -r1.25 -r1.25.4.1 *** macbuildno.h 20 Jun 2002 22:56:22 -0000 1.25 --- macbuildno.h 5 Jan 2003 23:13:33 -0000 1.25.4.1 *************** *** 1 **** ! #define BUILD 144 --- 1 ---- ! #define BUILD 147 From nnorwitz@users.sourceforge.net Sun Jan 5 23:19:45 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:19:45 -0800 Subject: [Python-checkins] python/dist/src/Lib tarfile.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14549/Lib Added Files: tarfile.py Log Message: SF #651082, tarfile module implementation from Lars Gustäbel --- NEW FILE: tarfile.py --- #!/usr/bin/env python # -*- coding: iso-8859-1 -*- #------------------------------------------------------------------- # tarfile.py #------------------------------------------------------------------- # Copyright (C) 2002 Lars Gustäbel # All rights reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. [...1888 lines suppressed...] self.tarfile.addfile(zinfo, StringIO.StringIO(bytes)) def close(self): self.tarfile.close() #class TarFileCompat #-------------------- # exported functions #-------------------- def is_tarfile(name): """Return True if name points to a tar archive that we are able to handle, else return False. """ try: t = open(name) t.close() return True except TarError: return False open = TarFile.open From nnorwitz@users.sourceforge.net Sun Jan 5 23:19:45 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:19:45 -0800 Subject: [Python-checkins] python/dist/src/Lib/test testtar.tar,NONE,1.1 test_tarfile.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14549/Lib/test Added Files: testtar.tar test_tarfile.py Log Message: SF #651082, tarfile module implementation from Lars Gustäbel --- NEW FILE: testtar.tar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: test_tarfile.py --- import sys import os import shutil import unittest import tarfile from test import test_support # Check for our compression modules. try: import gzip except ImportError: gzip = None try: import bz2 except ImportError: bz2 = None def path(path): return test_support.findfile(path) testtar = path("testtar.tar") tempdir = path("testtar.dir") tempname = path("testtar.tmp") membercount = 10 def tarname(comp=""): if not comp: return testtar return "%s.%s" % (testtar, comp) def dirname(): if not os.path.exists(tempdir): os.mkdir(tempdir) return tempdir def tmpname(): return tempname class BaseTest(unittest.TestCase): comp = '' mode = 'r' sep = ':' def setUp(self): mode = self.mode + self.sep + self.comp self.tar = tarfile.open(tarname(self.comp), mode) def tearDown(self): self.tar.close() class ReadTest(BaseTest): def test(self): """Test member extraction. """ members = 0 for tarinfo in self.tar: members += 1 if not tarinfo.isreg(): continue f = self.tar.extractfile(tarinfo) self.assert_(len(f.read()) == tarinfo.size, "size read does not match expected size") f.close() self.assert_(members == membercount, "could not find all members") def test_sparse(self): """Test sparse member extraction. """ if self.sep != "|": f1 = self.tar.extractfile("S-SPARSE") f2 = self.tar.extractfile("S-SPARSE-WITH-NULLS") self.assert_(f1.read() == f2.read(), "_FileObject failed on sparse file member") def test_readlines(self): """Test readlines() method of _FileObject. """ if self.sep != "|": filename = "0-REGTYPE-TEXT" self.tar.extract(filename, dirname()) lines1 = file(os.path.join(dirname(), filename), "r").readlines() lines2 = self.tar.extractfile(filename).readlines() self.assert_(lines1 == lines2, "_FileObject.readline() does not work correctly") def test_seek(self): """Test seek() method of _FileObject, incl. random reading. """ if self.sep != "|": filename = "0-REGTYPE" self.tar.extract(filename, dirname()) data = file(os.path.join(dirname(), filename), "rb").read() tarinfo = self.tar.getmember(filename) fobj = self.tar.extractfile(tarinfo) text = fobj.read() fobj.seek(0) self.assert_(0 == fobj.tell(), "seek() to file's start failed") fobj.seek(2048, 0) self.assert_(2048 == fobj.tell(), "seek() to absolute position failed") fobj.seek(-1024, 1) self.assert_(1024 == fobj.tell(), "seek() to negative relative position failed") fobj.seek(1024, 1) self.assert_(2048 == fobj.tell(), "seek() to positive relative position failed") s = fobj.read(10) self.assert_(s == data[2048:2058], "read() after seek failed") fobj.seek(0, 2) self.assert_(tarinfo.size == fobj.tell(), "seek() to file's end failed") self.assert_(fobj.read() == "", "read() at file's end did not return empty string") fobj.seek(-tarinfo.size, 2) self.assert_(0 == fobj.tell(), "relative seek() to file's start failed") fobj.seek(512) s1 = fobj.readlines() fobj.seek(512) s2 = fobj.readlines() self.assert_(s1 == s2, "readlines() after seek failed") fobj.close() class ReadStreamTest(ReadTest): sep = "|" def test(self): """Test member extraction, and for StreamError when seeking backwards. """ ReadTest.test(self) tarinfo = self.tar.getmembers()[0] f = self.tar.extractfile(tarinfo) self.assertRaises(tarfile.StreamError, f.read) def test_stream(self): """Compare the normal tar and the stream tar. """ stream = self.tar tar = tarfile.open(tarname(), 'r') while 1: t1 = tar.next() t2 = stream.next() if t1 is None: break self.assert_(t2 is not None, "stream.next() failed.") if t2.islnk() or t2.issym(): self.assertRaises(tarfile.StreamError, stream.extractfile, t2) continue v1 = tar.extractfile(t1) v2 = stream.extractfile(t2) if v1 is None: continue self.assert_(v2 is not None, "stream.extractfile() failed") self.assert_(v1.read() == v2.read(), "stream extraction failed") stream.close() class WriteTest(BaseTest): mode = 'w' def setUp(self): mode = self.mode + self.sep + self.comp self.src = tarfile.open(tarname(self.comp), 'r') self.dst = tarfile.open(tmpname(), mode) def tearDown(self): self.src.close() self.dst.close() def test_posix(self): self.dst.posix = 1 self._test() def test_nonposix(self): self.dst.posix = 0 self._test() def _test(self): for tarinfo in self.src: if not tarinfo.isreg(): continue f = self.src.extractfile(tarinfo) if self.dst.posix and len(tarinfo.name) > tarfile.LENGTH_NAME: self.assertRaises(ValueError, self.dst.addfile, tarinfo, f) else: self.dst.addfile(tarinfo, f) class WriteStreamTest(WriteTest): sep = '|' # Gzip TestCases class ReadTestGzip(ReadTest): comp = "gz" class ReadStreamTestGzip(ReadStreamTest): comp = "gz" class WriteTestGzip(WriteTest): comp = "gz" class WriteStreamTestGzip(WriteStreamTest): comp = "gz" if bz2: # Bzip2 TestCases class ReadTestBzip2(ReadTestGzip): comp = "bz2" class ReadStreamTestBzip2(ReadStreamTestGzip): comp = "bz2" class WriteTestBzip2(WriteTest): comp = "bz2" class WriteStreamTestBzip2(WriteStreamTestGzip): comp = "bz2" # If importing gzip failed, discard the Gzip TestCases. if not gzip: del ReadTestGzip del ReadStreamTestGzip del WriteTestGzip del WriteStreamTestGzip if __name__ == "__main__": if gzip: # create testtar.tar.gz gzip.open(tarname("gz"), "wb").write(file(tarname(), "rb").read()) if bz2: # create testtar.tar.bz2 bz2.BZ2File(tarname("bz2"), "wb").write(file(tarname(), "rb").read()) try: unittest.main() finally: if gzip: os.remove(tarname("gz")) if bz2: os.remove(tarname("bz2")) if os.path.exists(tempdir): shutil.rmtree(tempdir) if os.path.exists(tempname): os.remove(tempname) From nnorwitz@users.sourceforge.net Sun Jan 5 23:19:45 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:19:45 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libtarfile.tex,NONE,1.1 lib.tex,1.210,1.211 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv14549/Doc/lib Modified Files: lib.tex Added Files: libtarfile.tex Log Message: SF #651082, tarfile module implementation from Lars Gustäbel --- NEW FILE: libtarfile.tex --- \section{\module{tarfile} --- Read and write tar archive files} \declaremodule{standard}{tarfile} \modulesynopsis{Read and write tar-format archive files.} \versionadded{2.3} \moduleauthor{Lars Gust\"abel}{lars@gustaebel.de} \sectionauthor{Lars Gust\"abel}{lars@gustaebel.de} The \module{tarfile} module makes it possible to read and create tar archives. Some facts and figures: \begin{itemize} \item reads and writes \module{gzip} and \module{bzip2} compressed archives. \item creates POSIX 1003.1-1990 compliant or GNU tar compatible archives. \item reads GNU tar extensions \emph{longname}, \emph{longlink} and \emph{sparse}. \item stores pathnames of unlimited length using GNU tar extensions. \item handles directories, regular files, hardlinks, symbolic links, fifos, character devices and block devices and is able to acquire and restore file information like timestamp, access permissions and owner. \item can handle tape devices. \end{itemize} \begin{funcdesc}{open}{\optional{name\optional{, mode \optional{, fileobj\optional{, bufsize}}}}} Return a \class{TarFile} object for the pathname \var{name}. For detailed information on \class{TarFile} objects, see \citetitle{TarFile Objects} (section \ref{tarfile-objects}). \var{mode} has to be a string of the form \code{'filemode[:compression]'}, it defaults to \code{'r'}. Here is a full list of mode combinations: \begin{tableii}{c|l}{code}{mode}{action} \lineii{'r'}{Open for reading with transparent compression (recommended).} \lineii{'r:'}{Open for reading exclusively without compression.} \lineii{'r:gz'}{Open for reading with gzip compression.} \lineii{'r:bz2'}{Open for reading with bzip2 compression.} \lineii{'a' or 'a:'}{Open for appending with no compression.} \lineii{'w' or 'w:'}{Open for uncompressed writing.} \lineii{'w:gz'}{Open for gzip compressed writing.} \lineii{'w:bz2'}{Open for bzip2 compressed writing.} \end{tableii} Note that \code{'a:gz'} or \code{'a:bz2'} is not possible. If \var{mode} is not suitable to open a certain (compressed) file for reading, \exception{ReadError} is raised. Use \var{mode} \code{'r'} to avoid this. If a compression method is not supported, \exception{CompressionError} is raised. If \var{fileobj} is specified, it is used as an alternative to a file object opened for \var{name}. For special purposes, there is a second format for \var{mode}: \code{'filemode|[compression]'}. \code{open} will return a \class{TarFile} object that processes its data as a stream of blocks. No random seeking will be done on the file. If given, \var{fileobj} may be any object that has a \code{read()} resp. \code{write()} method. \var{bufsize} specifies the blocksize and defaults to \code{20 * 512} bytes. Use this variant in combination with e.g. \code{sys.stdin}, a socket file object or a tape device. However, such a \class{TarFile} object is limited in that it does not allow to be accessed randomly, see \citetitle{Examples} (section \ref{tar-examples}). The currently possible modes: \begin{tableii}{c|l}{code}{mode}{action} \lineii{'r|'}{Open a \emph{stream} of uncompressed tar blocks for reading.} \lineii{'r|gz'}{Open a gzip compressed \emph{stream} for reading.} \lineii{'r|bz2'}{Open a bzip2 compressed \emph{stream} for reading.} \lineii{'w|'}{Open an uncompressed \emph{stream} for writing.} \lineii{'w|gz'}{Open an gzip compressed \emph{stream} for writing.} \lineii{'w|bz2'}{Open an bzip2 compressed \emph{stream} for writing.} \end{tableii} \end{funcdesc} \begin{classdesc*}{TarFile} Class for reading and writing tar archives. Do not use this class directly, better use \function{open()} instead. See \citetitle{TarFile Objects} (section \ref{tarfile-objects}). \end{classdesc*} \begin{funcdesc}{is_tarfile}{name} Return \code{True} if \var{name} is a tar archive file, that the \module{tarfile} module can read. \end{funcdesc} \begin{classdesc}{TarFileCompat}{filename\optional{, mode\optional{, compression}}} Class for limited access to tar archives with a \code{zipfile}-like interface. Please consult the documentation of \code{zipfile} for more details. \code{compression} must be one of the following constants: \begin{datadesc}{TAR_PLAIN} Constant for an uncompressed tar archive. \end{datadesc} \begin{datadesc}{TAR_GZIPPED} Constant for a \code{gzip} compressed tar archive. \end{datadesc} \end{classdesc} \begin{excdesc}{TarError} Base class for all \module{tarfile} exceptions. \end{excdesc} \begin{excdesc}{ReadError} Is raised when a tar archive is opened, that either cannot be handled by the \module{tarfile} module or is somehow invalid. \end{excdesc} \begin{excdesc}{CompressionError} Is raised when a compression method is not supported or when the data cannot be decoded properly. \end{excdesc} \begin{excdesc}{StreamError} Is raised for the limitations that are typical for stream-like \class{TarFile} objects. \end{excdesc} \begin{excdesc}{ExtractError} Is raised for \emph{non-fatal} errors when using \method{extract()}, but only if \member{TarFile.errorlevel}\code{ == 2}. \end{excdesc} \begin{seealso} \seemodule[module-zipfile]{zipfile}{Documentation of the \code{zipfile} standard module.} \seetitle[http://www.gnu.org/manual/tar/html_chapter/tar_8.html\#SEC118] {GNU tar manual, Standard Section}{Documentation for tar archive files, including GNU tar extensions.} \end{seealso} %----------------- % TarFile Objects %----------------- \subsection{TarFile Objects \label{tarfile-objects}} The \class{TarFile} object provides an interface to a tar archive. A tar archive is a sequence of blocks. An archive member (a stored file) is made up of a header block followed by data blocks. It is possible, to store a file in a tar archive several times. Each archive member is represented by a \class{TarInfo} object, see \citetitle{TarInfo Objects} (section \ref{tarinfo-objects}) for details. \begin{classdesc}{TarFile}{\optional{name \optional{, mode\optional{, fileobj}}}} Open an \emph{(uncompressed)} tar archive \var{name}. \var{mode} is either \code{'r'} to read from an existing archive, \code{'a'} to append data to an existing file or \code{'w'} to create a new file overwriting an existing one. \var{mode} defaults to \code{'r'}. If \var{fileobj} is given, it is used for reading or writing data. If it can be determined, \var{mode} is overridden by \var{fileobj}'s mode. \begin{notice} \var{fileobj} is not closed, when \class{TarFile} is closed. \end{notice} \end{classdesc} \begin{methoddesc}{open}{...} Alternative constructor. The \function{open()} function on module level is actually a shortcut to this classmethod. See section \ref{module-tarfile} for details. \end{methoddesc} \begin{methoddesc}{getmember}{name} Return a \class{TarInfo} object for member \var{name}. If \var{name} can not be found in the archive, \exception{KeyError} is raised. \begin{notice} If a member occurs more than once in the archive, its last occurence is assumed to be the most up-to-date version. \end{notice} \end{methoddesc} \begin{methoddesc}{getmembers}{} Return the members of the archive as a list of \class{TarInfo} objects. The list has the same order as the members in the archive. \end{methoddesc} \begin{methoddesc}{getnames}{} Return the members as a list of their names. It has the same order as the list returned by \method{getmembers()}. \end{methoddesc} \begin{methoddesc}{list}{verbose=True} Print a table of contents to \code{sys.stdout}. If \var{verbose} is \code{False}, only the names of the members are printed. If it is \code{True}, an \code{"ls -l"}-like output is produced. \end{methoddesc} \begin{methoddesc}{next}{} Return the next member of the archive as a \class{TarInfo} object, when \class{TarFile} is opened for reading. Return \code{None} if there is no more available. \end{methoddesc} \begin{methoddesc}{extract}{member\optional{, path}} Extract a member from the archive to the current working directory, using its full name. Its file information is extracted as accurately as possible. \var{member} may be a filename or a \class{TarInfo} object. You can specify a different directory using \var{path}. \end{methoddesc} \begin{methoddesc}{extractfile}{member} Extract a member from the archive as a file object. \var{member} may be a filename or a \class{TarInfo} object. If \var{member} is a regular file, a file-like object is returned. If \var{member} is a link, a file-like object is constructed from the link's target. If \var{member} is none of the above, \code{None} is returned. \begin{notice} The file-like object is read-only and provides the following methods: \method{read()}, \method{readline()}, \method{readlines()}, \method{seek()}, \method{tell()}. \end{notice} \end{methoddesc} \begin{methoddesc}{add}{name\optional{, arcname\optional{, recursive=True}}} Add the file \var{name} to the archive. \var{name} may be any type of file (directory, fifo, symbolic link, etc.). If given, \var{arcname} specifies an alternative name for the file in the archive. Directories are added recursively by default. This can be avoided by setting \var{recursive} to \code{False}. \end{methoddesc} \begin{methoddesc}{addfile}{tarinfo\optional{, fileobj}} Add the \class{TarInfo} object \var{tarinfo} to the archive. If \var{fileobj} is given, \code{tarinfo.size} bytes are read from it and added to the archive. You can create \class{TarInfo} objects using \method{gettarinfo()}. \begin{notice} On Windows platforms, \var{fileobj} should always be opened with mode \code{'rb'} to avoid irritation about the file size. \end{notice} \end{methoddesc} \begin{methoddesc}{gettarinfo}{\optional{name\optional{, arcname \optional{, fileobj}}}} Create a \class{TarInfo} object for either the file \var{name} or the file object \var{fileobj} (using \code{os.fstat()} on its file descriptor). You can modify some of the \class{TarInfo}'s attributes before you add it using \method{addfile()}. If given, \var{arcname} specifies an alternative name for the file in the archive. \end{methoddesc} \begin{methoddesc}{close}{} Close the \class{TarFile}. In write-mode, two finishing zero blocks are appended to the archive. \end{methoddesc} \begin{memberdesc}{posix=True} If \code{True}, create a POSIX 1003.1-1990 compliant archive. GNU extensions are not used, because they are not part of the POSIX standard. This limits the length of filenames to at most 256 and linknames to 100 characters. A \exception{ValueError} is raised, if a pathname exceeds this limit. If \code{False}, create a GNU tar compatible archive. It will not be POSIX compliant, but can store pathnames of unlimited length. \end{memberdesc} \begin{memberdesc}{dereference=False} If \code{False}, add symbolic and hard links to archive. If \code{True}, add the content of the target files to the archive. This has no effect on systems that do not support links. \end{memberdesc} \begin{memberdesc}{ignore_zeros=False} If \code{False}, treat an empty block as the end of the archive. If \code{True}, skip empty (and invalid) blocks and try to get as many members as possible. This is only useful for concatenated or damaged archives. \end{memberdesc} \begin{memberdesc}{debug=0} To be set from \code{0}(no debug messages) up to \code{3}(all debug messages). The messages are written to \code{sys.stdout}. \end{memberdesc} \begin{memberdesc}{errorlevel=0} If \code{0}, all errors are ignored when using \method{extract()}. Nevertheless, they appear as error messages in the debug output, when debugging is enabled. If \code{1}, all \emph{fatal} errors are raised as \exception{OSError} or \exception{IOError} exceptions. If \code{2}, all \emph{non-fatal} errors are raised as \exception{TarError} exceptions as well. \end{memberdesc} %----------------- % TarInfo Objects %----------------- \subsection{TarInfo Objects \label{tarinfo-objects}} A \class{TarInfo} object represents one member in a \class{TarFile}. Aside from storing all required attributes of a file (like file type, size, time, permissions, owner etc.), it provides some useful methods to determine its type. It does \emph{not} contain the file's data itself. \class{TarInfo} objects are returned by \code{TarFile}'s methods \code{getmember()}, \code{getmembers()} and \code{gettarinfo()}. \begin{classdesc}{TarInfo}{\optional{name}} Create a \class{TarInfo} object. \end{classdesc} \begin{methoddesc}{frombuf}{} Create and return a \class{TarInfo} object from a string buffer. \end{methoddesc} \begin{methoddesc}{tobuf}{} Create a string buffer from a \class{TarInfo} object. \end{methoddesc} A \code{TarInfo} object has the following public data attributes: \begin{memberdesc}{name} Name of the archive member. \end{memberdesc} \begin{memberdesc}{size} Size in bytes. \end{memberdesc} \begin{memberdesc}{mtime} Time of last modification. \end{memberdesc} \begin{memberdesc}{mode} Permission bits. \end{memberdesc} \begin{memberdesc}{type} File type. \var{type} is usually one of these constants: \code{REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE}. To determine the type of a \class{TarInfo} object more conveniently, use the \code{is_*()} methods below. \end{memberdesc} \begin{memberdesc}{linkname} Name of the target file name, which is only present in \class{TarInfo} objects of type LNKTYPE and SYMTYPE. \end{memberdesc} \begin{memberdesc}{uid, gid} User and group ID of who originally stored this member. \end{memberdesc} \begin{memberdesc}{uname, gname} User and group name. \end{memberdesc} A \class{TarInfo} object also provides some convenient query methods: \begin{methoddesc}{isfile}{} Return \code{True} if the \class{Tarinfo} object is a regular file. \end{methoddesc} \begin{methoddesc}{isreg}{} Same as \method{isfile()}. \end{methoddesc} \begin{methoddesc}{isdir}{} Return \code{True} if it is a directory. \end{methoddesc} \begin{methoddesc}{issym}{} Return \code{True} if it is a symbolic link. \end{methoddesc} \begin{methoddesc}{islnk}{} Return \code{True} if it is a hard link. \end{methoddesc} \begin{methoddesc}{ischr}{} Return \code{True} if it is a character device. \end{methoddesc} \begin{methoddesc}{isblk}{} Return \code{True} if it is a block device. \end{methoddesc} \begin{methoddesc}{isfifo}{} Return \code{True} if it is a FIFO. \end{methoddesc} \begin{methoddesc}{isdev}{} Return \code{True} if it is one of character device, block device or FIFO. \end{methoddesc} %------------------------ % Examples %------------------------ \subsection{Examples \label{tar-examples}} How to create an uncompressed tar archive from a list of filenames: \begin{verbatim} import tarfile tar = tarfile.open("sample.tar", "w") for name in ["foo", "bar", "quux"]: tar.add(name) tar.close() \end{verbatim} How to read a gzip compressed tar archive and display some member information: \begin{verbatim} import tarfile tar = tarfile.open("sample.tar.gz", "r:gz") for tarinfo in tar: print tarinfo.name, "is", tarinfo.size, "bytes in size and is", if tarinfo.isreg(): print "a regular file." elif tarinfo.isdir(): print "a directory." else: print "something else." tar.close() \end{verbatim} How to create a tar archive with faked information: \begin{verbatim} import tarfile tar = tarfile.open("sample.tar.gz", "w:gz") for name in namelist: tarinfo = tar.gettarinfo(name, "fakeproj-1.0/" + name) tarinfo.uid = 123 tarinfo.gid = 456 tarinfo.uname = "johndoe" tarinfo.gname = "fake" tar.addfile(tarinfo, file(name)) tar.close() \end{verbatim} The \emph{only} way to extract an uncompressed tar stream from \code{sys.stdin}: \begin{verbatim} import sys import tarfile tar = tarfile.open(mode="r|", fileobj=sys.stdin) for tarinfo in tar: tar.extract(tarinfo) tar.close() \end{verbatim} Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.210 retrieving revision 1.211 diff -C2 -d -r1.210 -r1.211 *** lib.tex 1 Jan 2003 20:34:00 -0000 1.210 --- lib.tex 5 Jan 2003 23:19:41 -0000 1.211 *************** *** 129,132 **** --- 129,133 ---- \input{libfileinput} \input{libxreadlines} + \input{libtarfile} \input{libcalendar} \input{libcmd} From nnorwitz@users.sourceforge.net Sun Jan 5 23:20:13 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:20:13 -0800 Subject: [Python-checkins] python/dist/src/Doc Makefile.deps,1.94,1.95 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory sc8-pr-cvs1:/tmp/cvs-serv14549/Doc Modified Files: Makefile.deps Log Message: SF #651082, tarfile module implementation from Lars Gustäbel Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.94 retrieving revision 1.95 diff -C2 -d -r1.94 -r1.95 *** Makefile.deps 2 Jan 2003 05:00:12 -0000 1.94 --- Makefile.deps 5 Jan 2003 23:19:41 -0000 1.95 *************** *** 330,333 **** --- 330,334 ---- lib/tkinter.tex \ lib/libturtle.tex \ + lib/libtarfile.tex \ lib/libcfgparser.tex From nnorwitz@users.sourceforge.net Sun Jan 5 23:20:13 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 15:20:13 -0800 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.221,1.222 NEWS,1.601,1.602 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv14549/Misc Modified Files: ACKS NEWS Log Message: SF #651082, tarfile module implementation from Lars Gustäbel Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.221 retrieving revision 1.222 diff -C2 -d -r1.221 -r1.222 *** ACKS 31 Dec 2002 12:55:14 -0000 1.221 --- ACKS 5 Jan 2003 23:19:40 -0000 1.222 *************** *** 197,200 **** --- 197,201 ---- Dag Gruneau Michael Guravage + Lars Gustäbel Barry Haddow Paul ten Hagen Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.601 retrieving revision 1.602 diff -C2 -d -r1.601 -r1.602 *** NEWS 4 Jan 2003 18:17:36 -0000 1.601 --- NEWS 5 Jan 2003 23:19:40 -0000 1.602 *************** *** 64,67 **** --- 64,71 ---- See SF bug #659228. + - New module tarfile from Lars Gustäbel provides a comprehensive interface + to tar archive files with transparent gzip and bzip2 compression. + See SF patch #651082. + Tools/Demos From nnorwitz@users.sourceforge.net Mon Jan 6 06:51:38 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 22:51:38 -0800 Subject: [Python-checkins] python/dist/src/Lib urlparse.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv3304/Lib Modified Files: urlparse.py Log Message: SF feature #618024, urlparse fails on imap:// Index: urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urlparse.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** urlparse.py 16 Oct 2002 21:21:39 -0000 1.35 --- urlparse.py 6 Jan 2003 06:51:36 -0000 1.36 *************** *** 9,26 **** # A classification of schemes ('' means apply by default) ! uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'wais', 'file', 'https', 'shttp', 'prospero', 'rtsp', 'rtspu', ''] ! uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'wais', 'file', 'https', 'shttp', 'snews', 'prospero', 'rtsp', 'rtspu', ''] non_hierarchical = ['gopher', 'hdl', 'mailto', 'news', 'telnet', 'wais', ! 'snews', 'sip', ] ! uses_params = ['ftp', 'hdl', 'prospero', 'http', 'https', 'shttp', 'rtsp', 'rtspu', 'sip', ''] ! uses_query = ['http', 'wais', 'https', 'shttp', 'gopher', 'rtsp', 'rtspu', 'sip', --- 9,26 ---- # A classification of schemes ('' means apply by default) ! uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap', 'wais', 'file', 'https', 'shttp', 'prospero', 'rtsp', 'rtspu', ''] ! uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', 'file', 'https', 'shttp', 'snews', 'prospero', 'rtsp', 'rtspu', ''] non_hierarchical = ['gopher', 'hdl', 'mailto', 'news', 'telnet', 'wais', ! 'imap', 'snews', 'sip', ] ! uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap', 'https', 'shttp', 'rtsp', 'rtspu', 'sip', ''] ! uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'gopher', 'rtsp', 'rtspu', 'sip', From nnorwitz@users.sourceforge.net Mon Jan 6 06:58:33 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 22:58:33 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_urlparse.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv4814/Lib/test Modified Files: test_urlparse.py Log Message: SF feature #618024, urlparse fails on imap:// Index: test_urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_urlparse.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_urlparse.py 16 Oct 2002 21:02:36 -0000 1.9 --- test_urlparse.py 6 Jan 2003 06:58:31 -0000 1.10 *************** *** 26,29 **** --- 26,32 ---- ('file', '', '/tmp/junk.txt', '', '', ''), ('file', '', '/tmp/junk.txt', '', '')), + ('imap://mail.python.org/mbox1', + ('imap', 'mail.python.org', '/mbox1', '', '', ''), + ('imap', 'mail.python.org', '/mbox1', '', '')), ]: result = urlparse.urlparse(url) From nnorwitz@users.sourceforge.net Mon Jan 6 06:51:38 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 05 Jan 2003 22:51:38 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.602,1.603 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv3304/Misc Modified Files: NEWS Log Message: SF feature #618024, urlparse fails on imap:// Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.602 retrieving revision 1.603 diff -C2 -d -r1.602 -r1.603 *** NEWS 5 Jan 2003 23:19:40 -0000 1.602 --- NEWS 6 Jan 2003 06:51:36 -0000 1.603 *************** *** 68,71 **** --- 68,72 ---- See SF patch #651082. + - urlparse can now parse imap:// URLs. See SF feature request #618024. Tools/Demos From rhettinger@users.sourceforge.net Mon Jan 6 10:33:59 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 02:33:59 -0800 Subject: [Python-checkins] python/dist/src/Objects stringobject.c,2.201,2.202 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv28415 Modified Files: stringobject.c Log Message: Optimize string_repeat. Christian Tismer pointed out the high cost of the loop overhead and function call overhead for 'c' * n where n is large. Accordingly, the new code only makes lg2(n) loops. Interestingly, 'c' * 1000 * 1000 ran a bit faster with old code. At some point, the loop and function call overhead became cheaper than invalidating the cache with lengthy memcpys. But for more typical sizes of n, the new code runs much faster and for larger values of n it runs only a bit slower. Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.201 retrieving revision 2.202 diff -C2 -d -r2.201 -r2.202 *** stringobject.c 29 Dec 2002 19:44:06 -0000 2.201 --- stringobject.c 6 Jan 2003 10:33:56 -0000 2.202 *************** *** 934,937 **** --- 934,938 ---- { register int i; + register int j; register int size; register PyStringObject *op; *************** *** 966,971 **** op->ob_shash = -1; op->ob_sstate = SSTATE_NOT_INTERNED; ! for (i = 0; i < size; i += a->ob_size) ! memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); op->ob_sval[size] = '\0'; return (PyObject *) op; --- 967,980 ---- op->ob_shash = -1; op->ob_sstate = SSTATE_NOT_INTERNED; ! i = 0; ! if (i < size) { ! memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); ! i = (int) a->ob_size; ! } ! while (i < size) { ! j = (i <= size-i) ? i : size-i; ! memcpy(op->ob_sval+i, op->ob_sval, j); ! i += j; ! } op->ob_sval[size] = '\0'; return (PyObject *) op; From jvr@users.sourceforge.net Mon Jan 6 11:15:09 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Mon, 06 Jan 2003 03:15:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macresource.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv11372 Modified Files: macresource.py Log Message: always also search on sys.path for res files Index: macresource.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macresource.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** macresource.py 30 Dec 2002 22:04:20 -0000 1.1 --- macresource.py 6 Jan 2003 11:15:05 -0000 1.2 *************** *** 50,56 **** mod = sys.modules[modname] if hasattr(mod, '__file__'): ! searchdirs = [os.path.split(mod.__file__)[0]] ! if not searchdirs: ! searchdirs = sys.path # And look for the file --- 50,55 ---- mod = sys.modules[modname] if hasattr(mod, '__file__'): ! searchdirs = [os.path.dirname(mod.__file__)] ! searchdirs.extend(sys.path) # And look for the file From nnorwitz@users.sourceforge.net Mon Jan 6 16:52:05 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 06 Jan 2003 08:52:05 -0800 Subject: [Python-checkins] python/dist/src/Doc Makefile.deps,1.95,1.96 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory sc8-pr-cvs1:/tmp/cvs-serv13119 Modified Files: Makefile.deps Log Message: SF #642236, optparse LaTeX docs by Johannes Gijsbers Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.95 retrieving revision 1.96 diff -C2 -d -r1.95 -r1.96 *** Makefile.deps 5 Jan 2003 23:19:41 -0000 1.95 --- Makefile.deps 6 Jan 2003 16:51:32 -0000 1.96 *************** *** 143,146 **** --- 143,150 ---- lib/libtime.tex \ lib/libgetopt.tex \ + lib/liboptparse.tex \ + lib/caseless.py \ + lib/required_1.py \ + lib/required_2.py \ lib/libtempfile.tex \ lib/liberrno.tex \ From rhettinger@users.sourceforge.net Mon Jan 6 12:30:56 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 04:30:56 -0800 Subject: [Python-checkins] python/dist/src/Lib urlparse.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv4016 Modified Files: urlparse.py Log Message: Used dictionaries rather than lists for membership testing. Index: urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urlparse.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** urlparse.py 6 Jan 2003 06:51:36 -0000 1.36 --- urlparse.py 6 Jan 2003 12:30:53 -0000 1.37 *************** *** 9,32 **** # A classification of schemes ('' means apply by default) ! uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap', 'wais', 'file', 'https', 'shttp', ! 'prospero', 'rtsp', 'rtspu', ''] ! uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', 'file', 'https', 'shttp', 'snews', ! 'prospero', 'rtsp', 'rtspu', ''] ! non_hierarchical = ['gopher', 'hdl', 'mailto', 'news', 'telnet', 'wais', 'imap', 'snews', 'sip', ! ] ! uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap', 'https', 'shttp', 'rtsp', 'rtspu', 'sip', ! ''] ! uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'gopher', 'rtsp', 'rtspu', 'sip', ! ''] ! uses_fragment = ['ftp', 'hdl', 'http', 'gopher', 'news', 'nntp', 'wais', 'https', 'shttp', 'snews', ! 'file', 'prospero', ''] # Characters valid in scheme names --- 9,32 ---- # A classification of schemes ('' means apply by default) ! uses_relative = dict.fromkeys(['ftp', 'http', 'gopher', 'nntp', 'imap', 'wais', 'file', 'https', 'shttp', ! 'prospero', 'rtsp', 'rtspu', '']) ! uses_netloc = dict.fromkeys(['ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', 'file', 'https', 'shttp', 'snews', ! 'prospero', 'rtsp', 'rtspu', '']) ! non_hierarchical = dict.fromkeys(['gopher', 'hdl', 'mailto', 'news', 'telnet', 'wais', 'imap', 'snews', 'sip', ! ]) ! uses_params = dict.fromkeys(['ftp', 'hdl', 'prospero', 'http', 'imap', 'https', 'shttp', 'rtsp', 'rtspu', 'sip', ! '']) ! uses_query = dict.fromkeys(['http', 'wais', 'imap', 'https', 'shttp', 'gopher', 'rtsp', 'rtspu', 'sip', ! '']) ! uses_fragment = dict.fromkeys(['ftp', 'hdl', 'http', 'gopher', 'news', 'nntp', 'wais', 'https', 'shttp', 'snews', ! 'file', 'prospero', '']) # Characters valid in scheme names From jlt63@users.sourceforge.net Mon Jan 6 12:41:27 2003 From: jlt63@users.sourceforge.net (jlt63@users.sourceforge.net) Date: Mon, 06 Jan 2003 04:41:27 -0800 Subject: [Python-checkins] python/dist/src/Include pyport.h,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv7355/Include Modified Files: pyport.h Log Message: Patch #661760: Cygwin auto-import module patch The attached patch enables shared extension modules to build cleanly under Cygwin without moving the static initialization of certain function pointers (i.e., ones exported from the Python DLL core) to a module initialization function. Additionally, this patch fixes the modules that have been changed in the past to accommodate Cygwin. Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** pyport.h 28 Dec 2002 21:56:07 -0000 2.57 --- pyport.h 6 Jan 2003 12:41:24 -0000 2.58 *************** *** 430,434 **** /* Building an extension module, or an embedded situation */ /* public Python functions and data are imported */ ! # define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE # define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE /* module init functions outside the core must be exported */ --- 430,438 ---- /* Building an extension module, or an embedded situation */ /* public Python functions and data are imported */ ! /* Under Cygwin, auto-import functions to prevent compilation */ ! /* failures similar to http://python.org/doc/FAQ.html#3.24 */ ! # if !defined(__CYGWIN__) ! # define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE ! # endif /* !__CYGWIN__ */ # define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE /* module init functions outside the core must be exported */ From jlt63@users.sourceforge.net Mon Jan 6 12:41:29 2003 From: jlt63@users.sourceforge.net (jlt63@users.sourceforge.net) Date: Mon, 06 Jan 2003 04:41:29 -0800 Subject: [Python-checkins] python/dist/src/Modules _hotshot.c,1.31,1.32 _randommodule.c,1.2,1.3 _tkinter.c,1.145,1.146 arraymodule.c,2.80,2.81 bz2module.c,1.13,1.14 cPickle.c,2.98,2.99 socketmodule.c,1.250,1.251 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7355/Modules Modified Files: _hotshot.c _randommodule.c _tkinter.c arraymodule.c bz2module.c cPickle.c socketmodule.c Log Message: Patch #661760: Cygwin auto-import module patch The attached patch enables shared extension modules to build cleanly under Cygwin without moving the static initialization of certain function pointers (i.e., ones exported from the Python DLL core) to a module initialization function. Additionally, this patch fixes the modules that have been changed in the past to accommodate Cygwin. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** _hotshot.c 6 Dec 2002 12:48:49 -0000 1.31 --- _hotshot.c 6 Jan 2003 12:41:25 -0000 1.32 *************** *** 1259,1263 **** 0, /* tp_call */ 0, /* tp_str */ ! 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 1259,1263 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 1344,1348 **** 0, /* tp_call */ 0, /* tp_str */ ! 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 1344,1348 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 1635,1641 **** LogReaderType.ob_type = &PyType_Type; - LogReaderType.tp_getattro = PyObject_GenericGetAttr; ProfilerType.ob_type = &PyType_Type; - ProfilerType.tp_getattro = PyObject_GenericGetAttr; module = Py_InitModule("_hotshot", functions); if (module != NULL) { --- 1635,1639 ---- Index: _randommodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_randommodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _randommodule.c 31 Dec 2002 21:55:16 -0000 1.2 --- _randommodule.c 6 Jan 2003 12:41:25 -0000 1.3 *************** *** 487,491 **** 0, /*tp_call*/ 0, /*tp_str*/ ! 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ --- 487,491 ---- 0, /*tp_call*/ 0, /*tp_str*/ ! PyObject_GenericGetAttr, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ *************** *** 507,513 **** 0, /*tp_dictoffset*/ 0, /*tp_init*/ ! 0, /*tp_alloc*/ random_new, /*tp_new*/ ! 0, /*tp_free*/ 0, /*tp_is_gc*/ }; --- 507,513 ---- 0, /*tp_dictoffset*/ 0, /*tp_init*/ ! PyType_GenericAlloc, /*tp_alloc*/ random_new, /*tp_new*/ ! _PyObject_Del, /*tp_free*/ 0, /*tp_is_gc*/ }; *************** *** 521,527 **** PyObject *m; - Random_Type.tp_getattro = PyObject_GenericGetAttr; - Random_Type.tp_alloc = PyType_GenericAlloc; - Random_Type.tp_free = _PyObject_Del; if (PyType_Ready(&Random_Type) < 0) return; --- 521,524 ---- Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.145 retrieving revision 1.146 diff -C2 -d -r1.145 -r1.146 *** _tkinter.c 4 Jan 2003 08:54:59 -0000 1.145 --- _tkinter.c 6 Jan 2003 12:41:25 -0000 1.146 *************** *** 835,839 **** 0, /*tp_call*/ (reprfunc)PyTclObject_str, /*tp_str*/ ! 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ --- 835,839 ---- 0, /*tp_call*/ (reprfunc)PyTclObject_str, /*tp_str*/ ! PyObject_GenericGetAttr,/*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ *************** *** 2932,2936 **** PyTclObject_Type.ob_type = &PyType_Type; - PyTclObject_Type.tp_getattro = &PyObject_GenericGetAttr; PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type); --- 2932,2935 ---- Index: arraymodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v retrieving revision 2.80 retrieving revision 2.81 diff -C2 -d -r2.80 -r2.81 *** arraymodule.c 3 Jan 2003 08:24:58 -0000 2.80 --- arraymodule.c 6 Jan 2003 12:41:25 -0000 2.81 *************** *** 14,19 **** #endif /* !STDC_HEADERS */ - #define DELAYED(X) 0 - struct arrayobject; /* Forward */ --- 14,17 ---- *************** *** 1843,1847 **** 0, /* tp_call */ 0, /* tp_str */ ! DELAYED(PyObject_GenericGetAttr), /* tp_getattro */ 0, /* tp_setattro */ &array_as_buffer, /* tp_as_buffer*/ --- 1841,1845 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &array_as_buffer, /* tp_as_buffer*/ *************** *** 1863,1869 **** 0, /* tp_dictoffset */ 0, /* tp_init */ ! DELAYED(PyType_GenericAlloc), /* tp_alloc */ array_new, /* tp_new */ ! DELAYED(PyObject_Del), /* tp_free */ }; --- 1861,1867 ---- 0, /* tp_dictoffset */ 0, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ array_new, /* tp_new */ ! PyObject_Del, /* tp_free */ }; *************** *** 1880,1886 **** Arraytype.ob_type = &PyType_Type; - Arraytype.tp_getattro = PyObject_GenericGetAttr; - Arraytype.tp_alloc = PyType_GenericAlloc; - Arraytype.tp_free = PyObject_Del; m = Py_InitModule3("array", a_methods, module_doc); --- 1878,1881 ---- Index: bz2module.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/bz2module.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** bz2module.c 5 Dec 2002 20:31:53 -0000 1.13 --- bz2module.c 6 Jan 2003 12:41:25 -0000 1.14 *************** *** 1388,1393 **** 0, /*tp_call*/ 0, /*tp_str*/ ! 0, /*tp_getattro*/ ! 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ --- 1388,1393 ---- 0, /*tp_call*/ 0, /*tp_str*/ ! PyObject_GenericGetAttr,/*tp_getattro*/ ! PyObject_GenericSetAttr,/*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ *************** *** 1408,1414 **** 0, /*tp_dictoffset*/ (initproc)BZ2File_init, /*tp_init*/ ! 0, /*tp_alloc*/ 0, /*tp_new*/ ! 0, /*tp_free*/ 0, /*tp_is_gc*/ }; --- 1408,1414 ---- 0, /*tp_dictoffset*/ (initproc)BZ2File_init, /*tp_init*/ ! PyType_GenericAlloc, /*tp_alloc*/ 0, /*tp_new*/ ! _PyObject_Del, /*tp_free*/ 0, /*tp_is_gc*/ }; *************** *** 1653,1658 **** 0, /*tp_call*/ 0, /*tp_str*/ ! 0, /*tp_getattro*/ ! 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ --- 1653,1658 ---- 0, /*tp_call*/ 0, /*tp_str*/ ! PyObject_GenericGetAttr,/*tp_getattro*/ ! PyObject_GenericSetAttr,/*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ *************** *** 1673,1679 **** 0, /*tp_dictoffset*/ (initproc)BZ2Comp_init, /*tp_init*/ ! 0, /*tp_alloc*/ ! 0, /*tp_new*/ ! 0, /*tp_free*/ 0, /*tp_is_gc*/ }; --- 1673,1679 ---- 0, /*tp_dictoffset*/ (initproc)BZ2Comp_init, /*tp_init*/ ! PyType_GenericAlloc, /*tp_alloc*/ ! PyType_GenericNew, /*tp_new*/ ! _PyObject_Del, /*tp_free*/ 0, /*tp_is_gc*/ }; *************** *** 1870,1875 **** 0, /*tp_call*/ 0, /*tp_str*/ ! 0, /*tp_getattro*/ ! 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ --- 1870,1875 ---- 0, /*tp_call*/ 0, /*tp_str*/ ! PyObject_GenericGetAttr,/*tp_getattro*/ ! PyObject_GenericSetAttr,/*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ *************** *** 1890,1896 **** 0, /*tp_dictoffset*/ (initproc)BZ2Decomp_init, /*tp_init*/ ! 0, /*tp_alloc*/ ! 0, /*tp_new*/ ! 0, /*tp_free*/ 0, /*tp_is_gc*/ }; --- 1890,1896 ---- 0, /*tp_dictoffset*/ (initproc)BZ2Decomp_init, /*tp_init*/ ! PyType_GenericAlloc, /*tp_alloc*/ ! PyType_GenericNew, /*tp_new*/ ! _PyObject_Del, /*tp_free*/ 0, /*tp_is_gc*/ }; *************** *** 2090,2111 **** BZ2File_Type.tp_base = &PyFile_Type; BZ2File_Type.tp_new = PyFile_Type.tp_new; - BZ2File_Type.tp_getattro = PyObject_GenericGetAttr; - BZ2File_Type.tp_setattro = PyObject_GenericSetAttr; - BZ2File_Type.tp_alloc = PyType_GenericAlloc; - BZ2File_Type.tp_free = _PyObject_Del; BZ2Comp_Type.ob_type = &PyType_Type; - BZ2Comp_Type.tp_getattro = PyObject_GenericGetAttr; - BZ2Comp_Type.tp_setattro = PyObject_GenericSetAttr; - BZ2Comp_Type.tp_alloc = PyType_GenericAlloc; - BZ2Comp_Type.tp_new = PyType_GenericNew; - BZ2Comp_Type.tp_free = _PyObject_Del; - BZ2Decomp_Type.ob_type = &PyType_Type; - BZ2Decomp_Type.tp_getattro = PyObject_GenericGetAttr; - BZ2Decomp_Type.tp_setattro = PyObject_GenericSetAttr; - BZ2Decomp_Type.tp_alloc = PyType_GenericAlloc; - BZ2Decomp_Type.tp_new = PyType_GenericNew; - BZ2Decomp_Type.tp_free = _PyObject_Del; m = Py_InitModule3("bz2", bz2_methods, bz2__doc__); --- 2090,2096 ---- Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.98 retrieving revision 2.99 diff -C2 -d -r2.98 -r2.99 *** cPickle.c 24 Dec 2002 18:10:07 -0000 2.98 --- cPickle.c 6 Jan 2003 12:41:25 -0000 2.99 *************** *** 2544,2549 **** 0, /* tp_call */ 0, /* tp_str */ ! 0, /* set below */ /* tp_getattro */ ! 0, /* set below */ /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ --- 2544,2549 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ ! PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ *************** *** 4809,4814 **** Picklertype.ob_type = &PyType_Type; - Picklertype.tp_getattro = PyObject_GenericGetAttr; - Picklertype.tp_setattro = PyObject_GenericSetAttr; Unpicklertype.ob_type = &PyType_Type; PdataType.ob_type = &PyType_Type; --- 4809,4812 ---- Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.250 retrieving revision 1.251 diff -C2 -d -r1.250 -r1.251 *** socketmodule.c 2 Jan 2003 12:45:34 -0000 1.250 --- socketmodule.c 6 Jan 2003 12:41:26 -0000 1.251 *************** *** 2116,2120 **** 0, /* tp_call */ 0, /* tp_str */ ! 0, /* set below */ /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ --- 2116,2120 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ *************** *** 2136,2142 **** 0, /* tp_dictoffset */ sock_initobj, /* tp_init */ ! 0, /* set below */ /* tp_alloc */ sock_new, /* tp_new */ ! 0, /* set below */ /* tp_free */ }; --- 2136,2142 ---- 0, /* tp_dictoffset */ sock_initobj, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ sock_new, /* tp_new */ ! PyObject_Del, /* tp_free */ }; *************** *** 3148,3154 **** sock_type.ob_type = &PyType_Type; - sock_type.tp_getattro = PyObject_GenericGetAttr; - sock_type.tp_alloc = PyType_GenericAlloc; - sock_type.tp_free = PyObject_Del; m = Py_InitModule3(PySocket_MODULE_NAME, socket_methods, --- 3148,3151 ---- From rhettinger@users.sourceforge.net Mon Jan 6 12:54:57 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 04:54:57 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv11776 Modified Files: ref6.tex Log Message: SF bug #661848 and #631055: Clarify use of __all__. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** ref6.tex 7 Dec 2002 16:00:00 -0000 1.58 --- ref6.tex 6 Jan 2003 12:54:54 -0000 1.59 *************** *** 703,707 **** defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character ! (\character{_}). \withsubitem{(optional module attribute)}{\ttindex{__all__}} --- 703,710 ---- defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character ! (\character{_}). \code{__all__} should contain the entire public API. ! It is intended to avoid accidentally exporting items that are not part ! of the API (such as library modules which were imported and used within ! the module). \withsubitem{(optional module attribute)}{\ttindex{__all__}} From akuchling@users.sourceforge.net Mon Jan 6 13:28:15 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 06 Jan 2003 05:28:15 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils util.py,1.72,1.73 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory sc8-pr-cvs1:/tmp/cvs-serv23125 Modified Files: util.py Log Message: Translate spaces in the machine name to underscores (Power Macintosh -> Power_Macintosh) Index: util.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/util.py,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** util.py 3 Dec 2002 08:45:11 -0000 1.72 --- util.py 6 Jan 2003 13:28:12 -0000 1.73 *************** *** 41,48 **** (osname, host, release, version, machine) = os.uname() ! # Convert the OS name to lowercase and remove '/' characters ! # (to accommodate BSD/OS) osname = string.lower(osname) osname = string.replace(osname, '/', '') if osname[:5] == "linux": --- 41,49 ---- (osname, host, release, version, machine) = os.uname() ! # Convert the OS name to lowercase, remove '/' characters ! # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") osname = string.lower(osname) osname = string.replace(osname, '/', '') + machine = string.replace(machine, ' ', '_') if osname[:5] == "linux": From rhettinger@users.sourceforge.net Mon Jan 6 13:31:29 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 05:31:29 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.107,1.108 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv24197 Modified Files: libos.tex Log Message: SF bug #592859: os.chmod is underdocumented Document constants for permission bits. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.107 retrieving revision 1.108 diff -C2 -d -r1.107 -r1.108 *** libos.tex 5 Jan 2003 22:20:51 -0000 1.107 --- libos.tex 6 Jan 2003 13:31:26 -0000 1.108 *************** *** 654,657 **** --- 654,679 ---- \begin{funcdesc}{chmod}{path, mode} Change the mode of \var{path} to the numeric \var{mode}. + \var{mode} may take one of the following values: + \begin{itemize} + \item \code{S_ISUID} + \item \code{S_ISGID} + \item \code{S_ENFMT} + \item \code{S_ISVTX} + \item \code{S_IREAD} + \item \code{S_IWRITE} + \item \code{S_IEXEC} + \item \code{S_IRWXU} + \item \code{S_IRUSR} + \item \code{S_IWUSR} + \item \code{S_IXUSR} + \item \code{S_IRWXG} + \item \code{S_IRGRP} + \item \code{S_IWGRP} + \item \code{S_IXGRP} + \item \code{S_IRWXO} + \item \code{S_IROTH} + \item \code{S_IWOTH} + \item \code{S_IXOTH} + \end{itemize} Availability: \UNIX, Windows. \end{funcdesc} From fdrake@users.sourceforge.net Mon Jan 6 15:03:13 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 06 Jan 2003 07:03:13 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv27371 Modified Files: libdatetime.tex Log Message: Fix markup so this will format again. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** libdatetime.tex 4 Jan 2003 18:17:36 -0000 1.30 --- libdatetime.tex 6 Jan 2003 15:03:11 -0000 1.31 *************** *** 1364,1368 **** \begin{methoddesc}{astimezone}{tz} ! Return a \class{datetimetz} object with new \membar{tzinfo} member \var{tz}. \var{tz} must be \code{None}, or an instance of a \class{tzinfo} subclass. --- 1364,1368 ---- \begin{methoddesc}{astimezone}{tz} ! Return a \class{datetimetz} object with new \member{tzinfo} member \var{tz}. \var{tz} must be \code{None}, or an instance of a \class{tzinfo} subclass. From gvanrossum@users.sourceforge.net Mon Jan 6 15:43:17 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 07:43:17 -0800 Subject: [Python-checkins] python/dist/src/Lib rexec.py,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv16227 Modified Files: rexec.py Log Message: Sabotage rexec.py. It is not safe since the new-style classes. Index: rexec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** rexec.py 16 Dec 2002 13:11:55 -0000 1.46 --- rexec.py 6 Jan 2003 15:43:14 -0000 1.47 *************** *** 181,184 **** --- 181,187 ---- """ + + raise RuntimeError, "This code is not secure in Python 2.2 and 2.3" + ihooks._Verbose.__init__(self, verbose) # XXX There's a circular reference here: From gvanrossum@users.sourceforge.net Mon Jan 6 15:43:36 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 07:43:36 -0800 Subject: [Python-checkins] python/dist/src/Lib Bastion.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv16331 Modified Files: Bastion.py Log Message: Sabotage rexec.py. It is not safe since the new-style classes. Index: Bastion.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/Bastion.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Bastion.py 20 Jan 2001 19:54:20 -0000 1.6 --- Bastion.py 6 Jan 2003 15:43:34 -0000 1.7 *************** *** 98,101 **** --- 98,103 ---- """ + raise RuntimeError, "This code is not secure in Python 2.2 and 2.3" + # Note: we define *two* ad-hoc functions here, get1 and get2. # Both are intended to be called in the same way: get(name). From gvanrossum@users.sourceforge.net Mon Jan 6 15:45:14 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 07:45:14 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_bastion.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv16969 Modified Files: test_bastion.py Log Message: Disable the Bastion test now that Bastion is out of grace. Index: test_bastion.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bastion.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_bastion.py 19 Jan 2001 03:22:48 -0000 1.1 --- test_bastion.py 6 Jan 2003 15:45:11 -0000 1.2 *************** *** 1,3 **** ! import Bastion ! ! Bastion._test() --- 1,3 ---- ! ##import Bastion ! ## ! ##Bastion._test() From fdrake@users.sourceforge.net Mon Jan 6 15:50:36 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 06 Jan 2003 07:50:36 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsets.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv19336 Modified Files: libsets.tex Log Message: Fix some nits Guido brought up last August: - give subsection pages nicer names - shorten some really long table cells; table cells can't wrap in the typeset version of the documentation Index: libsets.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsets.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** libsets.tex 25 Aug 2002 18:43:10 -0000 1.7 --- libsets.tex 6 Jan 2003 15:50:32 -0000 1.8 *************** *** 61,65 **** ! \subsection{Set Objects} Instances of \class{Set} and \class{ImmutableSet} both provide --- 61,65 ---- ! \subsection{Set Objects \label{set-objects}} Instances of \class{Set} and \class{ImmutableSet} both provide *************** *** 143,163 **** \hline \lineii{\var{s}.add(\var{x})} ! {Add element \var{x} to set \var{s}} \lineii{\var{s}.remove(\var{x})} ! {Remove element \var{x} from set \var{s}} \lineii{\var{s}.discard(\var{x})} ! {Removes element \var{x} from set \var{s}. Like \var{s}.remove(\var{x}) ! but does not raise KeyError if \var{x} is not in \var{s}} \lineii{\var{s}.pop()} ! {Remove and return an element from \var{s}; no guarantee is ! made about which element is removed} \lineii{\var{s}.update(\var{t})} ! {Add elements from \var{t} to set \var{s}} \lineii{\var{s}.clear()} ! {Remove all elements from set \var{s}} \end{tableii} ! \subsection{Example} \begin{verbatim} --- 143,161 ---- \hline \lineii{\var{s}.add(\var{x})} ! {add element \var{x} to set \var{s}} \lineii{\var{s}.remove(\var{x})} ! {remove \var{x} from set \var{s}} \lineii{\var{s}.discard(\var{x})} ! {removes \var{x} from set \var{s} if present} \lineii{\var{s}.pop()} ! {remove and return an arbitrary element from \var{s}} \lineii{\var{s}.update(\var{t})} ! {add elements from \var{t} to set \var{s}} \lineii{\var{s}.clear()} ! {remove all elements from set \var{s}} \end{tableii} ! \subsection{Example \label{set-example}} \begin{verbatim} From gvanrossum@users.sourceforge.net Mon Jan 6 16:02:14 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 08:02:14 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_bastion,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv23834 Removed Files: test_bastion Log Message: Remove bastion test output --- test_bastion DELETED --- From gvanrossum@users.sourceforge.net Mon Jan 6 16:03:47 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 08:03:47 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.172,1.173 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv24518 Modified Files: test_descr.py Log Message: Disable the rexec test now that rexec is out of grace. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.172 retrieving revision 1.173 diff -C2 -d -r1.172 -r1.173 *** test_descr.py 24 Dec 2002 18:31:27 -0000 1.172 --- test_descr.py 6 Jan 2003 16:03:43 -0000 1.173 *************** *** 2375,2378 **** --- 2375,2380 ---- def restricted(): + # XXX This test is disabled because rexec is not deemed safe + return import rexec if verbose: From montanaro@users.sourceforge.net Mon Jan 6 17:23:54 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 06 Jan 2003 09:23:54 -0800 Subject: [Python-checkins] python/dist/src README,1.165,1.166 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv26753 Modified Files: README Log Message: delete reference to defunct Misc/HPUX-NOTES. Adjust reference for BeOS notes. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.165 retrieving revision 1.166 diff -C2 -d -r1.165 -r1.166 *** README 4 Jan 2003 04:05:51 -0000 1.165 --- README 6 Jan 2003 17:23:37 -0000 1.166 *************** *** 345,350 **** CC="xlC" without thread support). ! HP-UX: Please read the file Misc/HPUX-NOTES for shared libraries. ! When using threading, you may have to add -D_REENTRANT to the OPT variable in the top-level Makefile; reported by Pat Knight, this seems to make a difference (at least for HP-UX 10.20) --- 345,349 ---- CC="xlC" without thread support). ! HP-UX: When using threading, you may have to add -D_REENTRANT to the OPT variable in the top-level Makefile; reported by Pat Knight, this seems to make a difference (at least for HP-UX 10.20) *************** *** 420,427 **** to read: LDFLAGS = -N 48k ! BeOS: Chris Herborth (chrish@qnx.com) writes: ! See BeOS/README for notes about compiling/installing Python on ! BeOS R3 or later. Note that only the PowerPC platform is ! supported for R3; both PowerPC and x86 are supported for R4. Cray T3E: Mark Hadfield (m.hadfield@niwa.co.nz) writes: --- 419,426 ---- to read: LDFLAGS = -N 48k ! BeOS: See Misc/BeOS-NOTES for notes about compiling/installing ! Python on BeOS R3 or later. Note that only the PowerPC ! platform is supported for R3; both PowerPC and x86 are ! supported for R4. Cray T3E: Mark Hadfield (m.hadfield@niwa.co.nz) writes: From tim_one@users.sourceforge.net Mon Jan 6 16:24:16 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 06 Jan 2003 08:24:16 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime US.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv1265 Modified Files: US.py Log Message: Repaired the "unspellable hour" doctest example to match current behavior. Index: US.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/US.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** US.py 2 Jan 2003 21:01:19 -0000 1.15 --- US.py 6 Jan 2003 16:24:14 -0000 1.16 *************** *** 208,218 **** What happens when we convert that to Eastern? astimezone detects the ! impossibilty of the task, and raises an exception. >>> paradox = phantom.astimezone(Eastern) ! Traceback (most recent call last): ! ... ! ValueError: astimezone(): the source datetimetz can't be expressed in the target timezone's local time ! """ __test__ = {'brainbuster': brainbuster_test} --- 208,224 ---- What happens when we convert that to Eastern? astimezone detects the ! impossibilty of the task, and mimics the local clock's "repeat the 1:MM ! hour" behavior: >>> paradox = phantom.astimezone(Eastern) ! >>> printstuff(paradox) ! 2002-10-27 01:00:00-04:00 ! EDT ! (2002, 10, 27, 1, 0, 0, 6, 300, 1) ! Sun Oct 27 01:00:00 2002 ! ! That isn't a UTC equivalent, although it would be if 1:00 were taken as being ! in EST. ! """ __test__ = {'brainbuster': brainbuster_test} From tim_one@users.sourceforge.net Mon Jan 6 16:29:25 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 06 Jan 2003 08:29:25 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime test_datetime2.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv3382 Modified Files: test_datetime2.py Log Message: Repaired edit glitch from s/timetz/time/ in a test. Index: test_datetime2.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime2.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_datetime2.py 5 Jan 2003 02:10:30 -0000 1.1 --- test_datetime2.py 6 Jan 2003 16:29:19 -0000 1.2 *************** *** 2467,2471 **** self.assertEqual(got.date(), expected.date()) self.assertEqual(got.time(), expected.time()) ! self.assertEqual(got.time(), expected.time()) self.failUnless(got.tzinfo is expected.tzinfo) self.assertEqual(got, expected) --- 2467,2471 ---- self.assertEqual(got.date(), expected.date()) self.assertEqual(got.time(), expected.time()) ! self.assertEqual(got.timetz(), expected.timetz()) self.failUnless(got.tzinfo is expected.tzinfo) self.assertEqual(got, expected) From fdrake@users.sourceforge.net Mon Jan 6 16:38:14 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 06 Jan 2003 08:38:14 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libthreading.tex,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv7188 Modified Files: libthreading.tex Log Message: Strike any hint that from-import-* could ever be reasonable; it's a vile abomination and should be eradicated! Index: libthreading.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libthreading.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** libthreading.tex 30 Dec 2002 23:00:36 -0000 1.14 --- libthreading.tex 6 Jan 2003 16:38:10 -0000 1.15 *************** *** 13,18 **** \refmodule{thread} is missing. ! This module is safe for use with \samp{from threading import *}. It ! defines the following functions and objects: \begin{funcdesc}{activeCount}{} --- 13,17 ---- \refmodule{thread} is missing. ! This module defines the following functions and objects: \begin{funcdesc}{activeCount}{} From fdrake@users.sourceforge.net Mon Jan 6 16:38:54 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 06 Jan 2003 08:38:54 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libthreading.tex,1.11.14.1,1.11.14.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv7523 Modified Files: Tag: release22-maint libthreading.tex Log Message: Strike any hint that from-import-* could ever be reasonable; it's a vile abomination and should be eradicated! Index: libthreading.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libthreading.tex,v retrieving revision 1.11.14.1 retrieving revision 1.11.14.2 diff -C2 -d -r1.11.14.1 -r1.11.14.2 *** libthreading.tex 19 Mar 2002 14:37:14 -0000 1.11.14.1 --- libthreading.tex 6 Jan 2003 16:38:48 -0000 1.11.14.2 *************** *** 9,14 **** lower level \refmodule{thread} module. ! This module is safe for use with \samp{from threading import *}. It ! defines the following functions and objects: \begin{funcdesc}{activeCount}{} --- 9,13 ---- lower level \refmodule{thread} module. ! This module defines the following functions and objects: \begin{funcdesc}{activeCount}{} From montanaro@users.sourceforge.net Mon Jan 6 17:14:34 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 06 Jan 2003 09:14:34 -0800 Subject: [Python-checkins] python/dist/src/Misc HPUX-NOTES,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv22952 Removed Files: HPUX-NOTES Log Message: removing - contains outdated information --- HPUX-NOTES DELETED --- From rhettinger@users.sourceforge.net Mon Jan 6 18:41:10 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 10:41:10 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libxdrlib.tex,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv26012 Modified Files: libxdrlib.tex Log Message: Fix spelling. Index: libxdrlib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxdrlib.tex,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** libxdrlib.tex 10 Oct 2000 17:02:34 -0000 1.23 --- libxdrlib.tex 6 Jan 2003 18:41:01 -0000 1.24 *************** *** 34,38 **** defined the encoding of data which was XDR at the time this module was originally written. It has ! appearantly been obsoleted by \rfc{1832}.} \seerfc{1832}{XDR: External Data Representation Standard}{Newer RFC --- 34,38 ---- defined the encoding of data which was XDR at the time this module was originally written. It has ! apparently been obsoleted by \rfc{1832}.} \seerfc{1832}{XDR: External Data Representation Standard}{Newer RFC From gvanrossum@users.sourceforge.net Mon Jan 6 18:58:40 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 10:58:40 -0800 Subject: [Python-checkins] python/nondist/peps pep-0283.txt,1.26,1.27 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv1315a Modified Files: pep-0283.txt Log Message: PEPs 273+302 have landed. New ideas: - Add reST? - Fix new-style pickling - Remove __safe_for_unpickling__ Index: pep-0283.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0283.txt,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** pep-0283.txt 30 Dec 2002 17:30:25 -0000 1.26 --- pep-0283.txt 6 Jan 2003 18:58:25 -0000 1.27 *************** *** 41,44 **** --- 41,47 ---- - Set API issues; is the sets module perfect? + I expect it's good enough to stop polishing it until we've had + more widespread user experience. + - A nicer API to open text files, replacing the ugly (in some people's eyes) "U" mode flag. There's a proposal out there to *************** *** 46,54 **** --- 49,65 ---- (Shouldn't it have a bufsize argument too?) + Ditto. + - Fredrik Lundh's basetime proposal: http://effbot.org/ideas/time-type.htm + I believe this is dead now. + - New widgets for Tkinter??? + Has anyone gotten the time for this? *Are* there any new + widgets in Tk 8.4? Note that we've got better Tix support + already (though not on Windows yet). + Completed features for 2.3 *************** *** 141,144 **** --- 152,164 ---- this module basically complete -- except for its documentation. + - PEP 273 Import Modules from Zip Archives Ahlstrom + + Implemented as a part of the PEP 302 implementation work. + + - PEP 302 New Import Hooks JvR + + Implemented (though the 2.3a1 release contained some bugs that + have been fixed post-release). + Planned features for 2.3 *************** *** 153,168 **** life of the 2.3 development process. - For a class defined inside another class, the __name__ should be "outer.inner", and pickling should work. - - PEP 273 Import Modules from Zip Archives Ahlstrom - - There's a patch at http://www.python.org/sf/492105; an updated - patch at http://www.python.org/sf/645650; but my expectation is - that this will be subsumed by the PEP 302 work. ! - PEP 302 New Import Hooks JvR ! This looks very promising. See http://www.python.org/sf/652586 - Documentation: complete the distribution and installation --- 173,220 ---- life of the 2.3 development process. + - reST is going to be used a lot in Zope3. Maybe it could become + a standard library module? + + - I really, really, really would like to improve pickling of + new-style classes. + + I've finally come to the conclusion that any solution to making + pickled new-style class instances (and hence pickled datetime + objects) more efficient will require adding new codes to the + pickle protocol. + + We can do that in Python 2.3. Because this is backwards + incompatible, I propose that you have to request this protocol + explicitly. I propose to "upgrade' the binary flag to a general + "protocol version" flag, with values: + + 0 - original protocol + 1 - binary protocol + 2 - new protocol + + The new protocol can contain an explicit pickle code for the new + datetime objects. That's about all the thinking I've done so + far. We need to decide on the new format, but first we must + figure out ways how to efficiently pickle and unpickle subclass + instances of (picklable) built-in types, preferably without + having to copy all the data twice, and instances of new-style + classes with slots. And we need to implement these twice: in + Python for pickle.py and in C for cPickle.py. + + - I'd also like to get rid of __safe_for_unpickling__ and all + other pseudo security features. Attempting to unpickle pickles + from an untrusted source is insane, and nothing can help us + there; I'd rather make the marshal protocol bulletproof (all it + needs is a few more checks for inconsistent data and a little + better error handling). + - For a class defined inside another class, the __name__ should be "outer.inner", and pickling should work. ! Ongoing tasks ! The following are ongoing TO-DO items which we should attempt to ! work on without hoping for completion by any particular date. - Documentation: complete the distribution and installation From montanaro@users.sourceforge.net Mon Jan 6 20:27:05 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 06 Jan 2003 12:27:05 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_urlparse.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv1378/Lib/test Modified Files: test_urlparse.py Log Message: * add mms (windows media) as another scheme * reformat schemes to 80 columns Index: test_urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_urlparse.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_urlparse.py 6 Jan 2003 06:58:31 -0000 1.10 --- test_urlparse.py 6 Jan 2003 20:27:03 -0000 1.11 *************** *** 29,32 **** --- 29,35 ---- ('imap', 'mail.python.org', '/mbox1', '', '', ''), ('imap', 'mail.python.org', '/mbox1', '', '')), + ('mms://wms.sys.hinet.net/cts/Drama/09006251100.asf', + ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf', '', '', ''), + ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf', '', '')), ]: result = urlparse.urlparse(url) From montanaro@users.sourceforge.net Mon Jan 6 20:27:05 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 06 Jan 2003 12:27:05 -0800 Subject: [Python-checkins] python/dist/src/Lib urlparse.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv1378/Lib Modified Files: urlparse.py Log Message: * add mms (windows media) as another scheme * reformat schemes to 80 columns Index: urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urlparse.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** urlparse.py 6 Jan 2003 12:30:53 -0000 1.37 --- urlparse.py 6 Jan 2003 20:27:02 -0000 1.38 *************** *** 9,32 **** # A classification of schemes ('' means apply by default) ! uses_relative = dict.fromkeys(['ftp', 'http', 'gopher', 'nntp', 'imap', 'wais', 'file', ! 'https', 'shttp', ! 'prospero', 'rtsp', 'rtspu', '']) ! uses_netloc = dict.fromkeys(['ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', ! 'file', ! 'https', 'shttp', 'snews', ! 'prospero', 'rtsp', 'rtspu', '']) ! non_hierarchical = dict.fromkeys(['gopher', 'hdl', 'mailto', 'news', 'telnet', 'wais', ! 'imap', 'snews', 'sip', ! ]) uses_params = dict.fromkeys(['ftp', 'hdl', 'prospero', 'http', 'imap', ! 'https', 'shttp', 'rtsp', 'rtspu', 'sip', ! '']) ! uses_query = dict.fromkeys(['http', 'wais', 'imap', ! 'https', 'shttp', ! 'gopher', 'rtsp', 'rtspu', 'sip', ! '']) ! uses_fragment = dict.fromkeys(['ftp', 'hdl', 'http', 'gopher', 'news', 'nntp', 'wais', ! 'https', 'shttp', 'snews', ! 'file', 'prospero', '']) # Characters valid in scheme names --- 9,28 ---- # A classification of schemes ('' means apply by default) ! uses_relative = dict.fromkeys(['ftp', 'http', 'gopher', 'nntp', 'imap', ! 'wais', 'file', 'https', 'shttp', 'mms', ! 'prospero', 'rtsp', 'rtspu', '']) ! uses_netloc = dict.fromkeys(['ftp', 'http', 'gopher', 'nntp', 'telnet', ! 'imap', 'wais', 'file', 'mms', 'https', 'shttp', ! 'snews', 'prospero', 'rtsp', 'rtspu', '']) ! non_hierarchical = dict.fromkeys(['gopher', 'hdl', 'mailto', 'news', ! 'telnet', 'wais', 'imap', 'snews', 'sip']) uses_params = dict.fromkeys(['ftp', 'hdl', 'prospero', 'http', 'imap', ! 'https', 'shttp', 'rtsp', 'rtspu', 'sip', ! 'mms', '']) ! uses_query = dict.fromkeys(['http', 'wais', 'imap', 'https', 'shttp', 'mms', ! 'gopher', 'rtsp', 'rtspu', 'sip', '']) ! uses_fragment = dict.fromkeys(['ftp', 'hdl', 'http', 'gopher', 'news', ! 'nntp', 'wais', 'https', 'shttp', 'snews', ! 'file', 'prospero', '']) # Characters valid in scheme names From rhettinger@users.sourceforge.net Tue Jan 7 02:09:20 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 18:09:20 -0800 Subject: [Python-checkins] python/dist/src/Lib urlparse.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv22660a Modified Files: urlparse.py Log Message: Revert change 1.37. The nanoseconds saved by using dict.fromkeys aren't worth the loss in clarity. Linear searches live on. Index: urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urlparse.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** urlparse.py 6 Jan 2003 20:27:02 -0000 1.38 --- urlparse.py 7 Jan 2003 02:09:16 -0000 1.39 *************** *** 9,28 **** # A classification of schemes ('' means apply by default) ! uses_relative = dict.fromkeys(['ftp', 'http', 'gopher', 'nntp', 'imap', 'wais', 'file', 'https', 'shttp', 'mms', ! 'prospero', 'rtsp', 'rtspu', '']) ! uses_netloc = dict.fromkeys(['ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', 'file', 'mms', 'https', 'shttp', ! 'snews', 'prospero', 'rtsp', 'rtspu', '']) ! non_hierarchical = dict.fromkeys(['gopher', 'hdl', 'mailto', 'news', ! 'telnet', 'wais', 'imap', 'snews', 'sip']) ! uses_params = dict.fromkeys(['ftp', 'hdl', 'prospero', 'http', 'imap', 'https', 'shttp', 'rtsp', 'rtspu', 'sip', ! 'mms', '']) ! uses_query = dict.fromkeys(['http', 'wais', 'imap', 'https', 'shttp', 'mms', ! 'gopher', 'rtsp', 'rtspu', 'sip', '']) ! uses_fragment = dict.fromkeys(['ftp', 'hdl', 'http', 'gopher', 'news', 'nntp', 'wais', 'https', 'shttp', 'snews', ! 'file', 'prospero', '']) # Characters valid in scheme names --- 9,28 ---- # A classification of schemes ('' means apply by default) ! uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap', 'wais', 'file', 'https', 'shttp', 'mms', ! 'prospero', 'rtsp', 'rtspu', ''] ! uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', 'file', 'mms', 'https', 'shttp', ! 'snews', 'prospero', 'rtsp', 'rtspu', ''] ! non_hierarchical = ['gopher', 'hdl', 'mailto', 'news', ! 'telnet', 'wais', 'imap', 'snews', 'sip'] ! uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap', 'https', 'shttp', 'rtsp', 'rtspu', 'sip', ! 'mms', ''] ! uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'mms', ! 'gopher', 'rtsp', 'rtspu', 'sip', ''] ! uses_fragment = ['ftp', 'hdl', 'http', 'gopher', 'news', 'nntp', 'wais', 'https', 'shttp', 'snews', ! 'file', 'prospero', ''] # Characters valid in scheme names From rhettinger@users.sourceforge.net Tue Jan 7 10:25:58 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 07 Jan 2003 02:25:58 -0800 Subject: [Python-checkins] python/dist/src/Lib random.py,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv3551 Modified Files: random.py Log Message: Much clearer when super() is used. Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** random.py 5 Jan 2003 09:20:06 -0000 1.44 --- random.py 7 Jan 2003 10:25:55 -0000 1.45 *************** *** 59,65 **** # the Mersenne Twister core generator. ! from _random import Random as CoreGenerator ! class Random(CoreGenerator): """Random number generator base class used by bound module functions. --- 59,65 ---- # the Mersenne Twister core generator. ! import _random ! class Random(_random.Random): """Random number generator base class used by bound module functions. *************** *** 95,104 **** """ ! CoreGenerator.seed(self, a) self.gauss_next = None def getstate(self): """Return internal state; can be passed to setstate() later.""" ! return self.VERSION, CoreGenerator.getstate(self), self.gauss_next def setstate(self, state): --- 95,104 ---- """ ! super(Random, self).seed(a) self.gauss_next = None def getstate(self): """Return internal state; can be passed to setstate() later.""" ! return self.VERSION, super(Random, self).getstate(), self.gauss_next def setstate(self, state): *************** *** 107,111 **** if version == 2: version, internalstate, self.gauss_next = state ! CoreGenerator.setstate(self, internalstate) else: raise ValueError("state with version %s passed to " --- 107,111 ---- if version == 2: version, internalstate, self.gauss_next = state ! super(Random, self).setstate(internalstate) else: raise ValueError("state with version %s passed to " From gvanrossum@users.sourceforge.net Tue Jan 7 13:41:40 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 05:41:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.175,1.176 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv4861/Lib/test Modified Files: test_descr.py Log Message: Fix for SF bug #642358: only provide a new with a __dict__ or __weaklist__ descriptor if we added __dict__ or __weaklist__, respectively. With unit test. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.175 retrieving revision 1.176 diff -C2 -d -r1.175 -r1.176 *** test_descr.py 6 Jan 2003 23:00:59 -0000 1.175 --- test_descr.py 7 Jan 2003 13:41:37 -0000 1.176 *************** *** 3687,3690 **** --- 3687,3703 ---- vereq(C(1) / E(1), "C.__div__") # This one would fail + def dict_type_with_metaclass(): + if verbose: + print "Testing type of __dict__ when __metaclass__ set..." + + class B(object): + pass + class M(type): + pass + class C: + # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy + __metaclass__ = M + veris(type(C.__dict__), type(B.__dict__)) + def test_main(): *************** *** 3772,3775 **** --- 3785,3789 ---- mutable_names() subclass_right_op() + dict_type_with_metaclass() if verbose: print "All OK" From gvanrossum@users.sourceforge.net Tue Jan 7 13:41:39 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 05:41:39 -0800 Subject: [Python-checkins] python/dist/src/Objects typeobject.c,2.201,2.202 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv4861/Objects Modified Files: typeobject.c Log Message: Fix for SF bug #642358: only provide a new with a __dict__ or __weaklist__ descriptor if we added __dict__ or __weaklist__, respectively. With unit test. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.201 retrieving revision 2.202 diff -C2 -d -r2.201 -r2.202 *** typeobject.c 6 Jan 2003 22:57:47 -0000 2.201 --- typeobject.c 7 Jan 2003 13:41:36 -0000 2.202 *************** *** 1354,1362 **** } ! static PyGetSetDef subtype_getsets[] = { ! /* Not all objects have these attributes! ! The descriptor's __get__ method may raise AttributeError. */ {"__dict__", subtype_dict, subtype_setdict, PyDoc_STR("dictionary for instance variables (if defined)")}, {"__weakref__", subtype_getweakref, NULL, PyDoc_STR("list of weak references to the object (if defined)")}, --- 1354,1374 ---- } ! /* Three variants on the subtype_getsets list. */ ! ! static PyGetSetDef subtype_getsets_full[] = { ! {"__dict__", subtype_dict, subtype_setdict, ! PyDoc_STR("dictionary for instance variables (if defined)")}, ! {"__weakref__", subtype_getweakref, NULL, ! PyDoc_STR("list of weak references to the object (if defined)")}, ! {0} ! }; ! ! static PyGetSetDef subtype_getsets_dict_only[] = { {"__dict__", subtype_dict, subtype_setdict, PyDoc_STR("dictionary for instance variables (if defined)")}, + {0} + }; + + static PyGetSetDef subtype_getsets_weakref_only[] = { {"__weakref__", subtype_getweakref, NULL, PyDoc_STR("list of weak references to the object (if defined)")}, *************** *** 1811,1815 **** type->tp_itemsize = base->tp_itemsize; type->tp_members = et->members; ! type->tp_getset = subtype_getsets; /* Special case some slots */ --- 1823,1835 ---- type->tp_itemsize = base->tp_itemsize; type->tp_members = et->members; ! ! if (type->tp_weaklistoffset && type->tp_dictoffset) ! type->tp_getset = subtype_getsets_full; ! else if (type->tp_weaklistoffset && !type->tp_dictoffset) ! type->tp_getset = subtype_getsets_weakref_only; ! else if (!type->tp_weaklistoffset && type->tp_dictoffset) ! type->tp_getset = subtype_getsets_dict_only; ! else ! type->tp_getset = NULL; /* Special case some slots */ From gvanrossum@users.sourceforge.net Tue Jan 7 20:04:23 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:04:23 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.56,2.57 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv11303 Modified Files: readline.c Log Message: A few more whitespace normalizations. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.56 retrieving revision 2.57 diff -C2 -d -r2.56 -r2.57 *** readline.c 7 Jan 2003 20:01:29 -0000 2.56 --- readline.c 7 Jan 2003 20:04:12 -0000 2.57 *************** *** 362,366 **** return NULL; if ((hist_ent = history_get(idx))) ! return PyString_FromString(hist_ent->line); else { Py_INCREF(Py_None); --- 362,366 ---- return NULL; if ((hist_ent = history_get(idx))) ! return PyString_FromString(hist_ent->line); else { Py_INCREF(Py_None); *************** *** 478,481 **** --- 478,482 ---- }; + /* C function to call the Python hooks. */ *************** *** 524,527 **** --- 525,529 ---- #endif + /* C function to call the Python completer. */ *************** *** 577,580 **** --- 579,583 ---- return completion_matches(text, *on_completion); } + /* Helper to initialize GNU readline properly. */ From gvanrossum@users.sourceforge.net Tue Jan 7 20:34:22 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:34:22 -0800 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.222,1.223 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv23520 Modified Files: ACKS Log Message: Fix from Michael Stone for SF bug #660476 and #513033 (bogus thread state swaps in readline). Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.222 retrieving revision 1.223 diff -C2 -d -r1.222 -r1.223 *** ACKS 5 Jan 2003 23:19:40 -0000 1.222 --- ACKS 7 Jan 2003 20:34:19 -0000 1.223 *************** *** 512,515 **** --- 512,516 ---- Casper Stoel Peter Stoehr + Michael Stone Ken Stox Daniel Stutzbach From nnorwitz@users.sourceforge.net Mon Jan 6 16:51:39 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 06 Jan 2003 08:51:39 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib caseless.py,NONE,1.1 liboptparse.tex,NONE,1.1 required_1.py,NONE,1.1 required_2.py,NONE,1.1 lib.tex,1.211,1.212 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv13119/lib Modified Files: lib.tex Added Files: caseless.py liboptparse.tex required_1.py required_2.py Log Message: SF #642236, optparse LaTeX docs by Johannes Gijsbers --- NEW FILE: caseless.py --- from optparse import Option, OptionParser, _match_abbrev # This case-insensitive option parser relies on having a # case-insensitive dictionary type available. Here's one # for Python 2.2. Note that a *real* case-insensitive # dictionary type would also have to implement __new__(), # update(), and setdefault() -- but that's not the point # of this exercise. class caseless_dict (dict): def __setitem__ (self, key, value): dict.__setitem__(self, key.lower(), value) def __getitem__ (self, key): return dict.__getitem__(self, key.lower()) def get (self, key, default=None): return dict.get(self, key.lower()) def has_key (self, key): return dict.has_key(self, key.lower()) class CaselessOptionParser (OptionParser): def _create_option_list (self): self.option_list = [] self._short_opt = caseless_dict() self._long_opt = caseless_dict() self._long_opts = [] self.defaults = {} def _match_long_opt (self, opt): return _match_abbrev(opt.lower(), self._long_opt.keys()) if __name__ == "__main__": from optik.errors import OptionConflictError # test 1: no options to start with parser = CaselessOptionParser() try: parser.add_option("-H", dest="blah") except OptionConflictError: print "ok: got OptionConflictError for -H" else: print "not ok: no conflict between -h and -H" parser.add_option("-f", "--file", dest="file") #print `parser.get_option("-f")` #print `parser.get_option("-F")` #print `parser.get_option("--file")` #print `parser.get_option("--fIlE")` (options, args) = parser.parse_args(["--FiLe", "foo"]) assert options.file == "foo", options.file print "ok: case insensitive long options work" (options, args) = parser.parse_args(["-F", "bar"]) assert options.file == "bar", options.file print "ok: case insensitive short options work" --- NEW FILE: liboptparse.tex --- \section{\module{optparse} --- Powerful parser for command line options.} \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.} \versionadded{2.3} The \module{optparse} module is a powerful, flexible, extensible, easy-to-use command-line parsing library for Python. Using \module{optparse}, you can add intelligent, sophisticated handling of command-line options to your scripts with very little overhead. Here's an example of using \module{optparse} to add some command-line [...1654 lines suppressed...] Here are a few examples of extending the \module{optparse} module. First, let's change the option-parsing to be case-insensitive: \verbatiminput{caseless.py} And two ways of implementing ``required options'' with \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} --- NEW FILE: required_1.py --- import optparse class OptionParser (optparse.OptionParser): def check_required (self, opt): option = self.get_option(opt) # Assumes the option's 'default' is set to None! if getattr(self.values, option.dest) is None: self.error("%s option not supplied" % option) parser = OptionParser() parser.add_option("-v", action="count", dest="verbose") parser.add_option("-f", "--file", default=None) (options, args) = parser.parse_args() print "verbose:", options.verbose print "file:", options.file parser.check_required("-f") --- NEW FILE: required_2.py --- import optparse class Option (optparse.Option): ATTRS = optparse.Option.ATTRS + ['required'] def _check_required (self): if self.required and not self.takes_value(): raise OptionError( "required flag set for option that doesn't take a value", self) # Make sure _check_required() is called from the constructor! CHECK_METHODS = optparse.Option.CHECK_METHODS + [_check_required] def process (self, opt, value, values, parser): optparse.Option.process(self, opt, value, values, parser) parser.option_seen[self] = 1 class OptionParser (optparse.OptionParser): def _init_parsing_state (self): optparse.OptionParser._init_parsing_state(self) self.option_seen = {} def check_values (self, values, args): for option in self.option_list: if (isinstance(option, Option) and option.required and not self.option_seen.has_key(option)): self.error("%s not supplied" % option) return (values, args) parser = OptionParser(option_list=[ Option("-v", action="count", dest="verbose"), Option("-f", "--file", required=1)]) (options, args) = parser.parse_args() print "verbose:", options.verbose print "file:", options.file Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.211 retrieving revision 1.212 diff -C2 -d -r1.211 -r1.212 *** lib.tex 5 Jan 2003 23:19:41 -0000 1.211 --- lib.tex 6 Jan 2003 16:51:34 -0000 1.212 *************** *** 152,155 **** --- 152,156 ---- \input{libcursespanel} \input{libgetopt} + \input{liboptparse} \input{libtempfile} \input{liberrno} From akuchling@users.sourceforge.net Mon Jan 6 20:04:40 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 06 Jan 2003 12:04:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.102,1.103 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv24593 Modified Files: whatsnew23.tex Log Message: Add Tix and rexec changes Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.102 retrieving revision 1.103 diff -C2 -d -r1.102 -r1.103 *** whatsnew23.tex 3 Jan 2003 18:03:21 -0000 1.102 --- whatsnew23.tex 6 Jan 2003 20:04:17 -0000 1.103 *************** *** 1224,1228 **** %====================================================================== ! \section{New and Improved Modules} As usual, Python's standard library received a number of enhancements and --- 1224,1228 ---- %====================================================================== ! \section{New, Improved, and Deprecated Modules} As usual, Python's standard library received a number of enhancements and *************** *** 1433,1436 **** --- 1433,1449 ---- \function{get_current_history_length()}, and \function{redisplay()}. + \item The \module{rexec} and \module{Bastion} modules have been + declared dead, and attempts to import them will fail with a + \exception{RuntimeError}. New-style classes provide new ways to break + out of the restricted execution environment provided by + \module{rexec}, and no one has interest in fixing them or time to do + so. If you have applications using \module{rexec}, rewrite them to + use something else. + + (Sticking with Python 2.2 or 2.1 will not make your applications any + safer, because there are known bugs in the \module{rexec} module in + those versions. I repeat, if you're using \module{rexec}, stop using + it immediately.) + \item The \module{shutil} module gained a \function{move(\var{src}, \var{dest})} function that recursively moves a file or directory to a new *************** *** 1581,1584 **** --- 1594,1600 ---- particular encoding by providing an optional encoding argument to the \method{toxml()} and \method{toprettyxml()} methods of DOM nodes. + + item The \module{Tix} module has received various bug fixes and + updates for the current version of the Tix package. \item The \module{Tkinter} module now works with a thread-enabled From gvanrossum@users.sourceforge.net Mon Jan 6 21:26:56 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 13:26:56 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.173,1.174 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25724 Modified Files: test_descr.py Log Message: Add some print statements in verbose mode to announce that the newest tests are run. (All tests in this module should have one of these at the top.) Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.173 retrieving revision 1.174 diff -C2 -d -r1.173 -r1.174 *** test_descr.py 6 Jan 2003 16:03:43 -0000 1.173 --- test_descr.py 6 Jan 2003 21:26:44 -0000 1.174 *************** *** 3442,3445 **** --- 3442,3447 ---- def test_mutable_bases(): + if verbose: + print "Testing mutable bases..." # stuff that should work: class C(object): *************** *** 3539,3542 **** --- 3541,3546 ---- def test_mutable_bases_with_failing_mro(): + if verbose: + print "Testing mutable bases with failing mro..." class WorkOnce(type): def __new__(self, name, bases, ns): *************** *** 3592,3595 **** --- 3596,3601 ---- def test_mutable_bases_catch_mro_conflict(): + if verbose: + print "Testing mutable bases catch mro conflict..." class A(object): pass *************** *** 3615,3618 **** --- 3621,3626 ---- def mutable_names(): + if verbose: + print "Testing mutable names..." class C(object): pass From rhettinger@users.sourceforge.net Mon Jan 6 22:42:45 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 14:42:45 -0800 Subject: [Python-checkins] python/dist/src/Objects stringobject.c,2.202,2.203 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv23816 Modified Files: stringobject.c Log Message: GvR's idea to use memset() for the most common special case of repeating a single character. Shaves another 10% off the running time by avoiding the lg2(N) loops and cache effects for the other cases. Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.202 retrieving revision 2.203 diff -C2 -d -r2.202 -r2.203 *** stringobject.c 6 Jan 2003 10:33:56 -0000 2.202 --- stringobject.c 6 Jan 2003 22:42:41 -0000 2.203 *************** *** 967,970 **** --- 967,975 ---- op->ob_shash = -1; op->ob_sstate = SSTATE_NOT_INTERNED; + op->ob_sval[size] = '\0'; + if (a->ob_size == 1 && n > 0) { + memset(op->ob_sval, a->ob_sval[0] , n); + return (PyObject *) op; + } i = 0; if (i < size) { *************** *** 977,981 **** i += j; } - op->ob_sval[size] = '\0'; return (PyObject *) op; } --- 982,985 ---- From gvanrossum@users.sourceforge.net Mon Jan 6 22:57:55 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 14:57:55 -0800 Subject: [Python-checkins] python/dist/src/Objects typeobject.c,2.200,2.201 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv30728 Modified Files: typeobject.c Log Message: Add a refinement to SLOT1BINFULL() that fixes the problem reported in SF bug #623669: only try (e.g.) __rdiv__ before __div__ if the right class actually overrides it. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.200 retrieving revision 2.201 diff -C2 -d -r2.200 -r2.201 *** typeobject.c 31 Dec 2002 16:33:01 -0000 2.200 --- typeobject.c 6 Jan 2003 22:57:47 -0000 2.201 *************** *** 3495,3498 **** --- 3495,3532 ---- } + /* Boolean helper for SLOT1BINFULL(). + right.__class__ is a nontrivial subclass of left.__class__. */ + static int + method_is_overloaded(PyObject *left, PyObject *right, char *name) + { + PyObject *a, *b; + int ok; + + b = PyObject_GetAttrString((PyObject *)(right->ob_type), name); + if (b == NULL) { + PyErr_Clear(); + /* If right doesn't have it, it's not overloaded */ + return 0; + } + + a = PyObject_GetAttrString((PyObject *)(left->ob_type), name); + if (a == NULL) { + PyErr_Clear(); + Py_DECREF(b); + /* If right has it but left doesn't, it's overloaded */ + return 1; + } + + ok = PyObject_RichCompareBool(a, b, Py_NE); + Py_DECREF(a); + Py_DECREF(b); + if (ok < 0) { + PyErr_Clear(); + return 0; + } + + return ok; + } + #define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \ *************** *** 3508,3512 **** PyObject *r; \ if (do_other && \ ! PyType_IsSubtype(other->ob_type, self->ob_type)) { \ r = call_maybe( \ other, ROPSTR, &rcache_str, "(O)", self); \ --- 3542,3547 ---- PyObject *r; \ if (do_other && \ ! PyType_IsSubtype(other->ob_type, self->ob_type) && \ ! method_is_overloaded(self, other, ROPSTR)) { \ r = call_maybe( \ other, ROPSTR, &rcache_str, "(O)", self); \ From gvanrossum@users.sourceforge.net Mon Jan 6 23:01:13 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 15:01:13 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.174,1.175 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv31835 Modified Files: test_descr.py Log Message: Add a test for a feature added in rev. 2.82 of typeobject.c: - SLOT1BINFULL() macro: changed this to check for __rop__ overriding __op__, like binary_op1() in abstract.c -- the latter only calls the slot function once if both types use the same slot function, so the slot function must make both calls -- which it already did for the __op__, __rop__ order, but not yet for the __rop__, __op__ order when B.__class__ is a subclass of A.__class__. Also test the refinement added in rev. 2.201 that fixes the problem reported in SF bug #623669. Also test a similar provision in abstract.c's binary_op1(). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.174 retrieving revision 1.175 diff -C2 -d -r1.174 -r1.175 *** test_descr.py 6 Jan 2003 21:26:44 -0000 1.174 --- test_descr.py 6 Jan 2003 23:00:59 -0000 1.175 *************** *** 3635,3638 **** --- 3635,3690 ---- vereq((C.__module__, C.__name__), (mod, 'D.E')) + def subclass_right_op(): + if verbose: + print "Testing correct dispatch of subclass overloading __r__..." + + # This code tests various cases where right-dispatch of a subclass + # should be preferred over left-dispatch of a base class. + + # Case 1: subclass of int; this tests code in abstract.c::binary_op1() + + class B(int): + def __div__(self, other): + return "B.__div__" + def __rdiv__(self, other): + return "B.__rdiv__" + + vereq(B(1) / 1, "B.__div__") + vereq(1 / B(1), "B.__rdiv__") + + # Case 2: subclass of object; this is just the baseline for case 3 + + class C(object): + def __div__(self, other): + return "C.__div__" + def __rdiv__(self, other): + return "C.__rdiv__" + + vereq(C(1) / 1, "C.__div__") + vereq(1 / C(1), "C.__rdiv__") + + # Case 3: subclass of new-style class; here it gets interesting + + class D(C): + def __div__(self, other): + return "D.__div__" + def __rdiv__(self, other): + return "D.__rdiv__" + + vereq(D(1) / C(1), "D.__div__") + vereq(C(1) / D(1), "D.__rdiv__") + + # Case 4: this didn't work right in 2.2.2 and 2.3a1 + + class E(C): + pass + + vereq(E.__rdiv__, C.__rdiv__) + + vereq(E(1) / 1, "C.__div__") + vereq(1 / E(1), "C.__rdiv__") + vereq(E(1) / C(1), "C.__div__") + vereq(C(1) / E(1), "C.__div__") # This one would fail + def test_main(): *************** *** 3719,3722 **** --- 3771,3775 ---- test_mutable_bases_catch_mro_conflict() mutable_names() + subclass_right_op() if verbose: print "All OK" From gvanrossum@users.sourceforge.net Tue Jan 7 21:47:57 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 13:47:57 -0800 Subject: [Python-checkins] python/dist/src/Objects typeobject.c,2.126.4.30,2.126.4.31 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv21402 Modified Files: Tag: release22-maint typeobject.c Log Message: Backport typeobject.c revision 2.201 plus associated tests from 2.3: Add a refinement to SLOT1BINFULL() that fixes the problem reported in SF bug #623669: only try (e.g.) __rdiv__ before __div__ if the right class actually overrides it. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.126.4.30 retrieving revision 2.126.4.31 diff -C2 -d -r2.126.4.30 -r2.126.4.31 *** typeobject.c 24 Dec 2002 14:48:41 -0000 2.126.4.30 --- typeobject.c 7 Jan 2003 21:47:44 -0000 2.126.4.31 *************** *** 2839,2842 **** --- 2839,2876 ---- } + /* Boolean helper for SLOT1BINFULL(). + right.__class__ is a nontrivial subclass of left.__class__. */ + static int + method_is_overloaded(PyObject *left, PyObject *right, char *name) + { + PyObject *a, *b; + int ok; + + b = PyObject_GetAttrString((PyObject *)(right->ob_type), name); + if (b == NULL) { + PyErr_Clear(); + /* If right doesn't have it, it's not overloaded */ + return 0; + } + + a = PyObject_GetAttrString((PyObject *)(left->ob_type), name); + if (a == NULL) { + PyErr_Clear(); + Py_DECREF(b); + /* If right has it but left doesn't, it's overloaded */ + return 1; + } + + ok = PyObject_RichCompareBool(a, b, Py_NE); + Py_DECREF(a); + Py_DECREF(b); + if (ok < 0) { + PyErr_Clear(); + return 0; + } + + return ok; + } + #define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \ *************** *** 2852,2856 **** PyObject *r; \ if (do_other && \ ! PyType_IsSubtype(other->ob_type, self->ob_type)) { \ r = call_maybe( \ other, ROPSTR, &rcache_str, "(O)", self); \ --- 2886,2891 ---- PyObject *r; \ if (do_other && \ ! PyType_IsSubtype(other->ob_type, self->ob_type) && \ ! method_is_overloaded(self, other, ROPSTR)) { \ r = call_maybe( \ other, ROPSTR, &rcache_str, "(O)", self); \ From gvanrossum@users.sourceforge.net Tue Jan 7 21:49:23 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 13:49:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.113.4.27,1.113.4.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv22373 Modified Files: Tag: release22-maint test_descr.py Log Message: Backport typeobject.c revision 2.201 plus associated tests from 2.3: Add a refinement to SLOT1BINFULL() that fixes the problem reported in SF bug #623669: only try (e.g.) __rdiv__ before __div__ if the right class actually overrides it. Also backport a test for a feature that broke in 2.3 (__dict__ of a new-style class with a user-defined metaclass should be a proxy). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.113.4.27 retrieving revision 1.113.4.28 diff -C2 -d -r1.113.4.27 -r1.113.4.28 *** test_descr.py 24 Dec 2002 15:26:55 -0000 1.113.4.27 --- test_descr.py 7 Jan 2003 21:49:18 -0000 1.113.4.28 *************** *** 3055,3058 **** --- 3055,3124 ---- vereq(d.foo, 1) + def subclass_right_op(): + if verbose: + print "Testing correct dispatch of subclass overloading __r__..." + + # This code tests various cases where right-dispatch of a subclass + # should be preferred over left-dispatch of a base class. + + # Case 1: subclass of int; this tests code in abstract.c::binary_op1() + + class B(int): + def __div__(self, other): + return "B.__div__" + def __rdiv__(self, other): + return "B.__rdiv__" + + vereq(B(1) / 1, "B.__div__") + vereq(1 / B(1), "B.__rdiv__") + + # Case 2: subclass of object; this is just the baseline for case 3 + + class C(object): + def __div__(self, other): + return "C.__div__" + def __rdiv__(self, other): + return "C.__rdiv__" + + vereq(C(1) / 1, "C.__div__") + vereq(1 / C(1), "C.__rdiv__") + + # Case 3: subclass of new-style class; here it gets interesting + + class D(C): + def __div__(self, other): + return "D.__div__" + def __rdiv__(self, other): + return "D.__rdiv__" + + vereq(D(1) / C(1), "D.__div__") + vereq(C(1) / D(1), "D.__rdiv__") + + # Case 4: this didn't work right in 2.2.2 and 2.3a1 + + class E(C): + pass + + vereq(E.__rdiv__, C.__rdiv__) + + vereq(E(1) / 1, "C.__div__") + vereq(1 / E(1), "C.__rdiv__") + vereq(E(1) / C(1), "C.__div__") + vereq(C(1) / E(1), "C.__div__") # This one would fail + + def dict_type_with_metaclass(): + if verbose: + print "Testing type of __dict__ when __metaclass__ set..." + + class B(object): + pass + class M(type): + pass + class C: + # In 2.3a1, C.__dict__ was a real dict rather than a dict proxy + __metaclass__ = M + veris(type(C.__dict__), type(B.__dict__)) + + def test_main(): class_docstrings() *************** *** 3117,3120 **** --- 3183,3189 ---- subtype_resurrection() funnynew() + subclass_right_op() + dict_type_with_metaclass() + if verbose: print "All OK" From akuchling@users.sourceforge.net Tue Jan 7 00:07:23 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 06 Jan 2003 16:07:23 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.103,1.104 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv23748 Modified Files: whatsnew23.tex Log Message: Add tarfile module Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.103 retrieving revision 1.104 diff -C2 -d -r1.103 -r1.104 *** whatsnew23.tex 6 Jan 2003 20:04:17 -0000 1.103 --- whatsnew23.tex 7 Jan 2003 00:07:19 -0000 1.104 *************** *** 1474,1477 **** --- 1474,1481 ---- at the Python level as \code{sys.api_version}. + \item The new \module{tarfile} module + allows reading from and writing to \command{tar}-format archive files. + (Contributed by Lars Gust\"abel.) + \item The new \module{textwrap} module contains functions for wrapping strings containing paragraphs of text. The \function{wrap(\var{text}, From bwarsaw@users.sourceforge.net Tue Jan 7 00:29:10 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 06 Jan 2003 16:29:10 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Charset.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv30329 Modified Files: Charset.py Log Message: CHARSETS, ALIASES, CODEC_MAP: SF feature request 633543, Korean support and other charset defaults. See also: http://article.gmane.org/gmane.comp.python.mime.devel/250 (this just commits the last bit of the article that wasn't part of email 2.4.3.) Index: Charset.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Charset.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Charset.py 21 Oct 2002 05:29:53 -0000 1.11 --- Charset.py 7 Jan 2003 00:29:07 -0000 1.12 *************** *** 36,39 **** --- 36,53 ---- 'iso-8859-1': (QP, QP, None), 'iso-8859-2': (QP, QP, None), + 'iso-8859-3': (QP, QP, None), + 'iso-8859-4': (QP, QP, None), + # iso-8859-5 is Cyrillic, and not especially used + # iso-8859-6 is Arabic, also not particularly used + # iso-8859-7 is Greek, QP will not make it readable + # iso-8859-8 is Hebrew, QP will not make it readable + 'iso-8859-9': (QP, QP, None), + 'iso-8859-10': (QP, QP, None), + # iso-8859-11 is Thai, QP will not make it readable + 'iso-8859-13': (QP, QP, None), + 'iso-8859-14': (QP, QP, None), + 'iso-8859-15': (QP, QP, None), + 'windows-1252':(QP, QP, None), + 'viscii': (QP, QP, None), 'us-ascii': (None, None, None), 'big5': (BASE64, BASE64, None), *************** *** 53,56 **** --- 67,89 ---- 'latin_1': 'iso-8859-1', 'latin-1': 'iso-8859-1', + 'latin_2': 'iso-8859-2', + 'latin-2': 'iso-8859-2', + 'latin_3': 'iso-8859-3', + 'latin-3': 'iso-8859-3', + 'latin_4': 'iso-8859-4', + 'latin-4': 'iso-8859-4', + 'latin_5': 'iso-8859-9', + 'latin-5': 'iso-8859-9', + 'latin_6': 'iso-8859-10', + 'latin-6': 'iso-8859-10', + 'latin_7': 'iso-8859-13', + 'latin-7': 'iso-8859-13', + 'latin_8': 'iso-8859-14', + 'latin-8': 'iso-8859-14', + 'latin_9': 'iso-8859-15', + 'latin-9': 'iso-8859-15', + 'cp949': 'ks_c_5601-1987', + 'euc_jp': 'euc-jp', + 'euc_kr': 'euc-kr', 'ascii': 'us-ascii', } *************** *** 70,73 **** --- 103,110 ---- 'iso-2022-jp': 'japanese.iso-2022-jp', 'shift_jis': 'japanese.shift_jis', + 'euc-kr': 'korean.euc-kr', + 'ks_c_5601-1987': 'korean.cp949', + 'iso-2022-kr': 'korean.iso-2022-kr', + 'johab': 'korean.johab', 'gb2132': 'eucgb2312_cn', 'big5': 'big5_tw', From rhettinger@users.sourceforge.net Tue Jan 7 01:59:28 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 17:59:28 -0800 Subject: [Python-checkins] python/dist/src/Modules arraymodule.c,2.81,2.82 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv20414/Modules Modified Files: arraymodule.c Log Message: SF patch #662433: Fill arraymodule's tp_iter and sq_contains slots Index: arraymodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v retrieving revision 2.81 retrieving revision 2.82 diff -C2 -d -r2.81 -r2.82 *** arraymodule.c 6 Jan 2003 12:41:25 -0000 2.81 --- arraymodule.c 7 Jan 2003 01:58:51 -0000 2.82 *************** *** 845,848 **** --- 845,861 ---- Return index of first occurence of x in the array."); + static int + array_contains(arrayobject *self, PyObject *v) + { + int i, cmp; + + for (i = 0, cmp = 0 ; cmp == 0 && i < self->ob_size; i++) { + PyObject *selfi = getarrayitem((PyObject *)self, i); + cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); + Py_DECREF(selfi); + } + return cmp; + } + static PyObject * array_remove(arrayobject *self, PyObject *v) *************** *** 1656,1660 **** (intobjargproc)array_ass_item, /*sq_ass_item*/ (intintobjargproc)array_ass_slice, /*sq_ass_slice*/ ! NULL, /*sq_contains*/ (binaryfunc)array_inplace_concat, /*sq_inplace_concat*/ (intargfunc)array_inplace_repeat /*sq_inplace_repeat*/ --- 1669,1673 ---- (intobjargproc)array_ass_item, /*sq_ass_item*/ (intintobjargproc)array_ass_slice, /*sq_ass_slice*/ ! (objobjproc)array_contains, /*sq_contains*/ (binaryfunc)array_inplace_concat, /*sq_inplace_concat*/ (intargfunc)array_inplace_repeat /*sq_inplace_repeat*/ *************** *** 1823,1826 **** --- 1836,1841 ---- "); + static PyObject *array_iter(arrayobject *ao); + static PyTypeObject Arraytype = { PyObject_HEAD_INIT(NULL) *************** *** 1850,1854 **** array_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! 0, /* tp_iter */ 0, /* tp_iternext */ array_methods, /* tp_methods */ --- 1865,1869 ---- array_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)array_iter, /* tp_iter */ 0, /* tp_iternext */ array_methods, /* tp_methods */ *************** *** 1865,1868 **** --- 1880,1987 ---- PyObject_Del, /* tp_free */ }; + + + /*********************** Array Iterator **************************/ + + typedef struct { + PyObject_HEAD + long index; + arrayobject *ao; + PyObject * (*getitem)(struct arrayobject *, int); + } arrayiterobject; + + static PyTypeObject PyArrayIter_Type; + + #define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) + + static PyObject * + array_iter(arrayobject *ao) + { + arrayiterobject *it; + + if (!array_Check(ao)) { + PyErr_BadInternalCall(); + return NULL; + } + + it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type); + if (it == NULL) + return NULL; + + Py_INCREF(ao); + it->ao = ao; + it->index = 0; + it->getitem = ao->ob_descr->getitem; + PyObject_GC_Track(it); + return (PyObject *)it; + } + + static PyObject * + arrayiter_getiter(PyObject *it) + { + Py_INCREF(it); + return it; + } + + static PyObject * + arrayiter_next(arrayiterobject *it) + { + assert(PyArrayIter_Check(it)); + if (it->index < it->ao->ob_size) + return (*it->getitem)(it->ao, it->index++); + return NULL; + } + + static void + arrayiter_dealloc(arrayiterobject *it) + { + PyObject_GC_UnTrack(it); + Py_XDECREF(it->ao); + PyObject_GC_Del(it); + } + + static int + arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg) + { + if (it->ao != NULL) + return visit((PyObject *)(it->ao), arg); + return 0; + } + + static PyTypeObject PyArrayIter_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /* ob_size */ + "arrayiterator", /* tp_name */ + sizeof(arrayiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)arrayiter_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)arrayiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)arrayiter_getiter, /* tp_iter */ + (iternextfunc)arrayiter_next, /* tp_iternext */ + 0, /* tp_methods */ + }; + + + /*********************** Install Module **************************/ /* No functions in array module. */ From rhettinger@users.sourceforge.net Tue Jan 7 01:59:28 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 06 Jan 2003 17:59:28 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_array.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv20414/Lib/test Modified Files: test_array.py Log Message: SF patch #662433: Fill arraymodule's tp_iter and sq_contains slots Index: test_array.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_array.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** test_array.py 29 Jul 2002 14:35:04 -0000 1.18 --- test_array.py 7 Jan 2003 01:58:52 -0000 1.19 *************** *** 357,360 **** --- 357,366 ---- b[slice(2,3)] = ins c[2:3:] = ins + # iteration and contains + a = array.array(type, range(10)) + vereq(list(a), range(10)) + b = array.array(type, [20]) + vereq(a[-1] in a, True) + vereq(b[0] not in a, True) # test that overflow exceptions are raised as expected for assignment From gvanrossum@users.sourceforge.net Tue Jan 7 02:23:52 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 06 Jan 2003 18:23:52 -0800 Subject: [Python-checkins] python/nondist/peps pep-0283.txt,1.27,1.28 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv28853 Modified Files: pep-0283.txt Log Message: Add a more concrete release schedule. Index: pep-0283.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0283.txt,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** pep-0283.txt 6 Jan 2003 18:58:25 -0000 1.27 --- pep-0283.txt 7 Jan 2003 02:23:50 -0000 1.28 *************** *** 16,23 **** Bugs may be fixed until the final release. - There is currently no complete schedule. I plan to release alpha - 1 in 2002, and hope for a final release in the second quarter of - 2003. - There will be at least two alpha releases, two beta releases, and one release candidate. Alpha and beta releases will be spaced at --- 16,19 ---- *************** *** 26,29 **** --- 22,35 ---- release does not count). Release candidates will be spaced at least one week apart (excepting again blunder corrections). + + Based on the first alpha release, which was made on Dec. 31, 2002, + here's a fairly aggressive release schedule that follows the above + guidelines: + + alpha 2 -- late January + beta 1 -- late February + beta 2 -- late March + rc 1 -- late April + final -- early May From nnorwitz@users.sourceforge.net Tue Jan 7 22:36:13 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 07 Jan 2003 14:36:13 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib lib.tex,1.212,1.213 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv11720/Doc/lib Modified Files: lib.tex Log Message: SF #664011, move tarfile module in docs Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.212 retrieving revision 1.213 diff -C2 -d -r1.212 -r1.213 *** lib.tex 6 Jan 2003 16:51:34 -0000 1.212 --- lib.tex 7 Jan 2003 22:36:04 -0000 1.213 *************** *** 129,133 **** \input{libfileinput} \input{libxreadlines} - \input{libtarfile} \input{libcalendar} \input{libcmd} --- 129,132 ---- *************** *** 180,183 **** --- 179,183 ---- \input{libbz2} \input{libzipfile} + \input{libtarfile} \input{libreadline} \input{librlcompleter} From bwarsaw@users.sourceforge.net Tue Jan 7 22:42:57 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 07 Jan 2003 14:42:57 -0800 Subject: [Python-checkins] python/dist/src configure,1.373,1.374 configure.in,1.384,1.385 pyconfig.h.in,1.68,1.69 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv13717 Modified Files: configure configure.in pyconfig.h.in Log Message: Test for presence of sysexits.h and set HAVE_SYSEXITS_H if so. Used by posixmodule.c. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.373 retrieving revision 1.374 diff -C2 -d -r1.373 -r1.374 *** configure 1 Jan 2003 20:07:43 -0000 1.373 --- configure 7 Jan 2003 22:42:04 -0000 1.374 *************** *** 1,6 **** #! /bin/sh ! # From configure.in Revision: 1.383 . # Guess values for system-dependent variables and create Makefiles. ! # Generated by GNU Autoconf 2.54 for python 2.3. # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 --- 1,6 ---- #! /bin/sh ! # From configure.in Revision: 1.384 . # Guess values for system-dependent variables and create Makefiles. [...4449 lines suppressed...] ! [\\/]* | ?:[\\/]* ) as_incr_dir=;; ! *) as_incr_dir=.;; ! esac ! as_dummy="$ac_dir" ! for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do ! case $as_mkdir_dir in ! # Skip DOS drivespec ! ?:) as_incr_dir=$as_mkdir_dir ;; ! *) ! as_incr_dir=$as_incr_dir/$as_mkdir_dir ! test -d "$as_incr_dir" || ! mkdir "$as_incr_dir" || ! { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5 ! echo "$as_me: error: cannot create \"$ac_dir\"" >&2;} ! { (exit 1); exit 1; }; } ! ;; ! esac ! done; } rm -f $ac_file Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.384 retrieving revision 1.385 diff -C2 -d -r1.384 -r1.385 *** configure.in 1 Jan 2003 20:07:47 -0000 1.384 --- configure.in 7 Jan 2003 22:42:45 -0000 1.385 *************** *** 750,754 **** 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/resource.h netpacket/packet.h) AC_HEADER_DIRENT AC_HEADER_MAJOR --- 750,754 ---- 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/resource.h netpacket/packet.h sysexits.h) AC_HEADER_DIRENT AC_HEADER_MAJOR Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** pyconfig.h.in 1 Jan 2003 09:51:11 -0000 1.68 --- pyconfig.h.in 7 Jan 2003 22:42:49 -0000 1.69 *************** *** 468,471 **** --- 468,474 ---- #undef HAVE_SYSCONF + /* Define to 1 if you have the header file. */ + #undef HAVE_SYSEXITS_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_AUDIOIO_H From rhettinger@users.sourceforge.net Tue Jan 7 09:55:08 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 07 Jan 2003 01:55:08 -0800 Subject: [Python-checkins] python/dist/src/Tools/idle EditorWindow.py,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory sc8-pr-cvs1:/tmp/cvs-serv23740 Modified Files: EditorWindow.py Log Message: SF bug #652933 (for IdleFork): Open Module "math" Fails When a module doesn't have a __path__ attribute, trigger a dialog box rather than dumping a traceback to the console. Index: EditorWindow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/EditorWindow.py,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** EditorWindow.py 11 Sep 2002 20:36:01 -0000 1.44 --- EditorWindow.py 7 Jan 2003 09:55:03 -0000 1.45 *************** *** 92,96 **** break # find but not load the source file module = imp.load_module(tgt, file, filename, descr) ! path = module.__path__ return file, filename, descr --- 92,99 ---- break # find but not load the source file module = imp.load_module(tgt, file, filename, descr) ! try: ! path = module.__path__ ! except AttributeError: ! raise ImportError, 'No source for module ' + module.__name__ return file, filename, descr From gvanrossum@users.sourceforge.net Tue Jan 7 16:46:28 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 08:46:28 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts logmerge.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv21044 Modified Files: logmerge.py Log Message: Use regular expressions for branch matching, to avoid including changes on a sub-branch into output for a given branch. Index: logmerge.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/logmerge.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** logmerge.py 29 Sep 2002 04:37:36 -0000 1.9 --- logmerge.py 7 Jan 2003 16:46:24 -0000 1.10 *************** *** 34,38 **** """ ! import os, sys, getopt sep1 = '='*77 + '\n' # file separator --- 34,38 ---- """ ! import os, sys, getopt, re sep1 = '='*77 + '\n' # file separator *************** *** 101,105 **** else: working_file = None ! if branch and branch != "HEAD": revisions = {} key = 'symbolic names:\n' --- 101,109 ---- else: working_file = None ! if branch is None: ! pass ! elif branch == "HEAD": ! branch = re.compile(r"^\d+\.\d+$") ! else: revisions = {} key = 'symbolic names:\n' *************** *** 117,124 **** found = 0 rev = revisions.get(branch) if rev: if rev.find('.0.') >= 0: ! rev = rev.replace('.0.', '.') + '.' ! branch = rev or "<>" # <> to force a mismatch records = [] for lines in chunk[1:]: --- 121,129 ---- found = 0 rev = revisions.get(branch) + branch = re.compile(r"^<>$") # <> to force a mismatch by default if rev: if rev.find('.0.') >= 0: ! rev = rev.replace('.0.', '.') ! branch = re.compile(r"^" + re.escape(rev) + r"\.\d+$") records = [] for lines in chunk[1:]: *************** *** 145,155 **** rev = words[1] else: rev = None text.insert(0, revline) if branch: ! if branch == "HEAD": ! if rev is not None and rev.count('.') > 1: ! continue ! elif rev is None or not rev.startswith(branch): continue records.append((date, working_file, rev, author, text)) --- 150,158 ---- rev = words[1] else: + # No 'revision' line -- weird... rev = None text.insert(0, revline) if branch: ! if rev is None or not branch.match(rev): continue records.append((date, working_file, rev, author, text)) From jackjansen@users.sourceforge.net Tue Jan 7 23:21:52 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:21:52 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts BuildApplet.rsrc,1.6,1.6.18.1 BuildApplication.rsrc,1.6,1.6.18.1 ConfigurePython.rsrc,1.15,1.15.10.1 EditPythonPrefs.rsrc,1.15,1.15.18.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv31192 Modified Files: Tag: r23a1-branch BuildApplet.rsrc BuildApplication.rsrc ConfigurePython.rsrc EditPythonPrefs.rsrc Log Message: Upped the memory size of the applets: the old size was getting too small to fit all those Carbon constants into memory. Index: BuildApplet.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplet.rsrc,v retrieving revision 1.6 retrieving revision 1.6.18.1 diff -C2 -d -r1.6 -r1.6.18.1 Binary files /tmp/cvsSO8mTX and /tmp/cvsWaStvL differ Index: BuildApplication.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplication.rsrc,v retrieving revision 1.6 retrieving revision 1.6.18.1 diff -C2 -d -r1.6 -r1.6.18.1 Binary files /tmp/cvsdwaToL and /tmp/cvs8RQIwm differ Index: ConfigurePython.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/ConfigurePython.rsrc,v retrieving revision 1.15 retrieving revision 1.15.10.1 diff -C2 -d -r1.15 -r1.15.10.1 Binary files /tmp/cvsSDzqnE and /tmp/cvs4yFhy8 differ Index: EditPythonPrefs.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/EditPythonPrefs.rsrc,v retrieving revision 1.15 retrieving revision 1.15.18.1 diff -C2 -d -r1.15 -r1.15.18.1 Binary files /tmp/cvseDpfmf and /tmp/cvs6b31bk differ From gvanrossum@users.sourceforge.net Tue Jan 7 23:11:21 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:11:21 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.50,1.337.2.4.2.51 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv27326 Modified Files: Tag: release22-maint NEWS Log Message: Went through the CVS logs for 2.2 and recorded all the relevant fixes. Not that I'm releasing 2.2.3 tomorrow, but I'd like to be prepared. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.50 retrieving revision 1.337.2.4.2.51 diff -C2 -d -r1.337.2.4.2.50 -r1.337.2.4.2.51 *** NEWS 7 Jan 2003 20:40:15 -0000 1.337.2.4.2.50 --- NEWS 7 Jan 2003 23:10:48 -0000 1.337.2.4.2.51 *************** *** 1,11 **** ! What's New in Python 2.2.3 Release date: XX-XXX-2003 ! ========================== ! - XXX There's more, but nobody has updated NEWS so far. - - Fixed broken threadstate swap in readline that could cause fatal - errors when a readline hook was being invoked while a background - thread was active. (SF bugs #660476 and #513033.) What's New in Python 2.2.2 (final) ? --- 1,55 ---- ! What's New in Python 2.2.3 ? Release date: XX-XXX-2003 ! ============================ ! - Bastion.py and rexec.py are disabled. These modules are not safe in ! Python 2.2. or 2.3. ! ! - SF #660476 and #513033: broken threadstate swap in readline could ! cause fatal errors when a readline hook was being invoked while a ! background thread was active. ! ! - SF #623669: a class that inherits __rdiv__ (or another __r*__ ! operator) could end up with infinite recursion. ! ! - Fixed sundry memory leaks. ! ! - Correct long standing bugs in the methods for random distributions. ! The range of u=random() is [0,1), so log(u) and 1/x can fail. Fix ! by setting u=1-random() or by reselecting for a usable value. ! ! - SF #659709: bogus float length computation during string formatting. ! ! - Deleted the __del__ method on socket wrappers; it's not needed and ! prevents GC to work. ! ! - Exceptions raised by __cmp__ weren't always properly handled and ! could cause "exception set without error return" failures. ! ! - SF #643260: __rpow__ wasn't being called. ! ! - SF #534748, #645383: in setup.py, when modules fail to import, don't ! just delete them. ! ! - SF #529750: _Py_ResetReferences() is now a no-op. ! ! - SF #505427: build problem on HP-UX (h_errno not defined). ! ! - SF #564729: make FixTk.py search properly for Tix subdirectories. ! ! - Made string.strip() work as documented. ! ! - Implemented some additional restrictions on __class__ assignment. ! ! - SF #630824: added keyword 'yield' to pydoc.py. ! ! - SF #626172: fix crash using Unicode Latin-1 single character. ! ! - SF #570655: fix misleading option text in distutils rpm creation. ! ! - SF #624982: fix potential segfault in slot_sq_item. ! ! - New codec for Ukrainian Cyrillic. What's New in Python 2.2.2 (final) ? From gvanrossum@users.sourceforge.net Tue Jan 7 23:04:02 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:04:02 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.605,1.606 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv22559 Modified Files: NEWS Log Message: Note about rexec.py and Bastion.py. This requires doc changes and whatsnew updates as well. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.605 retrieving revision 1.606 diff -C2 -d -r1.605 -r1.606 *** NEWS 7 Jan 2003 20:55:26 -0000 1.605 --- NEWS 7 Jan 2003 23:03:05 -0000 1.606 *************** *** 66,69 **** --- 66,72 ---- ------- + - Bastion.py and rexec.py are disabled. These modules are not safe in + Python 2.2. or 2.3. + - realpath is now exported when doing from poxixpath import *. It is also exported for ntpath, macpath, and os2emxpath. From jackjansen@users.sourceforge.net Tue Jan 7 23:23:35 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:23:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_unicode.py,1.74.2.1,1.74.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv31869 Modified Files: Tag: r23a1-branch test_unicode.py Log Message: Made "ascii" the default encoding for MacPython, as suggested by MvL, and ripped out my previous changes to test_unicode. Doing this for 2.3a1 should give people enough time to complain, if they want to, and then we can see whether we want to do anything about it. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.74.2.1 retrieving revision 1.74.2.2 diff -C2 -d -r1.74.2.1 -r1.74.2.2 *** test_unicode.py 5 Jan 2003 23:07:39 -0000 1.74.2.1 --- test_unicode.py 7 Jan 2003 23:23:32 -0000 1.74.2.2 *************** *** 435,445 **** vereq((u'' in u'abc'), True) vereq(('' in u'abc'), True) ! if sys.getdefaultencoding() == 'ascii': ! try: ! u'\xe2' in 'g\xe2teau' ! except UnicodeError: ! pass ! else: ! print '*** contains operator does not propagate UnicodeErrors' print 'done.' --- 435,444 ---- vereq((u'' in u'abc'), True) vereq(('' in u'abc'), True) ! try: ! u'\xe2' in 'g\xe2teau' ! except UnicodeError: ! pass ! else: ! print '*** contains operator does not propagate UnicodeErrors' print 'done.' From jackjansen@users.sourceforge.net Tue Jan 7 23:23:43 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:23:43 -0800 Subject: [Python-checkins] python/dist/src/Mac/Python macmain.c,1.81,1.81.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory sc8-pr-cvs1:/tmp/cvs-serv31924 Modified Files: Tag: r23a1-branch macmain.c Log Message: Made "ascii" the default encoding for MacPython, as suggested by MvL, and ripped out my previous changes to test_unicode. Doing this for 2.3a1 should give people enough time to complain, if they want to, and then we can see whether we want to do anything about it. Index: macmain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macmain.c,v retrieving revision 1.81 retrieving revision 1.81.2.1 diff -C2 -d -r1.81 -r1.81.2.1 *** macmain.c 13 Dec 2002 13:57:35 -0000 1.81 --- macmain.c 7 Jan 2003 23:23:39 -0000 1.81.2.1 *************** *** 490,494 **** --- 490,497 ---- Py_Initialize(); + #if 0 + /* According to Martin v. Loewis this is a bad idea... */ PyUnicode_SetDefaultEncoding(PyMac_getscript()); + #endif PySys_SetArgv(argc, argv); From jackjansen@users.sourceforge.net Tue Jan 7 23:23:55 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:23:55 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.586,1.586.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv32001 Modified Files: Tag: r23a1-branch NEWS Log Message: Made "ascii" the default encoding for MacPython, as suggested by MvL, and ripped out my previous changes to test_unicode. Doing this for 2.3a1 should give people enough time to complain, if they want to, and then we can see whether we want to do anything about it. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.586 retrieving revision 1.586.2.1 diff -C2 -d -r1.586 -r1.586.2.1 *** NEWS 31 Dec 2002 16:38:01 -0000 1.586 --- NEWS 7 Jan 2003 23:23:51 -0000 1.586.2.1 *************** *** 1066,1069 **** --- 1066,1074 ---- - MacPython no longer maps both \r and \n to \n on input for any text file. This feature has been replaced by universal newline support (PEP278). + + - The default encoding for Python sourcefiles in MacPython-OS9 is no longer + mac-roman (or whatever your local Mac encoding was but "ascii", like on + other platforms. If you really need sourcefiles with Mac characters in them + you can change this in site.py. What's New in Python 2.2 final? From gvanrossum@users.sourceforge.net Tue Jan 7 20:01:37 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:01:37 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.55,2.56 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv10353 Modified Files: readline.c Log Message: Various cleanups: - Whitespace normalization. - Cleaned up some comments. - Broke long lines. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.55 retrieving revision 2.56 diff -C2 -d -r2.55 -r2.56 *** readline.c 30 Dec 2002 16:25:41 -0000 2.55 --- readline.c 7 Jan 2003 20:01:29 -0000 2.56 *************** *** 28,32 **** #ifdef HAVE_RL_COMPLETION_MATCHES ! #define completion_matches(x, y) rl_completion_matches((x), ((rl_compentry_func_t *)(y))) #endif --- 28,33 ---- #ifdef HAVE_RL_COMPLETION_MATCHES ! #define completion_matches(x, y) \ ! rl_completion_matches((x), ((rl_compentry_func_t *)(y))) #endif *************** *** 127,153 **** ! PyDoc_STRVAR(set_history_length_doc, ! "set_history_length(length) -> None\n\ ! set the maximal number of items which will be written to\n\ ! the history file. A negative length is used to inhibit\n\ ! history truncation."); static PyObject* set_history_length(PyObject *self, PyObject *args) { ! int length = history_length; ! if (!PyArg_ParseTuple(args, "i:set_history_length", &length)) ! return NULL; ! history_length = length; ! Py_INCREF(Py_None); ! return Py_None; } ! PyDoc_STRVAR(get_history_length_doc, ! "get_history_length() -> int\n\ ! return the maximum number of items that will be written to\n\ ! the history file."); static PyObject* --- 128,152 ---- ! /* Set history length */ static PyObject* set_history_length(PyObject *self, PyObject *args) { ! int length = history_length; ! if (!PyArg_ParseTuple(args, "i:set_history_length", &length)) ! return NULL; ! history_length = length; ! Py_INCREF(Py_None); ! return Py_None; } + PyDoc_STRVAR(set_history_length_doc, + "set_history_length(length) -> None\n\ + set the maximal number of items which will be written to\n\ + the history file. A negative length is used to inhibit\n\ + history truncation."); ! /* Get history length */ static PyObject* *************** *** 159,166 **** } /* Generic hook function setter */ static PyObject * ! set_hook(const char * funcname, PyObject **hook_var, PyThreadState **tstate, PyObject *args) { PyObject *function = Py_None; --- 158,172 ---- } + PyDoc_STRVAR(get_history_length_doc, + "get_history_length() -> int\n\ + return the maximum number of items that will be written to\n\ + the history file."); + + /* Generic hook function setter */ static PyObject * ! set_hook(const char *funcname, PyObject **hook_var, ! PyThreadState **tstate, PyObject *args) { PyObject *function = Py_None; *************** *** 192,195 **** --- 198,202 ---- } + /* Exported functions to specify hook functions in Python */ *************** *** 205,209 **** set_startup_hook(PyObject *self, PyObject *args) { ! return set_hook("startup_hook", &startup_hook, &startup_hook_tstate, args); } --- 212,217 ---- set_startup_hook(PyObject *self, PyObject *args) { ! return set_hook("startup_hook", &startup_hook, ! &startup_hook_tstate, args); } *************** *** 214,222 **** before readline prints the first prompt."); #ifdef HAVE_RL_PRE_INPUT_HOOK static PyObject * set_pre_input_hook(PyObject *self, PyObject *args) { ! return set_hook("pre_input_hook", &pre_input_hook, &pre_input_hook_tstate, args); } --- 222,235 ---- before readline prints the first prompt."); + #ifdef HAVE_RL_PRE_INPUT_HOOK + + /* Set pre-input hook */ + static PyObject * set_pre_input_hook(PyObject *self, PyObject *args) { ! return set_hook("pre_input_hook", &pre_input_hook, ! &pre_input_hook_tstate, args); } *************** *** 227,232 **** --- 240,247 ---- has been printed and just before readline starts reading input\n\ characters."); + #endif + /* Exported function to specify a word completer in Python */ *************** *** 237,241 **** static PyObject *endidx = NULL; ! /* get the beginning index for the scope of the tab-completion */ static PyObject * get_begidx(PyObject *self) --- 252,258 ---- static PyObject *endidx = NULL; ! ! /* Get the beginning index for the scope of the tab-completion */ ! static PyObject * get_begidx(PyObject *self) *************** *** 249,253 **** get the beginning index of the readline tab-completion scope"); ! /* get the ending index for the scope of the tab-completion */ static PyObject * get_endidx(PyObject *self) --- 266,272 ---- get the beginning index of the readline tab-completion scope"); ! ! /* Get the ending index for the scope of the tab-completion */ ! static PyObject * get_endidx(PyObject *self) *************** *** 262,266 **** ! /* set the tab-completion word-delimiters that readline uses */ static PyObject * --- 281,285 ---- ! /* Set the tab-completion word-delimiters that readline uses */ static PyObject * *************** *** 282,285 **** --- 301,307 ---- set the readline word delimiters for tab-completion"); + + /* Add a line to the history buffer */ + static PyObject * py_add_history(PyObject *self, PyObject *args) *************** *** 300,304 **** ! /* get the tab-completion word-delimiters that readline uses */ static PyObject * --- 322,326 ---- ! /* Get the tab-completion word-delimiters that readline uses */ static PyObject * *************** *** 307,315 **** return PyString_FromString(rl_completer_word_break_characters); } ! PyDoc_STRVAR(doc_get_completer_delims, "get_completer_delims() -> string\n\ get the readline word delimiters for tab-completion"); static PyObject * set_completer(PyObject *self, PyObject *args) --- 329,340 ---- return PyString_FromString(rl_completer_word_break_characters); } ! PyDoc_STRVAR(doc_get_completer_delims, "get_completer_delims() -> string\n\ get the readline word delimiters for tab-completion"); + + /* Set the completer function */ + static PyObject * set_completer(PyObject *self, PyObject *args) *************** *** 325,328 **** --- 350,354 ---- It should return the next possible completion starting with 'text'."); + /* Exported function to get any element of history */ *************** *** 347,350 **** --- 373,377 ---- return the current contents of history item at index."); + /* Exported function to get current length of history */ *************** *** 362,365 **** --- 389,393 ---- return the current (not the maximum) length of history."); + /* Exported function to read the current line buffer */ *************** *** 374,377 **** --- 402,406 ---- return the current contents of the line buffer."); + /* Exported function to insert text into the line buffer */ *************** *** 391,394 **** --- 420,426 ---- Insert text into the command line."); + + /* Redisplay the line buffer */ + static PyObject * redisplay(PyObject *self) *************** *** 404,407 **** --- 436,440 ---- contents of the line buffer."); + /* Table of functions exported by the module */ *************** *** 409,420 **** { {"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind}, ! {"get_line_buffer", (PyCFunction)get_line_buffer, METH_NOARGS, doc_get_line_buffer}, {"insert_text", insert_text, METH_VARARGS, doc_insert_text}, {"redisplay", (PyCFunction)redisplay, METH_NOARGS, doc_redisplay}, {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file}, ! {"read_history_file", read_history_file, METH_VARARGS, doc_read_history_file}, ! {"write_history_file", write_history_file, METH_VARARGS, doc_write_history_file}, {"get_history_item", get_history_item, --- 442,453 ---- { {"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind}, ! {"get_line_buffer", (PyCFunction)get_line_buffer, METH_NOARGS, doc_get_line_buffer}, {"insert_text", insert_text, METH_VARARGS, doc_insert_text}, {"redisplay", (PyCFunction)redisplay, METH_NOARGS, doc_redisplay}, {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file}, ! {"read_history_file", read_history_file, METH_VARARGS, doc_read_history_file}, ! {"write_history_file", write_history_file, METH_VARARGS, doc_write_history_file}, {"get_history_item", get_history_item, *************** *** 422,428 **** {"get_current_history_length", (PyCFunction)get_current_history_length, METH_NOARGS, doc_get_current_history_length}, ! {"set_history_length", set_history_length, METH_VARARGS, set_history_length_doc}, ! {"get_history_length", get_history_length, METH_VARARGS, get_history_length_doc}, {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, --- 455,461 ---- {"get_current_history_length", (PyCFunction)get_current_history_length, METH_NOARGS, doc_get_current_history_length}, ! {"set_history_length", set_history_length, METH_VARARGS, set_history_length_doc}, ! {"get_history_length", get_history_length, METH_VARARGS, get_history_length_doc}, {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, *************** *** 430,442 **** {"get_endidx", (PyCFunction)get_endidx, METH_NOARGS, doc_get_endidx}, ! {"set_completer_delims", set_completer_delims, METH_VARARGS, doc_set_completer_delims}, {"add_history", py_add_history, METH_VARARGS, doc_add_history}, ! {"get_completer_delims", (PyCFunction)get_completer_delims, METH_NOARGS, doc_get_completer_delims}, ! ! {"set_startup_hook", set_startup_hook, METH_VARARGS, doc_set_startup_hook}, #ifdef HAVE_RL_PRE_INPUT_HOOK ! {"set_pre_input_hook", set_pre_input_hook, METH_VARARGS, doc_set_pre_input_hook}, #endif {0, 0} --- 463,477 ---- {"get_endidx", (PyCFunction)get_endidx, METH_NOARGS, doc_get_endidx}, ! {"set_completer_delims", set_completer_delims, METH_VARARGS, doc_set_completer_delims}, {"add_history", py_add_history, METH_VARARGS, doc_add_history}, ! {"get_completer_delims", (PyCFunction)get_completer_delims, METH_NOARGS, doc_get_completer_delims}, ! ! {"set_startup_hook", set_startup_hook, ! METH_VARARGS, doc_set_startup_hook}, #ifdef HAVE_RL_PRE_INPUT_HOOK ! {"set_pre_input_hook", set_pre_input_hook, ! METH_VARARGS, doc_set_pre_input_hook}, #endif {0, 0} *************** *** 459,465 **** if (r == NULL) goto error; ! if (r == Py_None) result = 0; ! else result = PyInt_AsLong(r); Py_DECREF(r); --- 494,500 ---- if (r == NULL) goto error; ! if (r == Py_None) result = 0; ! else result = PyInt_AsLong(r); Py_DECREF(r); *************** *** 614,618 **** char *p, *q; PyOS_sighandler_t old_inthandler; ! old_inthandler = PyOS_setsig(SIGINT, onintr); if (setjmp(jbuf)) { --- 649,653 ---- char *p, *q; PyOS_sighandler_t old_inthandler; ! old_inthandler = PyOS_setsig(SIGINT, onintr); if (setjmp(jbuf)) { *************** *** 626,637 **** rl_event_hook = PyOS_InputHook; ! if (sys_stdin != rl_instream || sys_stdout != rl_outstream) { ! rl_instream = sys_stdin; ! rl_outstream = sys_stdout; #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER ! rl_prep_terminal (1); #endif ! } ! p = readline(prompt); PyOS_setsig(SIGINT, old_inthandler); --- 661,672 ---- rl_event_hook = PyOS_InputHook; ! if (sys_stdin != rl_instream || sys_stdout != rl_outstream) { ! rl_instream = sys_stdin; ! rl_outstream = sys_stdout; #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER ! rl_prep_terminal (1); #endif ! } ! p = readline(prompt); PyOS_setsig(SIGINT, old_inthandler); *************** *** 689,693 **** (PyObject *)NULL, PYTHON_API_VERSION); ! PyOS_ReadlineFunctionPointer = call_readline; ! setup_readline(); } --- 724,728 ---- (PyObject *)NULL, PYTHON_API_VERSION); ! PyOS_ReadlineFunctionPointer = call_readline; ! setup_readline(); } From gvanrossum@users.sourceforge.net Tue Jan 7 20:31:25 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:31:25 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv21547 Modified Files: readline.c Log Message: Fix from Michael Stone for SF bug #660476 and #513033 (bogus thread state swaps in readline). Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** readline.c 7 Jan 2003 20:04:12 -0000 2.57 --- readline.c 7 Jan 2003 20:31:20 -0000 2.58 *************** *** 482,495 **** static int ! on_hook(PyObject *func, PyThreadState *tstate) { int result = 0; if (func != NULL) { PyObject *r; - PyThreadState *save_tstate; /* Note that readline is called with the interpreter lock released! */ ! save_tstate = PyThreadState_Swap(NULL); ! PyEval_RestoreThread(tstate); r = PyObject_CallFunction(func, NULL); if (r == NULL) --- 482,493 ---- static int ! on_hook(PyObject *func, PyThreadState **tstate) { int result = 0; if (func != NULL) { PyObject *r; /* Note that readline is called with the interpreter lock released! */ ! PyEval_RestoreThread(*tstate); r = PyObject_CallFunction(func, NULL); if (r == NULL) *************** *** 505,510 **** Py_XDECREF(r); done: ! PyEval_SaveThread(); ! PyThreadState_Swap(save_tstate); } return result; --- 503,507 ---- Py_XDECREF(r); done: ! *tstate = PyEval_SaveThread(); } return result; *************** *** 514,518 **** on_startup_hook(void) { ! return on_hook(startup_hook, startup_hook_tstate); } --- 511,515 ---- on_startup_hook(void) { ! return on_hook(startup_hook, &startup_hook_tstate); } *************** *** 521,525 **** on_pre_input_hook(void) { ! return on_hook(pre_input_hook, pre_input_hook_tstate); } #endif --- 518,522 ---- on_pre_input_hook(void) { ! return on_hook(pre_input_hook, &pre_input_hook_tstate); } #endif *************** *** 534,541 **** if (completer != NULL) { PyObject *r; - PyThreadState *save_tstate; /* Note that readline is called with the interpreter lock released! */ - save_tstate = PyThreadState_Swap(NULL); PyEval_RestoreThread(completer_tstate); /* Don't use the default filename completion if we --- 531,536 ---- *************** *** 560,565 **** Py_XDECREF(r); done: ! PyEval_SaveThread(); ! PyThreadState_Swap(save_tstate); } return result; --- 555,559 ---- Py_XDECREF(r); done: ! completer_tstate = PyEval_SaveThread(); } return result; *************** *** 567,571 **** ! /* a more flexible constructor that saves the "begidx" and "endidx" * before calling the normal completer */ --- 561,565 ---- ! /* A more flexible constructor that saves the "begidx" and "endidx" * before calling the normal completer */ From gvanrossum@users.sourceforge.net Tue Jan 7 20:33:47 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:33:47 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.603,1.604 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv22724 Modified Files: NEWS Log Message: Fix from Michael Stone for SF bug #660476 and #513033 (bogus thread state swaps in readline). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.603 retrieving revision 1.604 diff -C2 -d -r1.603 -r1.604 *** NEWS 6 Jan 2003 06:51:36 -0000 1.603 --- NEWS 7 Jan 2003 20:33:41 -0000 1.604 *************** *** 22,25 **** --- 22,29 ---- ----------------- + - Fixed broken threadstate swap in readline that could cause fatal + errors when a readline hook was being invoked while a background + thread was active. (SF bugs #660476 and #513033.) + - fcntl now exposes the strops.h I_* constants. From gvanrossum@users.sourceforge.net Tue Jan 7 20:38:03 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:38:03 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.41.6.3,2.41.6.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv24999 Modified Files: Tag: release22-maint readline.c Log Message: Backport 2.58 from trunk (minus the cleanup): Fix from Michael Stone for SF bug #660476 and #513033 (bogus thread state swaps in readline). Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.41.6.3 retrieving revision 2.41.6.4 diff -C2 -d -r2.41.6.3 -r2.41.6.4 *** readline.c 6 Oct 2002 05:43:47 -0000 2.41.6.3 --- readline.c 7 Jan 2003 20:37:58 -0000 2.41.6.4 *************** *** 405,418 **** static int ! on_hook(PyObject *func, PyThreadState *tstate) { int result = 0; if (func != NULL) { PyObject *r; - PyThreadState *save_tstate; /* Note that readline is called with the interpreter lock released! */ ! save_tstate = PyThreadState_Swap(NULL); ! PyEval_RestoreThread(tstate); r = PyObject_CallFunction(func, NULL); if (r == NULL) --- 405,416 ---- static int ! on_hook(PyObject *func, PyThreadState **tstate) { int result = 0; if (func != NULL) { PyObject *r; /* Note that readline is called with the interpreter lock released! */ ! PyEval_RestoreThread(*tstate); r = PyObject_CallFunction(func, NULL); if (r == NULL) *************** *** 428,433 **** Py_XDECREF(r); done: ! PyEval_SaveThread(); ! PyThreadState_Swap(save_tstate); } return result; --- 426,430 ---- Py_XDECREF(r); done: ! *tstate = PyEval_SaveThread(); } return result; *************** *** 437,441 **** on_startup_hook(void) { ! return on_hook(startup_hook, startup_hook_tstate); } --- 434,438 ---- on_startup_hook(void) { ! return on_hook(startup_hook, &startup_hook_tstate); } *************** *** 444,448 **** on_pre_input_hook(void) { ! return on_hook(pre_input_hook, pre_input_hook_tstate); } #endif --- 441,445 ---- on_pre_input_hook(void) { ! return on_hook(pre_input_hook, &pre_input_hook_tstate); } #endif *************** *** 456,463 **** if (completer != NULL) { PyObject *r; - PyThreadState *save_tstate; /* Note that readline is called with the interpreter lock released! */ - save_tstate = PyThreadState_Swap(NULL); PyEval_RestoreThread(completer_tstate); r = PyObject_CallFunction(completer, "si", text, state); --- 453,458 ---- *************** *** 479,484 **** Py_XDECREF(r); done: ! PyEval_SaveThread(); ! PyThreadState_Swap(save_tstate); } return result; --- 474,478 ---- Py_XDECREF(r); done: ! completer_tstate = PyEval_SaveThread(); } return result; From gvanrossum@users.sourceforge.net Tue Jan 7 20:39:00 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:39:00 -0800 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.149.4.13,1.149.4.14 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv25440 Modified Files: Tag: release22-maint ACKS Log Message: Backport 2.58 from trunk (minus the cleanup): Fix from Michael Stone for SF bug #660476 and #513033 (bogus thread state swaps in readline). Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.149.4.13 retrieving revision 1.149.4.14 diff -C2 -d -r1.149.4.13 -r1.149.4.14 *** ACKS 17 Oct 2002 22:17:41 -0000 1.149.4.13 --- ACKS 7 Jan 2003 20:38:51 -0000 1.149.4.14 *************** *** 500,503 **** --- 500,504 ---- Casper Stoel Peter Stoehr + Michael Stone Ken Stox William Tanksley From gvanrossum@users.sourceforge.net Tue Jan 7 20:40:41 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:40:41 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.49,1.337.2.4.2.50 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv26128 Modified Files: Tag: release22-maint NEWS Log Message: Backport 2.58 from trunk (minus the cleanup): Fix from Michael Stone for SF bug #660476 and #513033 (bogus thread state swaps in readline). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.49 retrieving revision 1.337.2.4.2.50 diff -C2 -d -r1.337.2.4.2.49 -r1.337.2.4.2.50 *** NEWS 14 Oct 2002 20:11:50 -0000 1.337.2.4.2.49 --- NEWS 7 Jan 2003 20:40:15 -0000 1.337.2.4.2.50 *************** *** 1,2 **** --- 1,12 ---- + What's New in Python 2.2.3 + Release date: XX-XXX-2003 + ========================== + + - XXX There's more, but nobody has updated NEWS so far. + + - Fixed broken threadstate swap in readline that could cause fatal + errors when a readline hook was being invoked while a background + thread was active. (SF bugs #660476 and #513033.) + What's New in Python 2.2.2 (final) ? Release date: 14-Oct-2002 From bwarsaw@users.sourceforge.net Tue Jan 7 20:55:57 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:55:57 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.604,1.605 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv32232 Modified Files: NEWS Log Message: A note about EX_OK and friends in the posixmodule. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.604 retrieving revision 1.605 diff -C2 -d -r1.604 -r1.605 *** NEWS 7 Jan 2003 20:33:41 -0000 1.604 --- NEWS 7 Jan 2003 20:55:26 -0000 1.605 *************** *** 22,25 **** --- 22,27 ---- ----------------- + - os/posixmodule has grown the sysexits.h constants (EX_OK and friends). + - Fixed broken threadstate swap in readline that could cause fatal errors when a readline hook was being invoked while a background From bwarsaw@users.sourceforge.net Tue Jan 7 20:57:24 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 07 Jan 2003 12:57:24 -0800 Subject: [Python-checkins] python/dist/src/Modules posixmodule.c,2.280,2.281 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv440 Modified Files: posixmodule.c Log Message: all_ins(): EX_OK and friends, constants from sysexits.h Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.280 retrieving revision 2.281 diff -C2 -d -r2.280 -r2.281 *** posixmodule.c 1 Jan 2003 09:51:12 -0000 2.280 --- posixmodule.c 7 Jan 2003 20:57:09 -0000 2.281 *************** *** 89,92 **** --- 89,96 ---- #endif + #ifdef HAVE_SYSEXITS_H + #include + #endif /* HAVE_SYSEXITS_H */ + /* Various compilers have only certain posix functions */ /* XXX Gosh I wish these were all moved into pyconfig.h */ *************** *** 7651,7654 **** --- 7655,7711 ---- if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1; #endif + + /* These come from sysexits.h */ + #ifdef EX_OK + if (ins(d, "EX_OK", (long)EX_OK)) return -1; + #endif EX_OK + #ifdef EX_USAGE + if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1; + #endif EX_USAGE + #ifdef EX_DATAERR + if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1; + #endif EX_DATAERR + #ifdef EX_NOINPUT + if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1; + #endif EX_NOINPUT + #ifdef EX_NOUSER + if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1; + #endif EX_NOUSER + #ifdef EX_NOHOST + if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1; + #endif EX_NOHOST + #ifdef EX_UNAVAILABLE + if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1; + #endif EX_UNAVAILABLE + #ifdef EX_SOFTWARE + if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1; + #endif EX_SOFTWARE + #ifdef EX_OSERR + if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1; + #endif EX_OSERR + #ifdef EX_OSFILE + if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1; + #endif EX_OSFILE + #ifdef EX_CANTCREAT + if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1; + #endif EX_CANTCREAT + #ifdef EX_IOERR + if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1; + #endif EX_IOERR + #ifdef EX_TEMPFAIL + if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1; + #endif EX_TEMPFAIL + #ifdef EX_PROTOCOL + if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1; + #endif EX_PROTOCOL + #ifdef EX_NOPERM + if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1; + #endif EX_NOPERM + #ifdef EX_CONFIG + if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1; + #endif EX_CONFIG + #ifdef EX_NOTFOUND + if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1; + #endif EX_NOTFOUND #ifdef HAVE_SPAWNV From jackjansen@users.sourceforge.net Tue Jan 7 23:26:02 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:26:02 -0800 Subject: [Python-checkins] python/dist/src/Mac/Include macbuildno.h,1.25.4.1,1.25.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory sc8-pr-cvs1:/tmp/cvs-serv389 Modified Files: Tag: r23a1-branch macbuildno.h Log Message: Next stab at a final 2.3a1 distribution:-) Index: macbuildno.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/macbuildno.h,v retrieving revision 1.25.4.1 retrieving revision 1.25.4.2 diff -C2 -d -r1.25.4.1 -r1.25.4.2 *** macbuildno.h 5 Jan 2003 23:13:33 -0000 1.25.4.1 --- macbuildno.h 7 Jan 2003 23:26:00 -0000 1.25.4.2 *************** *** 1 **** ! #define BUILD 147 --- 1 ---- ! #define BUILD 148 From jackjansen@users.sourceforge.net Tue Jan 7 23:25:17 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:25:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macfs.py,1.1,1.1.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv32582 Modified Files: Tag: r23a1-branch macfs.py Log Message: Removed the SetDates warning. The warning is in the readme, and the print statement was too obtrusive (it appeared during the installation process, and the user needed to close the resulting window manually). Index: macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macfs.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -C2 -d -r1.1 -r1.1.2.1 *** macfs.py 30 Dec 2002 22:04:20 -0000 1.1 --- macfs.py 7 Jan 2003 23:25:14 -0000 1.1.2.1 *************** *** 58,62 **** def SetDates(self, *dates): ! print "FSSpec.SetDates no longer implemented" class FSRef(Carbon.File.FSRef): --- 58,62 ---- def SetDates(self, *dates): ! pass # print "FSSpec.SetDates not yet implemented" class FSRef(Carbon.File.FSRef): *************** *** 70,74 **** def Update(self, *args): ! print "Alias.Update not yet implemented" def Resolve(self, src=None): --- 70,74 ---- def Update(self, *args): ! pass # print "Alias.Update not yet implemented" def Resolve(self, src=None): From gvanrossum@users.sourceforge.net Wed Jan 8 01:23:03 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 17:23:03 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.133,1.134 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv9284 Modified Files: setup.py Log Message: Enable building and testing of ossaudiodev for Linux. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.133 retrieving revision 1.134 diff -C2 -d -r1.133 -r1.134 *** setup.py 4 Jan 2003 04:06:56 -0000 1.133 --- setup.py 8 Jan 2003 01:23:01 -0000 1.134 *************** *** 723,726 **** --- 723,727 ---- # Linux-specific modules exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) ) + exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) ) if platform == 'sunos5': From gvanrossum@users.sourceforge.net Wed Jan 8 01:23:03 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 17:23:03 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_ossaudiodev,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv9284/Lib/test/output Added Files: test_ossaudiodev Log Message: Enable building and testing of ossaudiodev for Linux. --- NEW FILE: test_ossaudiodev --- test_ossaudiodev expected rate >= 0, not -1 expected sample size >= 0, not -2 nchannels must be 1 or 2, not 3 unknown audio encoding: 177 for linear unsigned 16-bit little-endian audio, expected sample size 16, not 8 for linear unsigned 8-bit audio, expected sample size 8, not 16 From gward@users.sourceforge.net Wed Jan 8 01:37:44 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Tue, 07 Jan 2003 17:37:44 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.134,1.135 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv13518 Modified Files: setup.py Log Message: Add reminder that ossaudiodev can/should also be built on FreeBSD. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.134 retrieving revision 1.135 diff -C2 -d -r1.134 -r1.135 *** setup.py 8 Jan 2003 01:23:01 -0000 1.134 --- setup.py 8 Jan 2003 01:37:41 -0000 1.135 *************** *** 723,726 **** --- 723,728 ---- # Linux-specific modules exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) ) + + # XXX should also build this on FreeBSD! exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) ) From akuchling@users.sourceforge.net Wed Jan 8 02:09:45 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Tue, 07 Jan 2003 18:09:45 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.104,1.105 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv21383 Modified Files: whatsnew23.tex Log Message: Bump version number Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.104 retrieving revision 1.105 diff -C2 -d -r1.104 -r1.105 *** whatsnew23.tex 7 Jan 2003 00:07:19 -0000 1.104 --- whatsnew23.tex 8 Jan 2003 02:09:40 -0000 1.105 *************** *** 3,7 **** \title{What's New in Python 2.3} ! \release{0.07} \author{A.M. Kuchling} \authoraddress{\email{amk@amk.ca}} --- 3,7 ---- \title{What's New in Python 2.3} ! \release{0.08} \author{A.M. Kuchling} \authoraddress{\email{amk@amk.ca}} From gward@users.sourceforge.net Wed Jan 8 03:02:30 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Tue, 07 Jan 2003 19:02:30 -0800 Subject: [Python-checkins] python/dist/src/Doc/ext newtypes.tex,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory sc8-pr-cvs1:/tmp/cvs-serv4481 Modified Files: newtypes.tex Log Message: Rewrite awkward/ungrammatical sentence. Typo fix. Index: newtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/newtypes.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** newtypes.tex 3 Jan 2003 21:09:57 -0000 1.20 --- newtypes.tex 8 Jan 2003 03:02:26 -0000 1.21 *************** *** 53,58 **** \end{verbatim} ! This is what a Noddy object will contain. In this case nothing more ! than every Python object contains - a refcount and a pointer to a type object. These are the fields the \code{PyObject_HEAD} macro brings in. The reason for the macro is to standardize the layout and to --- 53,58 ---- \end{verbatim} ! This is what a Noddy object will contain---in this case, nothing more ! than every Python object contains, namely a refcount and a pointer to a type object. These are the fields the \code{PyObject_HEAD} macro brings in. The reason for the macro is to standardize the layout and to *************** *** 62,66 **** do from habit, and your compiler might not complain, but someone else's probably will! (On Windows, MSVC is known to call this an ! error and refuse to produce compiled code.) For contrast, let's take a look at the corresponding definition for --- 62,66 ---- do from habit, and your compiler might not complain, but someone else's probably will! (On Windows, MSVC is known to call this an ! error and refuse to compile the code.) For contrast, let's take a look at the corresponding definition for From gward@users.sourceforge.net Wed Jan 8 03:04:44 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Tue, 07 Jan 2003 19:04:44 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsmtplib.tex,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv5452 Modified Files: libsmtplib.tex Log Message: There's no such method as has_option() -- should be has_extn(). Index: libsmtplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsmtplib.tex,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** libsmtplib.tex 24 Mar 2002 15:41:40 -0000 1.22 --- libsmtplib.tex 8 Jan 2003 03:04:42 -0000 1.23 *************** *** 139,145 **** argument defaults to the fully qualified domain name of the local host. Examine the response for ESMTP option and store them for use by ! \method{has_option()}. ! Unless you wish to use \method{has_option()} before sending mail, it should not be necessary to call this method explicitly. It will be implicitly called by \method{sendmail()} when necessary. --- 139,145 ---- argument defaults to the fully qualified domain name of the local host. Examine the response for ESMTP option and store them for use by ! \method{has_extn()}. ! Unless you wish to use \method{has_extn()} before sending mail, it should not be necessary to call this method explicitly. It will be implicitly called by \method{sendmail()} when necessary. From gvanrossum@users.sourceforge.net Tue Jan 7 23:01:30 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 07 Jan 2003 15:01:30 -0800 Subject: [Python-checkins] python/dist/src/Lib rexec.py,1.34.10.4,1.34.10.5 Bastion.py,1.6,1.6.24.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv21744 Modified Files: Tag: release22-maint rexec.py Bastion.py Log Message: Sabotage rexec.py and Bastion.py. These are not secure in Python 2.2 or 2.3. Index: rexec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v retrieving revision 1.34.10.4 retrieving revision 1.34.10.5 diff -C2 -d -r1.34.10.4 -r1.34.10.5 *** rexec.py 19 Nov 2002 19:22:25 -0000 1.34.10.4 --- rexec.py 7 Jan 2003 23:01:13 -0000 1.34.10.5 *************** *** 180,183 **** --- 180,186 ---- """ + + raise RuntimeError, "This code is not secure in Python 2.2 and 2.3" + ihooks._Verbose.__init__(self, verbose) # XXX There's a circular reference here: Index: Bastion.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/Bastion.py,v retrieving revision 1.6 retrieving revision 1.6.24.1 diff -C2 -d -r1.6 -r1.6.24.1 *** Bastion.py 20 Jan 2001 19:54:20 -0000 1.6 --- Bastion.py 7 Jan 2003 23:01:21 -0000 1.6.24.1 *************** *** 98,101 **** --- 98,103 ---- """ + raise RuntimeError, "This code is not secure in Python 2.2 and 2.3" + # Note: we define *two* ad-hoc functions here, get1 and get2. # Both are intended to be called in the same way: get(name). From bwarsaw@users.sourceforge.net Tue Jan 7 22:43:30 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 07 Jan 2003 14:43:30 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.108,1.109 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv14668 Modified Files: libos.tex Log Message: Document EX_OK and friends. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.108 retrieving revision 1.109 diff -C2 -d -r1.108 -r1.109 *** libos.tex 6 Jan 2003 13:31:26 -0000 1.108 --- libos.tex 7 Jan 2003 22:43:25 -0000 1.109 *************** *** 1118,1121 **** --- 1118,1235 ---- \end{funcdesc} + The following exit codes are a defined, and can be used with + \function{_exit()}, although they are not required. These are + typically used for system programs written in Python, such as a + mail server's external command delivery program. + + \begin{datadesc}{EX_OK} + Exit code that means no error occurred. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_USAGE} + Exit code that means the command was used incorrectly, such as when + the wrong number of arguments are given. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_DATAERR} + Exit code that means the input data was incorrect. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_NOINPUT} + Exit code that means an input file did not exist or was not readable. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_NOUSER} + Exit code that means a specified user did not exist. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_NOHOST} + Exit code that means a specified host did not exist. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_UNAVAILABLE} + Exit code that means that a required service is unavailable. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_SOFTWARE} + Exit code that means an internal software error was detected. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_OSERR} + Exit code that means an operating system error was detected, such as + the inability to fork or create a pipe. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_OSFILE} + Exit code that means some system file did not exist, could not be + opened, or had some other kind of error. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_CANTCREAT} + Exit code that means a user specified output file could not be created. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_IOERR} + Exit code that means that an error occurred while doing I/O on some file. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_TEMPFAIL} + Exit code that means a temporary failure occurred. This indicates + something that may not really be an error, such as a network + connection that couldn't be made during a retryable operation. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_PROTOCOL} + Exit code that means that a protocol exchange was illegal, invalid, or + not understood. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_NOPERM} + Exit code that means that there were insufficient permissions to + perform the operation (but not intended for file system problems). + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_CONFIG} + Exit code that means that some kind of configuration error occurred. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + + \begin{datadesc}{EX_NOTFOUND} + Exit code that means something like ``an entry was not found''. + Availability: \UNIX. + \versionadded{2.3} + \end{datadesc} + \begin{funcdesc}{fork}{} Fork a child process. Return \code{0} in the child, the child's From nnorwitz@users.sourceforge.net Wed Jan 8 05:27:44 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 07 Jan 2003 21:27:44 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.105,1.106 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv22014/whatsnew Modified Files: whatsnew23.tex Log Message: command doesn't work, but program does, not sure it's correct, though Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.105 retrieving revision 1.106 diff -C2 -d -r1.105 -r1.106 *** whatsnew23.tex 8 Jan 2003 02:09:40 -0000 1.105 --- whatsnew23.tex 8 Jan 2003 05:27:42 -0000 1.106 *************** *** 1475,1479 **** \item The new \module{tarfile} module ! allows reading from and writing to \command{tar}-format archive files. (Contributed by Lars Gust\"abel.) --- 1475,1479 ---- \item The new \module{tarfile} module ! allows reading from and writing to \program{tar}-format archive files. (Contributed by Lars Gust\"abel.) From fdrake@users.sourceforge.net Wed Jan 8 07:09:46 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 07 Jan 2003 23:09:46 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_ossaudiodev.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv16671 Modified Files: test_ossaudiodev.py Log Message: - be explicit: audio data files should be opened in binary mode - ossaudiodev.open() raises IOError, not ossaudiodev.error, for cases which get mapped to TestSkipped Index: test_ossaudiodev.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_ossaudiodev.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_ossaudiodev.py 10 Dec 2002 16:27:35 -0000 1.2 --- test_ossaudiodev.py 8 Jan 2003 07:09:43 -0000 1.3 *************** *** 14,18 **** def read_sound_file(path): ! fp = open(path, 'r') size, enc, rate, nchannels, extra = sunaudio.gethdr(fp) data = fp.read() --- 14,18 ---- def read_sound_file(path): ! fp = open(path, 'rb') size, enc, rate, nchannels, extra = sunaudio.gethdr(fp) data = fp.read() *************** *** 31,35 **** try: a = ossaudiodev.open('w') ! except ossaudiodev.error, msg: if msg[0] in (errno.EACCES, errno.ENODEV, errno.EBUSY): raise TestSkipped, msg --- 31,35 ---- try: a = ossaudiodev.open('w') ! except IOError, msg: if msg[0] in (errno.EACCES, errno.ENODEV, errno.EBUSY): raise TestSkipped, msg From fdrake@users.sourceforge.net Wed Jan 8 07:21:55 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 07 Jan 2003 23:21:55 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libundoc.tex,1.82,1.83 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv19793 Modified Files: libundoc.tex Log Message: Add notes about the linuxaudiodev and ossaudiodev modules. Index: libundoc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libundoc.tex,v retrieving revision 1.82 retrieving revision 1.83 diff -C2 -d -r1.82 -r1.83 *** libundoc.tex 10 Oct 2002 18:24:53 -0000 1.82 --- libundoc.tex 8 Jan 2003 07:21:53 -0000 1.83 *************** *** 62,65 **** --- 62,69 ---- --- Platform-independent API for playing audio data. + \item[\module{linuxaudiodev}] + --- Play audio data on the Linux audio device. Replaced in Python 2.3 + by the \module{ossaudiodev} module. + \item[\module{sunaudio}] --- Interpret Sun audio headers (may become obsolete or a tool/demo). *************** *** 68,71 **** --- 72,79 ---- --- Convert "arbitrary" sound files to AIFF files; should probably become a tool or demo. Requires the external program \program{sox}. + + \item[\module{ossaudiodev}] + --- Play audio data via the Open Sound System API. This is usable on + Linux, some flavors of BSD, and some commercial \UNIX{} platforms. \end{description} From theller@users.sourceforge.net Wed Jan 8 14:33:51 2003 From: theller@users.sourceforge.net (theller@users.sourceforge.net) Date: Wed, 08 Jan 2003 06:33:51 -0800 Subject: [Python-checkins] python/dist/src/Python sysmodule.c,2.111,2.112 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv12807 Modified Files: sysmodule.c Log Message: Patch #664376: sys.path[0] should contain absolute pathname. This fixes the problem on Windows - that's the only system where I can test it. It leaves sys.argv alone and only changes sys.path[0] to an absolute pathname. Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.111 retrieving revision 2.112 diff -C2 -d -r2.111 -r2.112 *** sysmodule.c 8 Oct 2002 02:44:28 -0000 2.111 --- sysmodule.c 8 Jan 2003 14:33:48 -0000 2.112 *************** *** 970,973 **** --- 970,976 ---- PySys_SetArgv(int argc, char **argv) { + #ifdef MS_WINDOWS + char fullpath[MAX_PATH]; + #endif PyObject *av = makeargvobject(argc, argv); PyObject *path = PySys_GetObject("path"); *************** *** 1012,1015 **** --- 1015,1027 ---- if (argc > 0 && argv0 != NULL) { char *q; + #ifdef MS_WINDOWS + char *ptemp; + if (GetFullPathName(argv0, + sizeof(fullpath), + fullpath, + &ptemp)) { + argv0 = fullpath; + } + #endif p = strrchr(argv0, SEP); /* Test for alternate separator */ From theller@users.sourceforge.net Wed Jan 8 15:14:59 2003 From: theller@users.sourceforge.net (theller@users.sourceforge.net) Date: Wed, 08 Jan 2003 07:14:59 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.606,1.607 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv30081 Modified Files: NEWS Log Message: Mention the change from patch #664376. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.606 retrieving revision 1.607 diff -C2 -d -r1.606 -r1.607 *** NEWS 7 Jan 2003 23:03:05 -0000 1.606 --- NEWS 8 Jan 2003 15:14:55 -0000 1.607 *************** *** 123,126 **** --- 123,129 ---- ------- + - sys.path[0], if it contains a directory name, is now always an + absolute pathname. + - The new logging package is now installed by the Windows installer. It wasn't in 2.3a1 due to oversight. From skip@pobox.com Wed Jan 8 15:38:17 2003 From: skip@pobox.com (Skip Montanaro) Date: Wed, 8 Jan 2003 09:38:17 -0600 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.606,1.607 In-Reply-To: References: Message-ID: <15900.17897.885113.970379@montanaro.dyndns.org> theller> + - sys.path[0], if it contains a directory name, is now always an theller> + absolute pathname. I guess my next question is, why not make all paths absolute? (IOW, why is sys.path[0] special?) Perhaps site.py should contain something like # guard against current directory changes outside of our control, as # when an application changes directory when Python is embedded. import sys, os sys.path = [os.path.abspath(p) for p in sys.path] del sys, os Skip From theller@python.net Wed Jan 8 16:45:51 2003 From: theller@python.net (Thomas Heller) Date: 08 Jan 2003 17:45:51 +0100 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.606,1.607 In-Reply-To: <15900.17897.885113.970379@montanaro.dyndns.org> References: <15900.17897.885113.970379@montanaro.dyndns.org> Message-ID: <4r8jio8w.fsf@python.net> Skip Montanaro writes: > > theller> + - sys.path[0], if it contains a directory name, is now always an > theller> + absolute pathname. > > I guess my next question is, why not make all paths absolute? (IOW, why is > sys.path[0] special?) As Guido has explained, it is special because it is created *after* site.py has run. > Perhaps site.py should contain something like > > # guard against current directory changes outside of our control, as > # when an application changes directory when Python is embedded. > import sys, os > sys.path = [os.path.abspath(p) for p in sys.path] > del sys, os It already does, and additional code makes sure that the already imported modules __file__ attributes are absolute paths: for m in sys.modules.values(): if hasattr(m, "__file__") and m.__file__: m.__file__ = os.path.abspath(m.__file__) del m # This ensures that the initial path provided by the interpreter contains # only absolute pathnames, even if we're running from the build directory. L = [] _dirs_in_sys_path = {} dir = dircase = None # sys.path may be empty at this point for dir in sys.path: # Filter out duplicate paths (on case-insensitive file systems also # if they only differ in case); turn relative paths into absolute # paths. dir, dircase = makepath(dir) if not dircase in _dirs_in_sys_path: L.append(dir) _dirs_in_sys_path[dircase] = 1 sys.path[:] = L del dir, dircase, L From jackjansen@users.sourceforge.net Wed Jan 8 16:28:13 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:13 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules macmodule.c,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Modules Modified Files: macmodule.c Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: macmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macmodule.c,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** macmodule.c 12 Dec 2002 10:31:49 -0000 1.53 --- macmodule.c 8 Jan 2003 16:27:41 -0000 1.54 *************** *** 219,225 **** extern int fclose(FILE *); int fd; ! char *mode; FILE *fp; ! if (!PyArg_ParseTuple(args, "is", &fd, &mode)) return NULL; Py_BEGIN_ALLOW_THREADS --- 219,227 ---- extern int fclose(FILE *); int fd; ! char *mode = "r"; ! int bufsize = -1; FILE *fp; ! PyObject *f; ! if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize)) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 228,232 **** if (fp == NULL) return mac_error(); ! return PyFile_FromFile(fp, "(fdopen)", mode, fclose); } #endif --- 230,237 ---- if (fp == NULL) return mac_error(); ! f = PyFile_FromFile(fp, "", mode, fclose); ! if (f != NULL) ! PyFile_SetBufSize(f, bufsize); ! return f; } #endif From jackjansen@users.sourceforge.net Wed Jan 8 16:28:13 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:13 -0800 Subject: [Python-checkins] python/dist/src/Mac/Include macbuildno.h,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Include Modified Files: macbuildno.h Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: macbuildno.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/macbuildno.h,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** macbuildno.h 20 Jun 2002 22:56:22 -0000 1.25 --- macbuildno.h 8 Jan 2003 16:27:40 -0000 1.26 *************** *** 1 **** ! #define BUILD 144 --- 1 ---- ! #define BUILD 148 From jackjansen@users.sourceforge.net Wed Jan 8 16:28:49 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:49 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv28313/Modules Modified Files: datetimemodule.c Log Message: Added a couple of casts to make this compile with CodeWarrior. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** datetimemodule.c 4 Jan 2003 18:17:36 -0000 1.32 --- datetimemodule.c 8 Jan 2003 16:28:45 -0000 1.33 *************** *** 2561,2565 **** date_getstate(PyDateTime_Date *self) { ! return PyString_FromStringAndSize(self->data, _PyDateTime_DATE_DATASIZE); } --- 2561,2565 ---- date_getstate(PyDateTime_Date *self) { ! return PyString_FromStringAndSize((char *)self->data, _PyDateTime_DATE_DATASIZE); } *************** *** 3357,3361 **** datetime_getstate(PyDateTime_DateTime *self) { ! return PyString_FromStringAndSize(self->data, _PyDateTime_DATETIME_DATASIZE); } --- 3357,3361 ---- datetime_getstate(PyDateTime_DateTime *self) { ! return PyString_FromStringAndSize((char *)self->data, _PyDateTime_DATETIME_DATASIZE); } *************** *** 3827,3831 **** time_getstate(PyDateTime_Time *self) { ! return PyString_FromStringAndSize(self->data, _PyDateTime_TIME_DATASIZE); } --- 3827,3831 ---- time_getstate(PyDateTime_Time *self) { ! return PyString_FromStringAndSize((char *)self->data, _PyDateTime_TIME_DATASIZE); } From jackjansen@users.sourceforge.net Wed Jan 8 16:28:11 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:11 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo building.html,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Demo Modified Files: building.html Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: building.html =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/building.html,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** building.html 30 Jan 2002 10:42:59 -0000 1.33 --- building.html 8 Jan 2003 16:27:38 -0000 1.34 *************** *** 1,11 **** ! Building Mac Python from source !

    Building Mac Python from source


    ! This document explains how to build MacPython from source. This is necessary if you want to make modifications to the Python core. Building Python is not something to be undertaken lightly, you need a reasonable --- 1,11 ---- ! Building MacPython-OS9 from source !

    Building MacPython-OS9 from source


    ! This document explains how to build MacPython-OS9 from source. This is necessary if you want to make modifications to the Python core. Building Python is not something to be undertaken lightly, you need a reasonable *************** *** 24,31 **** released after MacPython. The MacPython homepage will ! hopefully have updated instructions in that case. These instructions are for CW7. ! I am very interested in feedback on this document, send your comments to the Mac Python Special --- 24,32 ---- released after MacPython. The MacPython homepage will ! hopefully have updated instructions in that case. These instructions are for CW7, ! it is rumoured you may encounter some problems with newer versions of CodeWarrior. ! I am interested in feedback on this document, send your comments to the Mac Python Special *************** *** 78,86 **** - - Build first the Tcl library, then - SimpleTcl (test it by typing ls -l in the window you get) - then the Tk library, then SimpleTk (which can again be tested with - ls -l). If this all worked you are all set to try - building Python. -

    The organization of the Python source tree

    --- 148,151 ---- *************** *** 213,217 ****
    Lib:lib-dynload !
    This is where the Classic and Carbon dynamically-loaded plugin modules live.
    Objects --- 179,187 ----
    Lib:lib-dynload !
    This is where the dynamically-loaded plugin modules live. ! !
    Lib:plat-mac !
    This is where most of the Mac-specific modules live. The modules here ! are available both in MacPython-OS9 and MacPython-OSX.
    Objects *************** *** 236,240 ****
  • ! All the mac-specific stuff lives in the Mac folder:
    Build --- 206,210 ----
    ! The mac-specific stuff lives in the Mac folder:
    Build *************** *** 242,246 **** libraries, shared libraries, executables and plugin modules. All the resulting binaries, except for intermedeate results, are deposited in ! the toplevel folder or the Mac:PlugIns folder (for plugin modules).
    Compat --- 212,216 ---- libraries, shared libraries, executables and plugin modules. All the resulting binaries, except for intermedeate results, are deposited in ! the toplevel folder or the :Lib:lib-dynload folder (for plugin modules).
    Compat *************** *** 256,262 ****
    Lib !
    Mac-specific standard modules. The Carbon package ! contains modules specifically needed with various MacOS toolbox ! interface modules, both for Carbon and classic PPC, despite the name.
    Modules --- 226,231 ----
    Lib !
    MacPython-OS9 specific standard modules which are not shared with ! MacPython-OSX.
    Modules *************** *** 286,295 ****
    OSX !
    Specific to unix-Python (also known as MachoPython) on OSX, not used ! by MacPython.
    OSXResources !
    Specific to unix-Python (also known as MachoPython) on OSX, not used ! by MacPython.
    Python --- 255,262 ----
    OSX !
    Specific to MacPython-OSX, not used by MacPython-OS9.
    OSXResources !
    Specific to MacPython-OSX, not used by MacPython-OS9.
    Python *************** *** 317,335 ****

    Building the PPC interpreter

    - This is different since 2.1. You are best off using the fullbuild.py - script, see
    below.

    ! First you optionally build the external libraries with buildlibs.prj. Next, ! the projects for ! interpreter and core library are linked together, so ! building the PythonInterpreterClassic and/or PythonInterpreterCarbon target ! in PythonInterpreter.prj ! will result in everything being built. The result, however, is an "Application ! template", (filetype Atmp). If you don't use fullbuild you can manually ! turn either of these into an interpreter by copying it to PythonInterpreter ! and setting the filetype to APPL (with ResEdit or some such).

    ! Fullbuild does this for you, and the Atmp files is also how ConfigurePythonCarbon ! and ConfigurePythonClassic work their magic.

    You will get about 100 warnings on "missing prototype" for the various module init --- 284,305 ----

    Building the PPC interpreter

    ! First you optionally build the external libraries with buildlibs.prj.

    ! Then, the fullbuild script can be used to build ! everything, but you need a fully-functional interpreter before you can ! use it (and one that isn't rebuilt in the process: you cannot rebuild ! a running program). You could copy the interpreter to a different ! place and use that to run fullbuild. The PythonStandSmall.prj ! project builds an interpreter that is suited to this, and it can also come ! in handy if you need to debug things (which is easier in a static program).

    ! ! In case you want to build by hand, or in case the fullbuild ! script does not work, here is a breakdown of the various projects.

    ! ! The projects for interpreter and core library are linked together, so ! building the PythonInterpreter target ! in PythonInterpreter.prj ! will result in the whole core being built, but not the extension modules.

    You will get about 100 warnings on "missing prototype" for the various module init *************** *** 337,341 **** override functions from MSL, ignore these too.

    ! For completeness sake here is a breakdown of the projects:

    --- 307,311 ---- override functions from MSL, ignore these too.

    ! Here is a breakdown of the projects:

    *************** *** 343,347 ****
    PythonCore
    The shared library that contains the bulk of the interpreter and ! its resources. It has targets for PythonCore and PythonCoreCarbon. It is a good idea to immedeately put an alias to this shared library in the Extensions folder of your system --- 313,317 ----
    PythonCore
    The shared library that contains the bulk of the interpreter and ! its resources. It is a good idea to immedeately put an alias to this shared library in the Extensions folder of your system *************** *** 353,361 ****
    PythonInterpeter
    The interpreter. This is basically a routine to call out to the ! shared library. Unlike in previous releases the same program is used for ! creating applets (for which formerly PythonApplet was used). There are 4 targets ! in here: two for the classic and carbon templates (which are normally used, and ! converted to PythonInterpreter by the ConfigurePython* applets) and two ! for PythonInterpreter in it's classic and carbon version.

    Plugin projects --- 323,327 ----
    PythonInterpeter
    The interpreter. This is basically a routine to call out to the ! shared library.

    Plugin projects *************** *** 379,394 **** BuildApplet.

    -

    - - The fullbuild script can be used to build - everything, but you need a fully-functional interpreter before you can - use it (and one that isn't rebuilt in the process: you cannot rebuild - a running program). You could copy the interpreter to a different - place and use that to run fullbuild. The PythonStandSmall.prj - project builds an interpreter that is suited to this, and it can also come - in handy if you need to debug things (which is easier in a static program).

    - -

    - You are all set now, and should read the release notes and ReadMe file from the Mac folder. --- 345,348 ---- *************** *** 412,425 **** conversion".

    !

    ! There is one group of people for whom MacCVS is not the best choice: people with ! checkin rights to the Python repository. You will have to use MacCVS Pro ! (completely unrelated) from www.maccvs.org, because it has working SSH support. !
    ! ! It is a good idea to disable Quicktime Exchange in the Quicktime ! control panel. Quicktime Exchange will magically map some extensions to ! filetypes, and this can seriously hinder you if, for instance, .bmp ! is not a Windows bitmap file.

    The Python sources are checked out from the main --- 366,373 ---- conversion".

    ! It is a good idea to disable Quicktime Exchange in the Quicktime control ! panel if you are on OS9 or before. Quicktime Exchange will magically map ! some extensions to filetypes, and this can seriously hinder you if, for ! instance, .bmp is not a Windows bitmap file.

    The Python sources are checked out from the main *************** *** 436,440 **** it is probably a good idea to first build PythonStandSmall.prj, which builds a fairly minimal interpreter, and then follow the ! fullbuild instructions.

    Odds and ends

    --- 384,388 ---- it is probably a good idea to first build PythonStandSmall.prj, which builds a fairly minimal interpreter, and then follow the ! fullbuild instructions.

    Odds and ends

    *************** *** 447,451 **** library to embed Python in another program, if your program can live with using GUSI for I/O. Use PythonCore in stead of your MSL C library ! (or, at the very least, link it before the normal C library).
  • It is possible to build PPC extension --- 395,400 ---- library to embed Python in another program, if your program can live with using GUSI for I/O. Use PythonCore in stead of your MSL C library ! (or, at the very least, link it before the normal C library). Ask for help ! on PythonMac-SIG if you have problems with this.
  • It is possible to build PPC extension From jackjansen@users.sourceforge.net Wed Jan 8 16:28:10 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:10 -0800 Subject: [Python-checkins] python/dist/src/Mac/Build PythonCore.mcp,1.41,1.42 PythonInterpreter.mcp,1.21,1.22 PythonStandSmall.mcp,1.47,1.48 _CG.carbon.mcp,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Build Modified Files: PythonCore.mcp PythonInterpreter.mcp PythonStandSmall.mcp _CG.carbon.mcp Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: PythonCore.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.mcp,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 Binary files /tmp/cvsqXRsVp and /tmp/cvsaC3a5G differ Index: PythonInterpreter.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonInterpreter.mcp,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 Binary files /tmp/cvsLvTbRx and /tmp/cvsKTzctX differ Index: PythonStandSmall.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonStandSmall.mcp,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 Binary files /tmp/cvsUfQR0A and /tmp/cvsumP3e2 differ Index: _CG.carbon.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/_CG.carbon.mcp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 Binary files /tmp/cvsfI7nPD and /tmp/cvsu98Oe7 differ From jackjansen@users.sourceforge.net Wed Jan 8 16:29:21 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:29:21 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.607,1.608 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv28433/Misc Modified Files: NEWS Log Message: Made "ascii" the default encoding for MacPython, as suggested by MvL, and ripped out my previous changes to test_unicode. Doing this for 2.3a1 should give people enough time to complain, if they want to, and then we can see whether we want to do anything about it. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.607 retrieving revision 1.608 diff -C2 -d -r1.607 -r1.608 *** NEWS 8 Jan 2003 15:14:55 -0000 1.607 --- NEWS 8 Jan 2003 16:29:17 -0000 1.608 *************** *** 1203,1206 **** --- 1203,1211 ---- - MacPython no longer maps both \r and \n to \n on input for any text file. This feature has been replaced by universal newline support (PEP278). + + - The default encoding for Python sourcefiles in MacPython-OS9 is no longer + mac-roman (or whatever your local Mac encoding was but "ascii", like on + other platforms. If you really need sourcefiles with Mac characters in them + you can change this in site.py. What's New in Python 2.2 final? From jackjansen@users.sourceforge.net Wed Jan 8 16:30:39 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:30:39 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_tempfile.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv28712/Lib/test Modified Files: test_tempfile.py Log Message: Added the Mac to platforms that don't have user/group/other modes. Set the limit for the number of open files to 32 if platform==mac. Index: test_tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_tempfile.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_tempfile.py 22 Nov 2002 20:13:43 -0000 1.12 --- test_tempfile.py 8 Jan 2003 16:30:34 -0000 1.13 *************** *** 26,30 **** # TEST_FILES may need to be tweaked for systems depending on the maximum # number of files that can be opened at one time (see ulimit -n) ! TEST_FILES = 100 # This is organized as one test for each chunk of code in tempfile.py, --- 26,33 ---- # TEST_FILES may need to be tweaked for systems depending on the maximum # number of files that can be opened at one time (see ulimit -n) ! if sys.platform == 'mac': ! TEST_FILES = 32 ! else: ! TEST_FILES = 100 # This is organized as one test for each chunk of code in tempfile.py, *************** *** 259,263 **** mode = stat.S_IMODE(os.stat(file.name).st_mode) expected = 0600 ! if sys.platform in ('win32', 'os2emx'): # There's no distinction among 'user', 'group' and 'world'; # replicate the 'user' bits. --- 262,266 ---- mode = stat.S_IMODE(os.stat(file.name).st_mode) expected = 0600 ! if sys.platform in ('win32', 'os2emx', 'mac'): # There's no distinction among 'user', 'group' and 'world'; # replicate the 'user' bits. *************** *** 464,468 **** mode = stat.S_IMODE(os.stat(dir).st_mode) expected = 0700 ! if sys.platform in ('win32', 'os2emx'): # There's no distinction among 'user', 'group' and 'world'; # replicate the 'user' bits. --- 467,471 ---- mode = stat.S_IMODE(os.stat(dir).st_mode) expected = 0700 ! if sys.platform in ('win32', 'os2emx', 'mac'): # There's no distinction among 'user', 'group' and 'world'; # replicate the 'user' bits. From jackjansen@users.sourceforge.net Wed Jan 8 16:30:57 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:30:57 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_frozen.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv28768/Lib/test Modified Files: test_frozen.py Log Message: n the Mac the frozen import that should fail actually succeeds, and we know it, so skip the test in stead of confusing the end user. Index: test_frozen.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_frozen.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_frozen.py 1 Nov 2002 11:33:00 -0000 1.3 --- test_frozen.py 8 Jan 2003 16:30:54 -0000 1.4 *************** *** 19,26 **** raise TestFailed, "import __phello__.spam failed:" + str(x) ! try: ! import __phello__.foo ! except ImportError: ! pass ! else: ! raise TestFailed, "import __phello__.foo should have failed" --- 19,27 ---- raise TestFailed, "import __phello__.spam failed:" + str(x) ! if sys.platform != "mac": # On the Mac this import does succeed. ! try: ! import __phello__.foo ! except ImportError: ! pass ! else: ! raise TestFailed, "import __phello__.foo should have failed" From jackjansen@users.sourceforge.net Wed Jan 8 16:31:14 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:31:14 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.115,1.116 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv28828/Lib/test Modified Files: regrtest.py Log Message: Updated the list of expected skips for MacPython-OS9. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.115 retrieving revision 1.116 diff -C2 -d -r1.115 -r1.116 *** regrtest.py 31 Dec 2002 11:26:50 -0000 1.115 --- regrtest.py 8 Jan 2003 16:31:11 -0000 1.116 *************** *** 596,600 **** --- 596,603 ---- """ test_al + test_atexit test_bsddb + test_bsddb3 + test_bz2 test_cd test_cl *************** *** 604,607 **** --- 607,611 ---- test_dbm test_dl + test_email_codecs test_fcntl test_fork1 *************** *** 613,623 **** --- 617,631 ---- test_locale test_mmap + test_mpz test_nis test_ntpath test_openpty + test_ossaudiodev test_poll + test_popen test_popen2 test_pty test_pwd + test_resource test_signal test_socketserver From jackjansen@users.sourceforge.net Wed Jan 8 16:28:15 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:15 -0800 Subject: [Python-checkins] python/dist/src/Mac/Python macmain.c,1.81,1.82 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Python Modified Files: macmain.c Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: macmain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macmain.c,v retrieving revision 1.81 retrieving revision 1.82 diff -C2 -d -r1.81 -r1.82 *** macmain.c 13 Dec 2002 13:57:35 -0000 1.81 --- macmain.c 8 Jan 2003 16:27:41 -0000 1.82 *************** *** 490,494 **** --- 490,497 ---- Py_Initialize(); + #if 0 + /* According to Martin v. Loewis this is a bad idea... */ PyUnicode_SetDefaultEncoding(PyMac_getscript()); + #endif PySys_SetArgv(argc, argv); From jackjansen@users.sourceforge.net Wed Jan 8 16:28:11 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:11 -0800 Subject: [Python-checkins] python/dist/src/Mac/Distributions binary.include,1.22,1.23 dev.exclude,1.10,1.11 dev.include,1.27,1.28 readme.txt,1.8,1.9 src.exclude,1.7,1.8 src.include,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Distributions Modified Files: binary.include dev.exclude dev.include readme.txt src.exclude src.include Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: binary.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/binary.include,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** binary.include 6 Sep 2002 23:33:50 -0000 1.22 --- binary.include 8 Jan 2003 16:27:38 -0000 1.23 *************** *** 3,6 **** --- 3,7 ---- (':BuildApplet', None) (':BuildApplication', None) + (':ConfigurePython', '') (':Demo', '') (':Demo:cwilib', None) *************** *** 112,116 **** (':Mac:Contrib:PythonDetector:PythonDetector', '') (':Mac:Contrib:PythonDetector:readme.txt', '') - (':Mac:Contrib:PythonScript', '') (':Mac:Contrib:Sherlock', '') (':Mac:Contrib:Tabcleaner', '') --- 113,116 ---- *************** *** 139,143 **** (':Mac:ReadMe~0', None) (':Mac:ReadmeSource', None) - (':Mac:Relnotes', ':Relnotes:') (':Mac:Resources', None) (':Mac:TODO', None) --- 139,142 ---- *************** *** 169,172 **** --- 168,172 ---- (':PythonCarbonStandalone', None) (':PythonCoreCarbon', '') + (':PythonInterpreter', '') (':PythonStandCarbon', None) (':PythonStandSmall', None) *************** *** 206,209 **** (':setup.py', None) (':site-packages', None) - (':ConfigurePython', '') - (':PythonInterpreter', '') --- 206,207 ---- Index: dev.exclude =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/dev.exclude,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** dev.exclude 6 Sep 2002 23:33:54 -0000 1.10 --- dev.exclude 8 Jan 2003 16:27:38 -0000 1.11 *************** *** 6,9 **** --- 6,10 ---- *.hqx *.idb + *.pch *.pyc *.pyo *************** *** 12,15 **** --- 13,17 ---- *.xSYM *Icon + *_pch *~[0-9] .#* *************** *** 19,22 **** CVS [(]*[)] - *.pch - *_pch --- 21,22 ---- Index: dev.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/dev.include,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** dev.include 6 Sep 2002 23:34:00 -0000 1.27 --- dev.include 8 Jan 2003 16:27:38 -0000 1.28 *************** *** 7,11 **** (':Demo', None) (':Demo:embed', ':Demo:embed') - (':Demo:extend', ':Demo:extend') (':Demo:pysvr', ':Demo:pysvr') (':Doc', None) --- 7,10 ---- *************** *** 71,84 **** (':Mac:Build:PythonInterpreter.old.mcp', None) (':Mac:Build:PythonStandSmall.mcp', None) - (':Mac:Build:PythonStandSmall.mcp~0', None) - (':Mac:Build:PythonStandSmall.mcp~1', None) (':Mac:Build:PythonStandSmall.old.mcp', None) (':Mac:Build:PythonStandalone.mcp', None) - (':Mac:Build:PythonStandalone.mcp~0', None) - (':Mac:Build:PythonStandalone.mcp~1', None) (':Mac:Build:Qt.carbon.mcp.exp', None) - (':Mac:Build:Qt.carbon.mcp.xml~0', None) (':Mac:Build:Qt.mcp.exp', None) - (':Mac:Build:Qt.mcp.xml~0', None) (':Mac:Build:Snd.carbon.mcp.exp', None) (':Mac:Build:Snd.carbon.mcp.xml', None) --- 70,77 ---- *************** *** 99,102 **** --- 92,98 ---- (':Mac:Build:_AE.mcp.exp', None) (':Mac:Build:_AE.mcp.xml', None) + (':Mac:Build:_AH.carbon.mcp', None) + (':Mac:Build:_AH.carbon.mcp.exp', None) + (':Mac:Build:_AH.carbon.mcp.xml', None) (':Mac:Build:_App.carbon.mcp', None) (':Mac:Build:_App.carbon.mcp.exp', None) *************** *** 150,156 **** --- 146,158 ---- (':Mac:Build:_Fm.mcp.exp', None) (':Mac:Build:_Fm.mcp.xml', None) + (':Mac:Build:_Help.carbon.mcp', None) + (':Mac:Build:_Help.carbon.mcp.exp', None) + (':Mac:Build:_Help.carbon.mcp.xml', None) (':Mac:Build:_Help.mcp', None) (':Mac:Build:_Help.mcp.exp', None) (':Mac:Build:_Help.mcp.xml', None) + (':Mac:Build:_IBCarbon.carbon.mcp', None) + (':Mac:Build:_IBCarbon.carbon.mcp.exp', None) + (':Mac:Build:_IBCarbon.carbon.mcp.xml', None) (':Mac:Build:_Icn.carbon.mcp', None) (':Mac:Build:_Icn.carbon.mcp.exp', None) *************** *** 292,295 **** --- 294,300 ---- (':Mac:Build:pyexpat.mcp.exp', None) (':Mac:Build:pyexpat.mcp.xml', None) + (':Mac:Build:pygusiconfig.carbon.lib', None) + (':Mac:Build:pygusiconfig.smcarbon.lib', None) + (':Mac:Build:temp_delete_me', None) (':Mac:Build:waste.carbon.mcp', None) (':Mac:Build:waste.carbon.mcp.exp', None) *************** *** 301,313 **** (':Mac:Build:xx.carbon.mcp.exp', '') (':Mac:Build:xx.carbon.mcp.xml', '') - (':Mac:Build:xx.mcp', '') - (':Mac:Build:xx.mcp.exp', '') - (':Mac:Build:xx.mcp.xml', None) (':Mac:Build:xxsubtype.carbon.mcp', None) (':Mac:Build:xxsubtype.carbon.mcp.exp', None) (':Mac:Build:xxsubtype.carbon.mcp.xml', None) - (':Mac:Build:xxsubtype.mcp', None) - (':Mac:Build:xxsubtype.mcp.exp', None) - (':Mac:Build:xxsubtype.mcp.xml', None) (':Mac:Build:zlib.carbon.mcp', None) (':Mac:Build:zlib.carbon.mcp.exp', None) --- 306,312 ---- *************** *** 373,376 **** --- 372,376 ---- (':Mac:MPW', None) (':Mac:Modules', None) + (':Mac:OSX', None) (':Mac:OSX:Makefile', None) (':Mac:OSX:README', None) *************** *** 395,398 **** --- 395,399 ---- (':Mac:Resources:pythonpath.r', '') (':Mac:Resources:tkpython.rsrc', None) + (':Mac:Resources:tkpython.rsrc-', None) (':Mac:Resources:version.r', None) (':Mac:TODO', None) *************** *** 416,419 **** --- 417,421 ---- (':Mac:mwerks:mwerks_nscarbon_config.h', '') (':Mac:mwerks:mwerks_shcarbon_config.h', '') + (':Mac:mwerks:mwerks_smcarbon_config.h', '') (':Mac:mwerks:mwerks_thrcarbonsm_config.h', None) (':Mac:mwerks:mwerks_threadsmall_config.h', '') *************** *** 441,444 **** --- 443,447 ---- (':Modules:_localemodule.c', None) (':Modules:_sre.c', None) + (':Modules:_ssl.c', None) (':Modules:_testcapimodule.c', None) (':Modules:_tkinter.c', None) *************** *** 467,470 **** --- 470,474 ---- (':Modules:dlmodule.c', None) (':Modules:errnomodule.c', None) + (':Modules:expat', None) (':Modules:fcntlmodule.c', None) (':Modules:flmodule.c', None) *************** *** 519,522 **** --- 523,527 ---- (':Modules:signalmodule.c', None) (':Modules:socketmodule.c', None) + (':Modules:socketmodule.h', None) (':Modules:soundex.c', None) (':Modules:sre.h', None) *************** *** 583,586 **** --- 588,592 ---- (':Tools:compiler', None) (':Tools:faqwiz', None) + (':Tools:framer', None) (':Tools:freeze', '') (':Tools:i18n', None) *************** *** 606,628 **** (':setup.py', None) (':site-packages', None) ! (':Mac:Build:_IBCarbon.carbon.mcp.xml', None) ! (':Mac:Build:_IBCarbon.carbon.mcp.exp', None) ! (':Mac:Build:_IBCarbon.carbon.mcp', None) ! (':Mac:Build:_Help.carbon.mcp.xml', None) ! (':Mac:Build:_Help.carbon.mcp.exp', None) ! (':Mac:Build:_Help.carbon.mcp', None) ! (':Mac:Build:_AH.carbon.mcp.xml', None) ! (':Mac:Build:_AH.carbon.mcp.exp', None) ! (':Mac:Build:_AH.carbon.mcp', None) ! (':Mac:Build:temp_delete_me', None) ! (':Mac:Build:pygusiconfig.smcarbon.lib', None) ! (':Mac:Build:pygusiconfig.carbon.lib', None) ! (':Mac:mwerks:mwerks_carbonpyexpat_config.h', '') ! (':Mac:mwerks:mwerks_pyexpat_config.h', '') ! (':Mac:mwerks:mwerks_smcarbon_config.h', '') ! (':Mac:OSX', None) ! (':Modules:_ssl.c', None) ! (':Modules:socketmodule.h', None) ! (':Mac:Resources:tkpython.rsrc-', None) ! (':Modules:expat', None) ! (':Tools:framer', None) --- 612,631 ---- (':setup.py', None) (':site-packages', None) ! (':Mac:Build:_Folder.carbon.mcp.xml', None) ! (':Mac:Build:_Folder.carbon.mcp.exp', None) ! (':Mac:Build:_Folder.carbon.mcp', None) ! (':Mac:Build:_File.carbon.mcp.xml', None) ! (':Mac:Build:_File.carbon.mcp.exp', None) ! (':Mac:Build:_File.carbon.mcp', None) ! (':Mac:Build:_Alias.carbon.mcp.xml', None) ! (':Mac:Build:_Alias.carbon.mcp.exp', None) ! (':Mac:Build:_Alias.carbon.mcp', None) ! (':Modules:zipimport.c', None) ! (':Modules:ossaudiodev.c', None) ! (':Modules:datetimemodule.c', None) ! (':Modules:bz2module.c', None) ! (':Modules:_randommodule.c', None) ! (':Modules:_bsddb.c', None) ! (':Mac:Build:datetime.carbon.mcp.xml', None) ! (':Mac:Build:datetime.carbon.mcp.exp', None) ! (':Mac:Build:datetime.carbon.mcp', None) Index: readme.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/readme.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** readme.txt 22 May 2002 14:30:37 -0000 1.8 --- readme.txt 8 Jan 2003 16:27:38 -0000 1.9 *************** *** 3,7 **** These notes are mainly for myself, or for whoever tries to make a MacPython ! distribution when I'm fed up with it. They were last updated for 2.2b1. - Increase fragment version number in PythonCore and PythonCoreCarbon. --- 3,7 ---- These notes are mainly for myself, or for whoever tries to make a MacPython ! distribution when I'm fed up with it. They were last updated for 2.3a1. - Increase fragment version number in PythonCore and PythonCoreCarbon. *************** *** 10,18 **** - Increase version number in _versioncheck.py - Build PythonStandSmall, run once in root folder ! - Update Relnotes, readme's, Demo:build.html ! - Make sure tkresources.rsrc is up-to-date - fullbuild everything with increase-buildno ! - Test both classic and Carbon with test.regrtest ! - Update Numeric and build/install it both with Classic and with Carbon python - Recompile OSAm and possibly other Contrib stuff - mkdistr binary.include --- 10,17 ---- - Increase version number in _versioncheck.py - Build PythonStandSmall, run once in root folder ! - Update NEWS, readme's, Demo:build.html - fullbuild everything with increase-buildno ! - Test with test.regrtest ! - Update Numeric and build/install it - Recompile OSAm and possibly other Contrib stuff - mkdistr binary.include *************** *** 34,39 **** add the missing stuff. Make sure of all settings for the new files (esp. "where" and "gestalt" are easy to miss). ! - test on virgin systems (OSX, OS9, OS8 without Carbon). Make sure to test ! tkinter too. - Remove the local installation so you don't get confused by it. - checkin everything except PythonX.Y.vct. --- 33,37 ---- add the missing stuff. Make sure of all settings for the new files (esp. "where" and "gestalt" are easy to miss). ! - test on virgin systems (both OS9 and OSX). - Remove the local installation so you don't get confused by it. - checkin everything except PythonX.Y.vct. Index: src.exclude =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/src.exclude,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** src.exclude 30 Oct 2001 22:41:39 -0000 1.7 --- src.exclude 8 Jan 2003 16:27:38 -0000 1.8 *************** *** 9,12 **** --- 9,13 ---- *.lib *.pyc + *.pyo *.slb *.xMAP *************** *** 20,22 **** PyIDE-src [(]*[)] - *.pyo --- 21,22 ---- Index: src.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/src.include,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** src.include 30 Oct 2001 22:41:43 -0000 1.7 --- src.include 8 Jan 2003 16:27:38 -0000 1.8 *************** *** 1,2 **** --- 1,3 ---- + (':.DS_Store', None) (':BeOS', None) (':BuildApplet', None) *************** *** 12,21 **** (':Extensions:Pmw', None) (':Extensions:PyDOM', None) - (':Extensions:README', '') - (':Extensions:README.TOO', '') (':Extensions:audio', None) - (':Extensions:example', '') - (':Extensions:example2', '') - (':Extensions:example3', '') (':Extensions:img', '') (':Extensions:midi', None) --- 13,17 ---- *************** *** 30,33 **** --- 26,30 ---- (':LICENSE', '') (':Lib', '') + (':Mac:.DS_Store', None) (':Mac:Build', '') (':Mac:Build:PythonAppletCFM68K', None) *************** *** 42,45 **** --- 39,43 ---- (':Mac:Contrib', '') (':Mac:Demo', '') + (':Mac:Distributions:(vise)', None) (':Mac:Distributions:68k-shared.exclude', None) (':Mac:Distributions:68k-shared.include', None) *************** *** 68,72 **** (':Mac:ReadMe-dev', None) (':Mac:ReadMe-src', ':ReadMe-src') - (':Mac:Relnotes', ':Relnotes:') (':Mac:Resources', '') (':Mac:TODO', None) --- 66,69 ---- *************** *** 78,82 **** (':Mac:Tools:bruce', None) (':Mac:Tools:macfreeze', '') - (':Mac:Unsupported', '') (':Mac:Wastemods', '') (':Mac:_checkversion.py', None) --- 75,78 ---- *************** *** 85,89 **** (':Mac:mwerks:projects', None) (':Mac:scripts', '') - (':Mac:tclmods', '') (':Misc', '') (':Modules', '') --- 81,84 ---- *************** *** 91,95 **** (':PC', None) (':PCbuild', None) - (':PLAN.txt', '') (':Parser', '') (':PlugIns', None) --- 86,89 ---- *************** *** 142,144 **** (':setup.py', None) (':site-packages', None) ! (':Mac:Distributions:(vise)', None) --- 136,138 ---- (':setup.py', None) (':site-packages', None) ! (':Tools:framer', '') From jackjansen@users.sourceforge.net Wed Jan 8 16:28:10 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:10 -0800 Subject: [Python-checkins] python/dist/src/Mac/Contrib/osam OSAm.c,1.1.1.1,1.2 OSAm.prj,1.3,1.4 ScriptRunner.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Contrib/osam In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Contrib/osam Modified Files: OSAm.c OSAm.prj ScriptRunner.c Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: OSAm.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Contrib/osam/OSAm.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** OSAm.c 18 Aug 1998 14:56:35 -0000 1.1.1.1 --- OSAm.c 8 Jan 2003 16:27:38 -0000 1.2 *************** *** 50,64 **** DescType typeCode; long dataSize = 0; ! HLock (temp.dataHandle); ! ! dataSize = GetHandleSize (temp.dataHandle); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), dataSize); ! ! AEDisposeDesc (&temp); if (!result) --- 50,62 ---- DescType typeCode; long dataSize = 0; + OSErr err; ! dataSize = AEGetDescDataSize (&temp); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize (NULL, dataSize); ! if (!result) *************** *** 66,72 **** --- 64,77 ---- printf ("OSAm.error Out of memory.\n"); Py_INCREF (Py_None); + AEDisposeDesc (&temp); return Py_None; } + if ( (err=AEGetDescData(&temp, PyString_AS_STRING(result), dataSize)) < 0 ) + { + AEDisposeDesc(&temp); + return PyMac_Error(err); + } + AEDisposeDesc(&temp); return result; } *************** *** 111,125 **** DescType typeCode; long dataSize = 0; ! HLock (temp.dataHandle); ! ! dataSize = GetHandleSize (temp.dataHandle); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), dataSize); ! ! AEDisposeDesc (&temp); if (!result) --- 116,128 ---- DescType typeCode; long dataSize = 0; + OSErr err; ! dataSize = AEGetDescDataSize (&temp); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize (NULL, dataSize); ! if (!result) *************** *** 127,136 **** printf ("OSAm.error Out of memory.\n"); Py_INCREF (Py_None); return Py_None; } return result; } - } --- 130,145 ---- printf ("OSAm.error Out of memory.\n"); Py_INCREF (Py_None); + AEDisposeDesc (&temp); return Py_None; } + if ( (err=AEGetDescData(&temp, PyString_AS_STRING(result), dataSize)) < 0 ) + { + AEDisposeDesc(&temp); + return PyMac_Error(err); + } + AEDisposeDesc(&temp); return result; } } *************** *** 171,185 **** DescType typeCode; long dataSize = 0; ! HLock (temp.dataHandle); ! ! dataSize = GetHandleSize (temp.dataHandle); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), dataSize); ! ! AEDisposeDesc (&temp); if (!result) --- 180,192 ---- DescType typeCode; long dataSize = 0; + OSErr err; ! dataSize = AEGetDescDataSize (&temp); if (dataSize > 0) { ! PyObject *result = PyString_FromStringAndSize (NULL, dataSize); ! if (!result) *************** *** 187,193 **** --- 194,207 ---- printf ("OSAm.error Out of memory.\n"); Py_INCREF (Py_None); + AEDisposeDesc (&temp); return Py_None; } + if ( (err=AEGetDescData(&temp, PyString_AS_STRING(result), dataSize)) < 0 ) + { + AEDisposeDesc(&temp); + return PyMac_Error(err); + } + AEDisposeDesc(&temp); return result; } *************** *** 217,221 **** METH_VARARGS, OSAm_DoCommand__doc__}, ! {"CompileAndSave", (PyCFunction) OSAm_CompileAndSave, --- 231,235 ---- METH_VARARGS, OSAm_DoCommand__doc__}, ! #if 0 {"CompileAndSave", (PyCFunction) OSAm_CompileAndSave, *************** *** 227,230 **** --- 241,245 ---- METH_VARARGS, OSAm_DoCommand__doc__}, + #endif {NULL, (PyCFunction) NULL, 0, NULL} Index: OSAm.prj =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Contrib/osam/OSAm.prj,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 Binary files /tmp/cvsCnQwhG and /tmp/cvsAtwl8d differ Index: ScriptRunner.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Contrib/osam/ScriptRunner.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ScriptRunner.c 3 Aug 2001 13:31:34 -0000 1.2 --- ScriptRunner.c 8 Jan 2003 16:27:38 -0000 1.3 *************** *** 45,49 **** OSAError LoadScriptingComponent (ComponentInstance * scriptingComponent); ! /* * store the script as a compile script so that OSA --- 45,49 ---- OSAError LoadScriptingComponent (ComponentInstance * scriptingComponent); ! #if 0 /* * store the script as a compile script so that OSA *************** *** 144,147 **** --- 144,148 ---- return err2; } + #endif *************** *** 195,199 **** } ! /* * This routine reads in a saved script file and executes --- 196,200 ---- } ! #if 0 /* * This routine reads in a saved script file and executes *************** *** 292,295 **** --- 293,297 ---- return err2; } + #endif From jackjansen@users.sourceforge.net Wed Jan 8 16:32:32 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:32:32 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macfs.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv29154/Lib/plat-mac Modified Files: macfs.py Log Message: Removed the SetDates warning. The warning is in the readme, and the print statement was too obtrusive (it appeared during the installation process, and the user needed to close the resulting window manually). Index: macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macfs.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** macfs.py 30 Dec 2002 22:04:20 -0000 1.1 --- macfs.py 8 Jan 2003 16:32:29 -0000 1.2 *************** *** 58,62 **** def SetDates(self, *dates): ! print "FSSpec.SetDates no longer implemented" class FSRef(Carbon.File.FSRef): --- 58,62 ---- def SetDates(self, *dates): ! pass # print "FSSpec.SetDates not yet implemented" class FSRef(Carbon.File.FSRef): *************** *** 70,74 **** def Update(self, *args): ! print "Alias.Update not yet implemented" def Resolve(self, src=None): --- 70,74 ---- def Update(self, *args): ! pass # print "Alias.Update not yet implemented" def Resolve(self, src=None): From jackjansen@users.sourceforge.net Wed Jan 8 16:32:15 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:32:15 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac FrameWork.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv28944/Lib/plat-mac Modified Files: FrameWork.py Log Message: quashed another case of the 32-bit warning. Index: FrameWork.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/FrameWork.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** FrameWork.py 30 Dec 2002 22:04:20 -0000 1.1 --- FrameWork.py 8 Jan 2003 16:32:09 -0000 1.2 *************** *** 646,650 **** if not reply: return ! id = (reply & 0xffff0000) >> 16 item = reply & 0xffff if not window: --- 646,650 ---- if not reply: return ! id = (reply >> 16) & 0xffff item = reply & 0xffff if not window: From jackjansen@users.sourceforge.net Wed Jan 8 16:33:19 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:33:19 -0800 Subject: [Python-checkins] python/dist/src/Lib fileinput.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv29515/Lib Modified Files: fileinput.py Log Message: Test that chmod() actually exists before calling it (it doesn't on MacOS9). Index: fileinput.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/fileinput.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** fileinput.py 14 Aug 2002 02:58:16 -0000 1.15 --- fileinput.py 8 Jan 2003 16:33:16 -0000 1.16 *************** *** 310,314 **** self._output = os.fdopen(fd, "w") try: ! os.chmod(self._filename, perm) except OSError: pass --- 310,315 ---- self._output = os.fdopen(fd, "w") try: ! if hasattr(os, 'chmod'): ! os.chmod(self._filename, perm) except OSError: pass From jackjansen@users.sourceforge.net Wed Jan 8 16:33:44 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:33:44 -0800 Subject: [Python-checkins] python/dist/src/Lib os.py,1.63,1.64 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv29758/Lib Modified Files: os.py Log Message: Always define getenv(), as suggested by Guido. This means that os.getenv() is also defined for MacPython-OS9 (even though it doesn't actually do anything useful), and it shouldn't hurt on other platforms. Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** os.py 9 Oct 2002 17:23:29 -0000 1.63 --- os.py 8 Jan 2003 16:33:40 -0000 1.64 *************** *** 417,425 **** environ = _Environ(environ) ! def getenv(key, default=None): ! """Get an environment variable, return None if it doesn't exist. ! The optional second argument can specify an alternate default.""" ! return environ.get(key, default) ! __all__.append("getenv") def _exists(name): --- 417,425 ---- environ = _Environ(environ) ! def getenv(key, default=None): ! """Get an environment variable, return None if it doesn't exist. ! The optional second argument can specify an alternate default.""" ! return environ.get(key, default) ! __all__.append("getenv") def _exists(name): From jackjansen@users.sourceforge.net Wed Jan 8 16:37:06 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:37:06 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_zipimport.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv31033/Lib/test Modified Files: test_zipimport.py Log Message: Various tweaks to make the test work on the Mac. Index: test_zipimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zipimport.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_zipimport.py 3 Jan 2003 11:18:56 -0000 1.3 --- test_zipimport.py 8 Jan 2003 16:37:03 -0000 1.4 *************** *** 16,20 **** def make_pyc(co, mtime): data = marshal.dumps(co) ! pyc = imp.get_magic() + struct.pack(" Update of /cvsroot/python/python/dist/src/Mac/Resources In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Resources Modified Files: pythonpath.r Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: pythonpath.r =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Resources/pythonpath.r,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** pythonpath.r 30 Dec 2002 23:07:44 -0000 1.15 --- pythonpath.r 8 Jan 2003 16:27:42 -0000 1.16 *************** *** 90,95 **** "$(PYTHON)", "$(PYTHON):Lib", - "$(PYTHON):Lib:plat-mac", "$(PYTHON):Lib:lib-dynload", "$(PYTHON):Mac:Lib", "$(PYTHON):Extensions:img:Mac", --- 90,96 ---- "$(PYTHON)", "$(PYTHON):Lib", "$(PYTHON):Lib:lib-dynload", + "$(PYTHON):Lib:plat-mac", + "$(PYTHON):Lib:plat-mac:lib-scriptpackages", "$(PYTHON):Mac:Lib", "$(PYTHON):Extensions:img:Mac", From jackjansen@users.sourceforge.net Wed Jan 8 16:28:02 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:02 -0800 Subject: [Python-checkins] python/dist/src/Mac ReadMe,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Mac In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac Modified Files: ReadMe Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: ReadMe =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/ReadMe,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** ReadMe 19 Aug 2002 13:17:39 -0000 1.45 --- ReadMe 8 Jan 2003 16:27:29 -0000 1.46 *************** *** 1,18 **** ! How to install Python 2.2.1 on your Macintosh ! --------------------------------------------- ! This is a MacPython that can run on classic MacOS (from 8.1 ! onwards) and natively on MacOSX. The installer tries to work out whether you can ! use the Carbon version or not. For Mac OS X users: this version of Python ! does not run from the command line, it is a pure "Mac only" app. Use the standard ! unix Python from the commandline, the two Pythons will be merged in the future. ! You should definitely read the Relnotes file too, and the section below about ! toolbox module reorganization. You should also read :Misc:NEWS, which lists ! the general (non-mac-dependent) new features of this Python release. ! A special note about the active installer: do not background it, it may hang ! your machine. This is a general problem with Vise active installers, MindVision ! are working on it. ------ --- 1,24 ---- ! How to install MacPython-OS9 2.3a1 on your Macintosh ! ---------------------------------------------------- ! This is a MacPython that can run on Mac OS 8.6 with CarbonLib ! installed, Mac OS 9 and Mac OS X. It is the direct successor of MacPython 2.2. ! For Mac OS X users: you are probably better off with the normal unix distribution ! of Python. That version also runs from the commandline, and if you do a framework ! build it will contain all the functionality of this version too. A prebuilt ! version will be available starting with the beta distributions. ! If you are upgrading from a previous MacPython you should read :Misc:NEWS, ! which lists the new features of this Python release. As of this release ! the Mac-specific release notes have been moved to the "Mac" section of ! the general NEWS file. ! ! Two changes since 2.2 deserve special mention: ! - Most Mac-specific modules have moved to :Lib:plat-mac. :Mac:Lib now contains ! only modules that are not shared with MacPython-OSX 2.3. ! - macfs is now a pure Python wrapper module around various modules in the ! Carbon package. For 2.3a1 only this wrapping is incomplete: fsspec.SetDates() ! does not work yet. If you encounter any other problems please report them. ------ *************** *** 29,36 **** now. The documentation is in HTML format, start with index.html. ! This installer installs MacPython for classic PPC MacOS, MacPython for Carbon ! (OS X, OS 9 or OS 8 with CarbonLib installed) or both, depending on your ! configuration. By selecting custom install you can bypass these tests and ! install what you want. If you want 68k support you will have get MacPython 1.5.2. --- 35,40 ---- now. The documentation is in HTML format, start with index.html. ! If you want a MacPython that runs on systems without Carbon support (8.1 ! up to 8.6 without CarbonLib) you should get MacPython 2.2.2. If you want 68k support you will have get MacPython 1.5.2. *************** *** 40,66 **** The optional parts in this distribution are ! - TK+PIL: Tkinter and support modules, plus Imaging, the Python image ! manipulation package (allows you to read, write and display images and ! do lots of operations on them). ! For Carbon MacPython you only get PIL: there is no Tcl/Tk for Carbon yet. ! This is the reason Classic MacPython is also installed on MacOSX: it ! allows you to run Tkinter applications, albeit in the Classic box. - img: another imaging package. Has more file format support and is faster than imaging, but has only limited operations on images. There is a bridge between the packages. - Numeric: the LLNL Numeric Python extension. All sorts of nifty operations ! on matrices and such. This is the most recent version from the ! sourceforge archive. ! Numeric has moved from Extensions to :Lib:site-python, by the way, ! see the release notes. - Developers kit: all header files and some tools and sample projects to get you started on writing Python extensions if you have CodeWarrior. All these except the DevKit are installed with Easy Install. ! After the installer finishes it automatically launches the appropriate ! ConfigurePython applet, to finish configuration of your Python. If you ! run MacOS9 or later (or 8 with CarbonLib installed) you can switch ! back and forth between the classic and Carbon versions of Python by ! running either ConfigurePythonClassic or ConfigurePythonCarbon. Moving your Python installation after installing is generally not a --- 44,61 ---- The optional parts in this distribution are ! - PIL: the Python image manipulation package (allows you to read, write ! and display images and do lots of operations on them). Tkinter is no ! longer supported, a working Carbon version is Tk is not available. - img: another imaging package. Has more file format support and is faster than imaging, but has only limited operations on images. There is a bridge between the packages. - Numeric: the LLNL Numeric Python extension. All sorts of nifty operations ! on matrices and such. This is version 22. - Developers kit: all header files and some tools and sample projects to get you started on writing Python extensions if you have CodeWarrior. All these except the DevKit are installed with Easy Install. ! After the installer finishes it automatically launches the ! ConfigurePython applet, to finish configuration of your Python. Moving your Python installation after installing is generally not a *************** *** 81,86 **** Python and "import test.regrtest ; test.regrtest.main()". ! test_frozen will fail in MacPython because of different handling on ! frozen modules. This should not be a problem in normal use. Three tests will fail on MacOS9 with MemoryErrors: --- 76,83 ---- Python and "import test.regrtest ; test.regrtest.main()". ! test_httplib fails with an unexpected output error, ! this problem is being investigated. ! ! test_socket fails, this problem is being investigated. Three tests will fail on MacOS9 with MemoryErrors: *************** *** 120,124 **** not having a preference file: the symptom is failing to import all sorts of standard modules. If you remove your per-user Python preference files ! (in ~/Library/Preferences) and then run PythonIntpreter once everything should be fine. --- 117,121 ---- not having a preference file: the symptom is failing to import all sorts of standard modules. If you remove your per-user Python preference files ! (in ~/Library/Preferences) and then run PythonInterpreter once everything should be fine. *************** *** 126,136 **** ------------ ! Up to three items are installed in the system folder: the interpreter shared ! libraries PythonCore and PythonCoreCarbon live in the Extensions ! folder and the "Python 2.2.1 Preferences" file in the Python subfolder in the Preferences folder. All the rest of Python lives in the folder you installed in. ! On OSX the libraries are installed in /Library/CFMSupport. The ConfigurePython applets will complain if you have no right to create the libraries there (you need Admin privileges). This has one consequence: you will not be able to --- 123,133 ---- ------------ ! Up to three items are installed in the MacOS 8 or 9 system folder: the interpreter ! shared library PythonCore lives in the Extensions ! folder and the "Python 2.3a1 Preferences" file in the Python subfolder in the Preferences folder. All the rest of Python lives in the folder you installed in. ! On OSX the library is installed in /Library/CFMSupport. The ConfigurePython applets will complain if you have no right to create the libraries there (you need Admin privileges). This has one consequence: you will not be able to *************** *** 144,153 **** Start off at Mac:Demo:index.html. Read at least the first few sections. ! There are also some interesting files in the "Relnotes" folder that may ! contain useful information. There is also a first stab at documentation ! (plus examples) in the Mac:Demo folder. The toplevel Demo folder has ! machine-independent demos. ! The Mac:Lib:test folder also has some programs that show simple ! capabilities of various modules. The ":Mac:scripts" folder has some sample scripts. Some are useful, --- 141,146 ---- Start off at Mac:Demo:index.html. Read at least the first few sections. ! There is also a first stab at documentation (plus examples) in the ! Mac:Demo folder. The toplevel Demo folder has machine-independent demos. The ":Mac:scripts" folder has some sample scripts. Some are useful, *************** *** 176,184 **** are lost and you have to set them again. ! After you are satisfied that 2.2.1 works as expected you can trash anything in the system folder that has "python" in the name and not ! "2.2.1". ! The ConfigurePython... applets will try to detect incompatible preferences files and offer to remove them. This means that re-running ConfigurePython after a second install of the same MacPython version --- 169,177 ---- are lost and you have to set them again. ! After you are satisfied that 2.3a1 works as expected you can trash anything in the system folder that has "python" in the name and not ! "2.3a1". ! The ConfigurePython applet will try to detect incompatible preferences files and offer to remove them. This means that re-running ConfigurePython after a second install of the same MacPython version From jackjansen@users.sourceforge.net Wed Jan 8 16:28:13 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:28:13 -0800 Subject: [Python-checkins] python/dist/src/Mac/Distributions/(vise) Python 2.3.vct,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions/(vise) In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/Distributions/(vise) Modified Files: Python 2.3.vct Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: Python 2.3.vct =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/(vise)/Python 2.3.vct,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 Binary files /tmp/cvsMVDL5f and /tmp/cvsFDFBai differ From jackjansen@users.sourceforge.net Wed Jan 8 16:27:47 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 08 Jan 2003 08:27:47 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts BuildApplet.rsrc,1.6,1.7 BuildApplication.rsrc,1.6,1.7 ConfigurePython.py,1.41,1.42 ConfigurePython.rsrc,1.15,1.16 EditPythonPrefs.rsrc,1.15,1.16 fullbuild.py,1.88,1.89 genpluginprojects.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv27782/Mac/scripts Modified Files: BuildApplet.rsrc BuildApplication.rsrc ConfigurePython.py ConfigurePython.rsrc EditPythonPrefs.rsrc fullbuild.py genpluginprojects.py Log Message: Merging the various tweaks for MacPython-OS9 2.3a1 back into the trunk. Index: BuildApplet.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplet.rsrc,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 Binary files /tmp/cvsad1rhA and /tmp/cvsc5NOm0 differ Index: BuildApplication.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplication.rsrc,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 Binary files /tmp/cvs3RN1OF and /tmp/cvssakeNd differ Index: ConfigurePython.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/ConfigurePython.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** ConfigurePython.py 7 Dec 2001 16:06:59 -0000 1.41 --- ConfigurePython.py 8 Jan 2003 16:27:43 -0000 1.42 *************** *** 161,167 **** MacOS.splash(SPLASH_COPYCORE) if verbose: ! print "Copying PythonCore..." n = 0 - n = n + mkcorealias('PythonCore', 'PythonCore') n = n + mkcorealias('PythonCoreCarbon', 'PythonCoreCarbon') if n == 0: --- 161,166 ---- MacOS.splash(SPLASH_COPYCORE) if verbose: ! print "Copying PythonCoreCarbon..." n = 0 n = n + mkcorealias('PythonCoreCarbon', 'PythonCoreCarbon') if n == 0: *************** *** 171,200 **** print "Warning: PythonCore not copied to Extensions folder" print " (Applets will not work unless run from the Python folder)" - if sys.argv[0][-7:] == 'Classic': - do_classic = 1 - elif sys.argv[0][-6:] == 'Carbon': - do_classic = 0 - else: - print "I don't know the sys.argv[0] function", sys.argv[0] - if verbose: - print "Configure classic or carbon - ", - rv = string.strip(sys.stdin.readline()) - while rv and rv != "classic" and rv != "carbon": - print "Configure classic or carbon - ", - rv = string.strip(sys.stdin.readline()) - if rv == "classic": - do_classic = 1 - elif rv == "carbon": - do_classic = 0 - else: - return - else: - sys.exit(1) - if do_classic: - MacOS.splash(SPLASH_COPYCLASSIC) - buildcopy(sys.prefix, None, [("PythonInterpreterClassic", "PythonInterpreter")]) - else: - MacOS.splash(SPLASH_COPYCARBON) - buildcopy(sys.prefix, None, [("PythonInterpreterCarbon", "PythonInterpreter")]) MacOS.splash(SPLASH_BUILDAPPLETS) buildapplet(sys.prefix, None, APPLET_LIST) --- 170,173 ---- Index: ConfigurePython.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/ConfigurePython.rsrc,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 Binary files /tmp/cvsrntTMI and /tmp/cvsgSC1kh differ Index: EditPythonPrefs.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/EditPythonPrefs.rsrc,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 Binary files /tmp/cvssI5l8J and /tmp/cvsKYjOZj differ Index: fullbuild.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fullbuild.py,v retrieving revision 1.88 retrieving revision 1.89 diff -C2 -d -r1.88 -r1.89 *** fullbuild.py 24 Dec 2002 13:07:58 -0000 1.88 --- fullbuild.py 8 Jan 2003 16:27:44 -0000 1.89 *************** *** 203,206 **** --- 203,207 ---- (":Mac:Build:pyexpat.carbon.mcp", "pyexpat.carbon"), (":Mac:Build:calldll.carbon.mcp", "calldll.carbon"), + (":Mac:Build:datetime.carbon.mcp", "datetime.carbon"), (":Mac:Build:gdbm.carbon.mcp", "gdbm.carbon"), (":Mac:Build:icglue.carbon.mcp", "icglue.carbon"), Index: genpluginprojects.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/genpluginprojects.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** genpluginprojects.py 24 Dec 2002 13:07:58 -0000 1.38 --- genpluginprojects.py 8 Jan 2003 16:27:44 -0000 1.39 *************** *** 115,164 **** genpluginproject("carbon", "_testcapi") genpluginproject("carbon", "xx") genpluginproject("carbon", "xxsubtype", sources=["xxsubtype.c"]) genpluginproject("carbon", "_hotshot", sources=["_hotshot.c"]) # bgen-generated Toolbox modules ! genpluginproject("carbon", "_AE", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_AH", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_App", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Cm", outputdir="::Lib:Carbon") ! # XXX can't work properly because we need to set a custom fragment initializer ! #genpluginproject("carbon", "_CG", ! # sources=["_CGModule.c", "CFMLateImport.c"], ! # libraries=["CGStubLib"], ! # outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Ctl", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Dlg", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Drag", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Evt", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_File", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Fm", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Folder", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Help", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_IBCarbon", sources=[":ibcarbon:_IBCarbon.c"], ! outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Icn", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_List", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Menu", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Qd", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Qt", ! libraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Qdoffs", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") genpluginproject("carbon", "_Res", ! stdlibraryflags="Debug, WeakImport", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Scrap", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Snd", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Sndihooks", sources=[":snd:_Sndihooks.c"], outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_TE", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Mlte", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_Win", outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_CF", sources=["_CFmodule.c", "pycfbridge.c"], outputdir="::Lib:Carbon") ! genpluginproject("carbon", "_CarbonEvt", outputdir="::Lib:Carbon") genpluginproject("carbon", "hfsplus") --- 115,159 ---- genpluginproject("carbon", "_testcapi") genpluginproject("carbon", "xx") + genpluginproject("carbon", "datetime") genpluginproject("carbon", "xxsubtype", sources=["xxsubtype.c"]) genpluginproject("carbon", "_hotshot", sources=["_hotshot.c"]) # bgen-generated Toolbox modules ! genpluginproject("carbon", "_AE") ! genpluginproject("carbon", "_AH") ! genpluginproject("carbon", "_App") ! genpluginproject("carbon", "_Cm") ! genpluginproject("carbon", "_Ctl") ! genpluginproject("carbon", "_Dlg") ! genpluginproject("carbon", "_Drag") genpluginproject("carbon", "_Evt", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_File", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_Fm", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_Folder", ! stdlibraryflags="Debug, WeakImport") ! genpluginproject("carbon", "_Help") ! genpluginproject("carbon", "_IBCarbon", sources=[":ibcarbon:_IBCarbon.c"]) ! genpluginproject("carbon", "_Icn") ! genpluginproject("carbon", "_List") ! genpluginproject("carbon", "_Menu") genpluginproject("carbon", "_Qd", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_Qt", ! libraryflags="Debug, WeakImport") genpluginproject("carbon", "_Qdoffs", ! stdlibraryflags="Debug, WeakImport") genpluginproject("carbon", "_Res", ! stdlibraryflags="Debug, WeakImport") ! genpluginproject("carbon", "_Scrap") ! genpluginproject("carbon", "_Snd") ! genpluginproject("carbon", "_Sndihooks", sources=[":snd:_Sndihooks.c"]) ! genpluginproject("carbon", "_TE") ! genpluginproject("carbon", "_Mlte") ! genpluginproject("carbon", "_Win") ! genpluginproject("carbon", "_CF", sources=["_CFmodule.c", "pycfbridge.c"]) ! genpluginproject("carbon", "_CarbonEvt") genpluginproject("carbon", "hfsplus") From skip@pobox.com Wed Jan 8 16:59:12 2003 From: skip@pobox.com (Skip Montanaro) Date: Wed, 8 Jan 2003 10:59:12 -0600 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.606,1.607 In-Reply-To: <4r8jio8w.fsf@python.net> References: <15900.17897.885113.970379@montanaro.dyndns.org> <4r8jio8w.fsf@python.net> Message-ID: <15900.22752.116858.790061@montanaro.dyndns.org> >> I guess my next question is, why not make all paths absolute? (IOW, >> why is sys.path[0] special?) Thomas> As Guido has explained, it is special because it is created Thomas> *after* site.py has run. Sorry, my fault for engaging my mouth before my brain was in gear. Skip From theller@python.net Wed Jan 8 17:56:59 2003 From: theller@python.net (Thomas Heller) Date: 08 Jan 2003 18:56:59 +0100 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.606,1.607 In-Reply-To: <15900.22752.116858.790061@montanaro.dyndns.org> References: <15900.17897.885113.970379@montanaro.dyndns.org> <4r8jio8w.fsf@python.net> <15900.22752.116858.790061@montanaro.dyndns.org> Message-ID: Skip Montanaro writes: > >> I guess my next question is, why not make all paths absolute? (IOW, > >> why is sys.path[0] special?) > > Thomas> As Guido has explained, it is special because it is created > Thomas> *after* site.py has run. > > Sorry, my fault for engaging my mouth before my brain was in gear. > You can compensate by extending the patch to another system, linux for example ;-) Thomas From holdenweb@users.sourceforge.net Wed Jan 8 18:53:21 2003 From: holdenweb@users.sourceforge.net (holdenweb@users.sourceforge.net) Date: Wed, 08 Jan 2003 10:53:21 -0800 Subject: [Python-checkins] python/dist/src/Lib CGIHTTPServer.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv10589 Modified Files: CGIHTTPServer.py Log Message: Fix bug 427345 [related to IE's additional input on POST request]. Index: CGIHTTPServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/CGIHTTPServer.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** CGIHTTPServer.py 17 Oct 2002 16:21:35 -0000 1.29 --- CGIHTTPServer.py 8 Jan 2003 18:53:18 -0000 1.30 *************** *** 27,30 **** --- 27,31 ---- import BaseHTTPServer import SimpleHTTPServer + import select *************** *** 200,203 **** --- 201,207 ---- # Parent pid, sts = os.waitpid(pid, 0) + # throw away additional data [see bug #427345] + while select.select([self.rfile], [], [], 0)[0]: + waste = self.rfile.read(1) if sts: self.log_error("CGI script exit status %#x", sts) *************** *** 245,248 **** --- 249,255 ---- data = self.rfile.read(nbytes) fi.write(data) + # throw away additional data [see bug #427345] + while select.select([self.rfile._sock], [], [], 0)[0]: + waste = self.rfile._sock.recv(1) fi.close() shutil.copyfileobj(fo, self.wfile) From tim_one@users.sourceforge.net Wed Jan 8 19:43:49 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 08 Jan 2003 11:43:49 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime EU.py,1.3,1.4 Local.py,1.1,1.2 US.py,1.16,1.17 datetime.py,1.144,1.145 dateutil.py,1.3,1.4 test_datetime.py,1.95,1.96 datetime2.py,1.1,NONE test_datetime2.py,1.2,NONE Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv24202 Modified Files: EU.py Local.py US.py datetime.py dateutil.py test_datetime.py Removed Files: datetime2.py test_datetime2.py Log Message: Collapsing datetime and datetimetz into datetime, and time and timetz into time. Index: EU.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/EU.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** EU.py 31 Dec 2002 05:58:02 -0000 1.3 --- EU.py 8 Jan 2003 19:43:44 -0000 1.4 *************** *** 17,21 **** """ ! from datetime import date, time, timedelta, datetime, datetimetz, tzinfo from dateutil import MARCH, OCTOBER, SUNDAY, weekday_of_month --- 17,21 ---- """ ! from datetime import date, time, timedelta, datetime, tzinfo from dateutil import MARCH, OCTOBER, SUNDAY, weekday_of_month *************** *** 82,86 **** We start easy, Saturday noon in Amsterdam on the last day of DST: ! >>> dt = datetimetz(2002, 10, 26, 12, 0, 0, tzinfo=Amsterdam) >>> dt.ctime() 'Sat Oct 26 12:00:00 2002' --- 82,86 ---- We start easy, Saturday noon in Amsterdam on the last day of DST: ! >>> dt = datetime(2002, 10, 26, 12, 0, 0, tzinfo=Amsterdam) >>> dt.ctime() 'Sat Oct 26 12:00:00 2002' *************** *** 105,109 **** Wednesday before DST ends: ! >>> dt = datetimetz(2002, 10, 23, 12, 0, 0, tzinfo=Amsterdam) >>> dt.ctime() 'Wed Oct 23 12:00:00 2002' --- 105,109 ---- Wednesday before DST ends: ! >>> dt = datetime(2002, 10, 23, 12, 0, 0, tzinfo=Amsterdam) >>> dt.ctime() 'Wed Oct 23 12:00:00 2002' *************** *** 122,126 **** before it ends: ! >>> dt = datetimetz(2002, 10, 27, 1, 59, 59, tzinfo=Amsterdam) >>> dt.ctime() + ' ' + dt.tzname() 'Sun Oct 27 01:59:59 2002 MDT' --- 122,126 ---- before it ends: ! >>> dt = datetime(2002, 10, 27, 1, 59, 59, tzinfo=Amsterdam) >>> dt.ctime() + ' ' + dt.tzname() 'Sun Oct 27 01:59:59 2002 MDT' Index: Local.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/Local.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Local.py 2 Jan 2003 23:11:02 -0000 1.1 --- Local.py 8 Jan 2003 19:43:45 -0000 1.2 *************** *** 3,7 **** import time as _time ! from datetime import date, time, timedelta, datetime, datetimetz, tzinfo STDOFFSET = timedelta(seconds = -_time.timezone) --- 3,7 ---- import time as _time ! from datetime import date, time, timedelta, datetime, tzinfo STDOFFSET = timedelta(seconds = -_time.timezone) *************** *** 46,50 **** Pick a time in standard time. ! >>> dt = datetimetz(2003, 1, 2, 18, 05, 49) >>> dt.isoformat() '2003-01-02T18:05:49' --- 46,50 ---- Pick a time in standard time. ! >>> dt = datetime(2003, 1, 2, 18, 05, 49) >>> dt.isoformat() '2003-01-02T18:05:49' *************** *** 55,59 **** Pick a time in DST. ! >>> dt = datetimetz(2003, 7, 2, 18, 05, 49) >>> dt.isoformat() '2003-07-02T18:05:49' --- 55,59 ---- Pick a time in DST. ! >>> dt = datetime(2003, 7, 2, 18, 05, 49) >>> dt.isoformat() '2003-07-02T18:05:49' Index: US.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/US.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** US.py 6 Jan 2003 16:24:14 -0000 1.16 --- US.py 8 Jan 2003 19:43:45 -0000 1.17 *************** *** 1,3 **** ! from datetime import time, datetime, datetimetz from datetime import tzinfo from datetime import timedelta --- 1,3 ---- ! from datetime import time, datetime from datetime import tzinfo from datetime import timedelta *************** *** 104,108 **** Right before DST starts. ! >>> before = datetimetz(2002, 4, 7, 1, 59, 59, tzinfo=Eastern) >>> printstuff(before) 2002-04-07 01:59:59-05:00 --- 104,108 ---- Right before DST starts. ! >>> before = datetime(2002, 4, 7, 1, 59, 59, tzinfo=Eastern) >>> printstuff(before) 2002-04-07 01:59:59-05:00 *************** *** 170,174 **** Now right before DST ends. ! >>> before = datetimetz(2002, 10, 27, 1, 59, 59, tzinfo=Eastern) >>> printstuff(before) 2002-10-27 01:59:59-04:00 --- 170,174 ---- Now right before DST ends. ! >>> before = datetime(2002, 10, 27, 1, 59, 59, tzinfo=Eastern) >>> printstuff(before) 2002-10-27 01:59:59-04:00 Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.144 retrieving revision 1.145 diff -C2 -d -r1.144 -r1.145 *** datetime.py 4 Jan 2003 18:25:23 -0000 1.144 --- datetime.py 8 Jan 2003 19:43:45 -0000 1.145 *************** *** 850,1015 **** self.__year = yhi * 256 + ylo date.min = date(1, 1, 1) date.max = date(9999, 12, 31) date.resolution = timedelta(days=1) - - class time(object): - """Concrete time type. - [...1195 lines suppressed...] ! pickle(datetime, _datetime_pickler, _datetime_unpickler) del pickle """ ! Some time zone algebra. For a datetime x, let x.n = x stripped of its timezone -- its naive time. x.o = x.utcoffset(), and assuming that doesn't raise an exception or *************** *** 1921,1925 **** None when called). ! The function wants to return a datetimetz y with timezone tz, equivalent to x. By #3, we want --- 1638,1642 ---- None when called). ! The function wants to return a datetime y with timezone tz, equivalent to x. By #3, we want Index: dateutil.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/dateutil.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dateutil.py 29 Dec 2002 06:42:28 -0000 1.3 --- dateutil.py 8 Jan 2003 19:43:46 -0000 1.4 *************** *** 1,5 **** ! # These all take dt arguments of type date, datetime, or datetimetz, and ! # those that return a date-like result return one of the same type as the ! # input dt. import datetime --- 1,4 ---- ! # These all take dt arguments of type date or datetime, and those that ! # return a date-like result return one of the same type as the input dt. import datetime Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.95 retrieving revision 1.96 diff -C2 -d -r1.95 -r1.96 *** test_datetime.py 4 Jan 2003 04:50:16 -0000 1.95 --- test_datetime.py 8 Jan 2003 19:43:46 -0000 1.96 *************** *** 10,15 **** from datetime import timedelta from datetime import tzinfo ! from datetime import time, timetz ! from datetime import date, datetime, datetimetz --- 10,15 ---- from datetime import timedelta from datetime import tzinfo ! from datetime import time ! from datetime import date, datetime *************** *** 1147,1151 **** orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, '\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00') derived = self.theclass(1, 1, 1) derived.__setstate__(state) --- 1147,1151 ---- orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) derived = self.theclass(1, 1, 1) derived.__setstate__(state) *************** *** 1312,1320 **** def test_astimezone(self): ! # Pretty boring for a datetime! datetimetz is more interesting here. dt = self.theclass.now() f = FixedOffset(44, "") for dtz in dt.astimezone(f), dt.astimezone(tz=f): ! self.failUnless(isinstance(dtz, datetimetz)) self.assertEqual(dt.date(), dtz.date()) self.assertEqual(dt.time(), dtz.time()) --- 1312,1320 ---- def test_astimezone(self): ! # Pretty boring! The TZ test is more interesting here. dt = self.theclass.now() f = FixedOffset(44, "") for dtz in dt.astimezone(f), dt.astimezone(tz=f): ! self.failUnless(isinstance(dtz, datetime)) self.assertEqual(dt.date(), dtz.date()) self.assertEqual(dt.time(), dtz.time()) *************** *** 1526,1530 **** orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, '\x14\x3b\x10\x00\x10\x00') derived = self.theclass() derived.__setstate__(state) --- 1526,1530 ---- orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) derived = self.theclass() derived.__setstate__(state) *************** *** 1572,1581 **** # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) ! # must be legit (which is true for timetz and datetimetz). class TZInfoBase(unittest.TestCase): def test_argument_passing(self): cls = self.theclass ! # A datetimetz passes itself on, a timetz passes None. class introspective(tzinfo): def tzname(self, dt): return dt and "real" or "none" --- 1572,1581 ---- # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) ! # must be legit (which is true for time and datetime). class TZInfoBase(unittest.TestCase): def test_argument_passing(self): cls = self.theclass ! # A datetime passes itself on, a time passes None. class introspective(tzinfo): def tzname(self, dt): return dt and "real" or "none" *************** *** 1586,1593 **** obj = cls(1, 2, 3, tzinfo=introspective()) ! expected = cls is timetz and "none" or "real" self.assertEqual(obj.tzname(), expected) ! expected = timedelta(minutes=(cls is timetz and -42 or 42)) self.assertEqual(obj.utcoffset(), expected) self.assertEqual(obj.dst(), expected) --- 1586,1593 ---- obj = cls(1, 2, 3, tzinfo=introspective()) ! expected = cls is time and "none" or "real" self.assertEqual(obj.tzname(), expected) ! expected = timedelta(minutes=(cls is time and -42 or 42)) self.assertEqual(obj.utcoffset(), expected) self.assertEqual(obj.dst(), expected) *************** *** 1621,1633 **** (1439, True), (1440, False)): ! if cls is timetz: t = cls(1, 2, 3, tzinfo=Edgy(offset)) ! elif cls is datetimetz: t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset)) if legit: aofs = abs(offset) h, m = divmod(aofs, 60) tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m) ! if isinstance(t, datetimetz): t = t.timetz() self.assertEqual(str(t), "01:02:03" + tag) --- 1621,1635 ---- (1439, True), (1440, False)): ! if cls is time: t = cls(1, 2, 3, tzinfo=Edgy(offset)) ! elif cls is datetime: t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset)) + else: + assert 0, "impossible" if legit: aofs = abs(offset) h, m = divmod(aofs, 60) tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m) ! if isinstance(t, datetime): t = t.timetz() self.assertEqual(str(t), "01:02:03" + tag) *************** *** 1708,1715 **** # However, if they're different members, uctoffset is not ignored. ! # Note that a timetz can't actually have an operand-depedent offset, ! # though (and timetz.utcoffset() passes None to tzinfo.utcoffset()), ! # so skip this test for timetz. ! if cls is not timetz: d0 = base.replace(minute=3, tzinfo=OperandDependentOffset()) d1 = base.replace(minute=9, tzinfo=OperandDependentOffset()) --- 1710,1717 ---- # However, if they're different members, uctoffset is not ignored. ! # Note that a time can't actually have an operand-depedent offset, ! # though (and time.utcoffset() passes None to tzinfo.utcoffset()), ! # so skip this test for time. ! if cls is not time: d0 = base.replace(minute=3, tzinfo=OperandDependentOffset()) d1 = base.replace(minute=9, tzinfo=OperandDependentOffset()) *************** *** 1730,1735 **** class TestTimeTZ(TestTime, TZInfoBase): ! theclass = timetz def test_empty(self): --- 1732,1738 ---- + # Testing time objects with a non-None tzinfo. class TestTimeTZ(TestTime, TZInfoBase): ! theclass = time def test_empty(self): *************** *** 1745,1753 **** utc = FixedOffset(0, "UTC", -2) met = FixedOffset(60, "MET", 3) ! t1 = timetz( 7, 47, tzinfo=est) ! t2 = timetz(12, 47, tzinfo=utc) ! t3 = timetz(13, 47, tzinfo=met) ! t4 = timetz(microsecond=40) ! t5 = timetz(microsecond=40, tzinfo=utc) self.assertEqual(t1.tzinfo, est) --- 1748,1756 ---- utc = FixedOffset(0, "UTC", -2) met = FixedOffset(60, "MET", 3) ! t1 = time( 7, 47, tzinfo=est) ! t2 = time(12, 47, tzinfo=utc) ! t3 = time(13, 47, tzinfo=met) ! t4 = time(microsecond=40) ! t5 = time(microsecond=40, tzinfo=utc) self.assertEqual(t1.tzinfo, est) *************** *** 1798,1802 **** self.assertEqual(t5.isoformat(), "00:00:00.000040+00:00") ! d = 'datetime.timetz' self.assertEqual(repr(t1), d + "(7, 47, tzinfo=est)") self.assertEqual(repr(t2), d + "(12, 47, tzinfo=utc)") --- 1801,1805 ---- self.assertEqual(t5.isoformat(), "00:00:00.000040+00:00") ! d = 'datetime.time' self.assertEqual(repr(t1), d + "(7, 47, tzinfo=est)") self.assertEqual(repr(t2), d + "(12, 47, tzinfo=utc)") *************** *** 1811,1815 **** yuck = FixedOffset(-1439, "%z %Z %%z%%Z") ! t1 = timetz(23, 59, tzinfo=yuck) self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"), "23:59 %Z='%z %Z %%z%%Z' %z='-2359'") --- 1814,1818 ---- yuck = FixedOffset(-1439, "%z %Z %%z%%Z") ! t1 = time(23, 59, tzinfo=yuck) self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"), "23:59 %Z='%z %Z %%z%%Z' %z='-2359'") *************** *** 1818,1822 **** class Badtzname(tzinfo): def tzname(self, dt): return 42 ! t = timetz(2, 3, 4, tzinfo=Badtzname()) self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04") self.assertRaises(TypeError, t.strftime, "%Z") --- 1821,1825 ---- class Badtzname(tzinfo): def tzname(self, dt): return 42 ! t = time(2, 3, 4, tzinfo=Badtzname()) self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04") self.assertRaises(TypeError, t.strftime, "%Z") *************** *** 1939,1943 **** def test_mixed_compare(self): t1 = time(1, 2, 3) ! t2 = timetz(1, 2, 3) self.assertEqual(t1, t2) t2 = t2.replace(tzinfo=None) --- 1942,1946 ---- def test_mixed_compare(self): t1 = time(1, 2, 3) ! t2 = time(1, 2, 3) self.assertEqual(t1, t2) t2 = t2.replace(tzinfo=None) *************** *** 1949,1953 **** self.assertRaises(TypeError, lambda: t1 == t2) ! # In timetz w/ identical tzinfo objects, utcoffset is ignored. class Varies(tzinfo): def __init__(self): --- 1952,1956 ---- self.assertRaises(TypeError, lambda: t1 == t2) ! # In time w/ identical tzinfo objects, utcoffset is ignored. class Varies(tzinfo): def __init__(self): *************** *** 1969,1974 **** class TestDateTimeTZ(TestDateTime, TZInfoBase): ! theclass = datetimetz def test_trivial(self): --- 1972,1979 ---- + # Testing datetime objects with a non-None tzinfo. + class TestDateTimeTZ(TestDateTime, TZInfoBase): ! theclass = datetime def test_trivial(self): *************** *** 2105,2111 **** utc = FixedOffset(0, "UTC") met = FixedOffset(60, "MET") ! t1 = datetimetz(2002, 3, 19, 7, 47, tzinfo=est) ! t2 = datetimetz(2002, 3, 19, 12, 47, tzinfo=utc) ! t3 = datetimetz(2002, 3, 19, 13, 47, tzinfo=met) self.assertEqual(t1.tzinfo, est) self.assertEqual(t2.tzinfo, utc) --- 2110,2116 ---- utc = FixedOffset(0, "UTC") met = FixedOffset(60, "MET") ! t1 = datetime(2002, 3, 19, 7, 47, tzinfo=est) ! t2 = datetime(2002, 3, 19, 12, 47, tzinfo=utc) ! t3 = datetime(2002, 3, 19, 13, 47, tzinfo=met) self.assertEqual(t1.tzinfo, est) self.assertEqual(t2.tzinfo, utc) *************** *** 2126,2130 **** self.assertEqual(str(t2), "2002-03-19 12:47:00+00:00") self.assertEqual(str(t3), "2002-03-19 13:47:00+01:00") ! d = 'datetime.datetimetz(2002, 3, 19, ' self.assertEqual(repr(t1), d + "7, 47, tzinfo=est)") self.assertEqual(repr(t2), d + "12, 47, tzinfo=utc)") --- 2131,2135 ---- self.assertEqual(str(t2), "2002-03-19 12:47:00+00:00") self.assertEqual(str(t3), "2002-03-19 13:47:00+01:00") ! d = 'datetime.datetime(2002, 3, 19, ' self.assertEqual(repr(t1), d + "7, 47, tzinfo=est)") self.assertEqual(repr(t2), d + "12, 47, tzinfo=utc)") *************** *** 2134,2140 **** met = FixedOffset(60, "MET") d = date(2002, 3, 4) ! tz = timetz(18, 45, 3, 1234, tzinfo=met) ! dt = datetimetz.combine(d, tz) ! self.assertEqual(dt, datetimetz(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met)) --- 2139,2145 ---- met = FixedOffset(60, "MET") d = date(2002, 3, 4) ! tz = time(18, 45, 3, 1234, tzinfo=met) ! dt = datetime.combine(d, tz) ! self.assertEqual(dt, datetime(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met)) *************** *** 2144,2148 **** self.assertEqual(dt.date(), date(2002, 3, 4)) self.assertEqual(dt.time(), time(18, 45, 3, 1234)) ! self.assertEqual(dt.timetz(), timetz(18, 45, 3, 1234, tzinfo=met)) def test_tz_aware_arithmetic(self): --- 2149,2153 ---- self.assertEqual(dt.date(), date(2002, 3, 4)) self.assertEqual(dt.time(), time(18, 45, 3, 1234)) ! self.assertEqual(dt.timetz(), time(18, 45, 3, 1234, tzinfo=met)) def test_tz_aware_arithmetic(self): *************** *** 2151,2155 **** now = self.theclass.now() tz55 = FixedOffset(-330, "west 5:30") ! timeaware = now.timetz().replace(tzinfo=tz55) nowaware = self.theclass.combine(now.date(), timeaware) self.failUnless(nowaware.tzinfo is tz55) --- 2156,2160 ---- now = self.theclass.now() tz55 = FixedOffset(-330, "west 5:30") ! timeaware = now.time().replace(tzinfo=tz55) nowaware = self.theclass.combine(now.date(), timeaware) self.failUnless(nowaware.tzinfo is tz55) *************** *** 2160,2164 **** self.assertRaises(TypeError, lambda: nowaware - now) ! # And adding datetimetz's doesn't make sense, aware or not. self.assertRaises(TypeError, lambda: now + nowaware) self.assertRaises(TypeError, lambda: nowaware + now) --- 2165,2169 ---- self.assertRaises(TypeError, lambda: nowaware - now) ! # And adding datetime's doesn't make sense, aware or not. self.assertRaises(TypeError, lambda: now + nowaware) self.assertRaises(TypeError, lambda: nowaware + now) *************** *** 2271,2275 **** def test_tzinfo_timetuple(self): ! # TestDateTime tested most of this. datetimetz adds a twist to the # DST flag. class DST(tzinfo): --- 2276,2280 ---- def test_tzinfo_timetuple(self): ! # TestDateTime tested most of this. datetime adds a twist to the # DST flag. class DST(tzinfo): *************** *** 2512,2516 **** def test_mixed_compare(self): t1 = datetime(1, 2, 3, 4, 5, 6, 7) ! t2 = datetimetz(1, 2, 3, 4, 5, 6, 7) self.assertEqual(t1, t2) t2 = t2.replace(tzinfo=None) --- 2517,2521 ---- def test_mixed_compare(self): t1 = datetime(1, 2, 3, 4, 5, 6, 7) ! t2 = datetime(1, 2, 3, 4, 5, 6, 7) self.assertEqual(t1, t2) t2 = t2.replace(tzinfo=None) *************** *** 2522,2526 **** self.assertRaises(TypeError, lambda: t1 == t2) ! # In datetimetz w/ identical tzinfo objects, utcoffset is ignored. class Varies(tzinfo): def __init__(self): --- 2527,2531 ---- self.assertRaises(TypeError, lambda: t1 == t2) ! # In datetime w/ identical tzinfo objects, utcoffset is ignored. class Varies(tzinfo): def __init__(self): *************** *** 2611,2618 **** class TestTimezoneConversions(unittest.TestCase): # The DST switch times for 2002, in local time. ! dston = datetimetz(2002, 4, 7, 2) ! dstoff = datetimetz(2002, 10, 27, 2) ! theclass = datetimetz # Check a time that's inside DST. --- 2616,2623 ---- class TestTimezoneConversions(unittest.TestCase): # The DST switch times for 2002, in local time. ! dston = datetime(2002, 4, 7, 2) ! dstoff = datetime(2002, 10, 27, 2) ! theclass = datetime # Check a time that's inside DST. --- datetime2.py DELETED --- --- test_datetime2.py DELETED --- From doerwalter@users.sourceforge.net Wed Jan 8 20:38:45 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Wed, 08 Jan 2003 12:38:45 -0800 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c,2.176,2.177 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv6112/Objects Modified Files: unicodeobject.c Log Message: Remove variable owned from PyUnicode_FromEncodedObject, which is unused (except for Py_DECREF calls) since the introduction of __unicode__. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.176 retrieving revision 2.177 diff -C2 -d -r2.176 -r2.177 *** unicodeobject.c 29 Dec 2002 19:44:06 -0000 2.176 --- unicodeobject.c 8 Jan 2003 20:38:39 -0000 2.177 *************** *** 453,457 **** const char *s = NULL; int len; - int owned = 0; PyObject *v; --- 453,456 ---- *************** *** 511,523 **** v = PyUnicode_Decode(s, len, encoding, errors); - if (owned) { - Py_DECREF(obj); - } return v; onError: - if (owned) { - Py_DECREF(obj); - } return NULL; } --- 510,516 ---- From tim_one@users.sourceforge.net Wed Jan 8 20:40:27 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 08 Jan 2003 12:40:27 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv5753/python/Lib/test Modified Files: test_datetime.py Log Message: Utterly minimal changes to collapse datetimetz into datetime, and timetz into time. This is little more than *exporting* the datetimetz object under the name "datetime", and similarly for timetz. A good implementation of this change requires more work, but this is fully functional if you don't stare too hard at the internals (e.g., right now a type named "datetime" shows up as a base class of the type named "datetime"). The docs also need extensive revision, not part of this checkin. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** test_datetime.py 4 Jan 2003 06:03:15 -0000 1.22 --- test_datetime.py 8 Jan 2003 20:39:52 -0000 1.23 *************** *** 1,3 **** ! """Test date/time type.""" import sys --- 1,6 ---- ! """Test date/time type. ! ! See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases ! """ import sys *************** *** 9,14 **** from datetime import timedelta from datetime import tzinfo ! from datetime import time, timetz ! from datetime import date, datetime, datetimetz ############################################################################# --- 12,33 ---- from datetime import timedelta from datetime import tzinfo ! from datetime import time ! from datetime import date, datetime ! ! ! # XXX The test suite uncovered a bug in Python 2.2.2: if x and y are ! # XXX instances of new-style classes (like date and time) that both ! # XXX define __cmp__, and x is compared to y, and one of the __cmp__ ! # XXX implementations raises an exception, the exception can get dropped ! # XXX on the floor when it occurs, and pop up again at some "random" time ! # XXX later (it depends on when the next opcode gets executed that ! # XXX bothers to check). There isn't a workaround for this, so instead ! # XXX we disable the parts of the tests that trigger it unless ! # XXX CMP_BUG_FIXED is true. The bug is still there, we simply avoid ! # XXX provoking it here. ! # XXX Guido checked into a fix that will go into 2.2.3. The bug was ! # XXX already fixed in 2.3 CVS via a different means. ! CMP_BUG_FIXED = sys.version_info >= (2, 2, 3) ! ############################################################################# *************** *** 479,503 **** self.assertEqual(fromord.microsecond, 0) ! # Check first and last days of year across the whole range of years ! # supported. ! ordinal = 1 ! for year in xrange(MINYEAR, MAXYEAR+1): # Verify (year, 1, 1) -> ordinal -> y, m, d is identity. d = self.theclass(year, 1, 1) n = d.toordinal() - self.assertEqual(ordinal, n) d2 = self.theclass.fromordinal(n) self.assertEqual(d, d2) ! self.assertEqual(d.timetuple().tm_yday, 1) ! # Same for (year, 12, 31). ! isleap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) ! days_in_year = 365 + isleap ! d = self.theclass(year, 12, 31) ! n = d.toordinal() ! self.assertEqual(n, ordinal + days_in_year - 1) ! self.assertEqual(d.timetuple().tm_yday, days_in_year) ! d2 = self.theclass.fromordinal(n) ! self.assertEqual(d, d2) ! ordinal += days_in_year # Test every day in a leap-year and a non-leap year. --- 498,515 ---- self.assertEqual(fromord.microsecond, 0) ! # Check first and last days of year spottily across the whole ! # range of years supported. ! for year in xrange(MINYEAR, MAXYEAR+1, 7): # Verify (year, 1, 1) -> ordinal -> y, m, d is identity. d = self.theclass(year, 1, 1) n = d.toordinal() d2 = self.theclass.fromordinal(n) self.assertEqual(d, d2) ! # Verify that moving back a day gets to the end of year-1. ! if year > 1: ! d = self.theclass.fromordinal(n-1) ! d2 = self.theclass(year-1, 12, 31) ! self.assertEqual(d, d2) ! self.assertEqual(d2.toordinal(), n-1) # Test every day in a leap-year and a non-leap year. *************** *** 1137,1141 **** orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, '\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00') derived = self.theclass(1, 1, 1) derived.__setstate__(state) --- 1149,1153 ---- orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) derived = self.theclass(1, 1, 1) derived.__setstate__(state) *************** *** 1302,1310 **** def test_astimezone(self): ! # Pretty boring for a datetime! datetimetz is more interesting here. dt = self.theclass.now() f = FixedOffset(44, "") for dtz in dt.astimezone(f), dt.astimezone(tz=f): ! self.failUnless(isinstance(dtz, datetimetz)) self.assertEqual(dt.date(), dtz.date()) self.assertEqual(dt.time(), dtz.time()) --- 1314,1322 ---- def test_astimezone(self): ! # Pretty boring! The TZ test is more interesting here. dt = self.theclass.now() f = FixedOffset(44, "") for dtz in dt.astimezone(f), dt.astimezone(tz=f): ! self.failUnless(isinstance(dtz, datetime)) self.assertEqual(dt.date(), dtz.date()) self.assertEqual(dt.time(), dtz.time()) *************** *** 1384,1389 **** self.assertEqual(cmp(t2, t1), 1) ! for badarg in (10, 10L, 34.5, "abc", {}, [], (), date(1, 1, 1), ! datetime(1, 1, 1, 1, 1), timedelta(9)): self.assertRaises(TypeError, lambda: t1 == badarg) self.assertRaises(TypeError, lambda: t1 != badarg) --- 1396,1403 ---- self.assertEqual(cmp(t2, t1), 1) ! badargs = (10, 10L, 34.5, "abc", {}, [], ()) ! if CMP_BUG_FIXED: ! badargs += (date(1, 1, 1), datetime(1, 1, 1, 1, 1), timedelta(9)) ! for badarg in badargs: self.assertRaises(TypeError, lambda: t1 == badarg) self.assertRaises(TypeError, lambda: t1 != badarg) *************** *** 1514,1518 **** orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, '\x14\x3b\x10\x00\x10\x00') derived = self.theclass() derived.__setstate__(state) --- 1528,1532 ---- orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) derived = self.theclass() derived.__setstate__(state) *************** *** 1560,1569 **** # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) ! # must be legit (which is true for timetz and datetimetz). class TZInfoBase(unittest.TestCase): def test_argument_passing(self): cls = self.theclass ! # A datetimetz passes itself on, a timetz passes None. class introspective(tzinfo): def tzname(self, dt): return dt and "real" or "none" --- 1574,1583 ---- # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) ! # must be legit (which is true for time and datetime). class TZInfoBase(unittest.TestCase): def test_argument_passing(self): cls = self.theclass ! # A datetime passes itself on, a time passes None. class introspective(tzinfo): def tzname(self, dt): return dt and "real" or "none" *************** *** 1574,1581 **** obj = cls(1, 2, 3, tzinfo=introspective()) ! expected = cls is timetz and "none" or "real" self.assertEqual(obj.tzname(), expected) ! expected = timedelta(minutes=(cls is timetz and -42 or 42)) self.assertEqual(obj.utcoffset(), expected) self.assertEqual(obj.dst(), expected) --- 1588,1595 ---- obj = cls(1, 2, 3, tzinfo=introspective()) ! expected = cls is time and "none" or "real" self.assertEqual(obj.tzname(), expected) ! expected = timedelta(minutes=(cls is time and -42 or 42)) self.assertEqual(obj.utcoffset(), expected) self.assertEqual(obj.dst(), expected) *************** *** 1609,1621 **** (1439, True), (1440, False)): ! if cls is timetz: t = cls(1, 2, 3, tzinfo=Edgy(offset)) ! elif cls is datetimetz: t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset)) if legit: aofs = abs(offset) h, m = divmod(aofs, 60) tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m) ! if isinstance(t, datetimetz): t = t.timetz() self.assertEqual(str(t), "01:02:03" + tag) --- 1623,1637 ---- (1439, True), (1440, False)): ! if cls is time: t = cls(1, 2, 3, tzinfo=Edgy(offset)) ! elif cls is datetime: t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset)) + else: + assert 0, "impossible" if legit: aofs = abs(offset) h, m = divmod(aofs, 60) tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m) ! if isinstance(t, datetime): t = t.timetz() self.assertEqual(str(t), "01:02:03" + tag) *************** *** 1696,1703 **** # However, if they're different members, uctoffset is not ignored. ! # Note that a timetz can't actually have an operand-depedent offset, ! # though (and timetz.utcoffset() passes None to tzinfo.utcoffset()), ! # so skip this test for timetz. ! if cls is not timetz: d0 = base.replace(minute=3, tzinfo=OperandDependentOffset()) d1 = base.replace(minute=9, tzinfo=OperandDependentOffset()) --- 1712,1719 ---- # However, if they're different members, uctoffset is not ignored. ! # Note that a time can't actually have an operand-depedent offset, ! # though (and time.utcoffset() passes None to tzinfo.utcoffset()), ! # so skip this test for time. ! if cls is not time: d0 = base.replace(minute=3, tzinfo=OperandDependentOffset()) d1 = base.replace(minute=9, tzinfo=OperandDependentOffset()) *************** *** 1718,1723 **** class TestTimeTZ(TestTime, TZInfoBase): ! theclass = timetz def test_empty(self): --- 1734,1740 ---- + # Testing time objects with a non-None tzinfo. class TestTimeTZ(TestTime, TZInfoBase): ! theclass = time def test_empty(self): *************** *** 1733,1741 **** utc = FixedOffset(0, "UTC", -2) met = FixedOffset(60, "MET", 3) ! t1 = timetz( 7, 47, tzinfo=est) ! t2 = timetz(12, 47, tzinfo=utc) ! t3 = timetz(13, 47, tzinfo=met) ! t4 = timetz(microsecond=40) ! t5 = timetz(microsecond=40, tzinfo=utc) self.assertEqual(t1.tzinfo, est) --- 1750,1758 ---- utc = FixedOffset(0, "UTC", -2) met = FixedOffset(60, "MET", 3) ! t1 = time( 7, 47, tzinfo=est) ! t2 = time(12, 47, tzinfo=utc) ! t3 = time(13, 47, tzinfo=met) ! t4 = time(microsecond=40) ! t5 = time(microsecond=40, tzinfo=utc) self.assertEqual(t1.tzinfo, est) *************** *** 1786,1790 **** self.assertEqual(t5.isoformat(), "00:00:00.000040+00:00") ! d = 'datetime.timetz' self.assertEqual(repr(t1), d + "(7, 47, tzinfo=est)") self.assertEqual(repr(t2), d + "(12, 47, tzinfo=utc)") --- 1803,1807 ---- self.assertEqual(t5.isoformat(), "00:00:00.000040+00:00") ! d = 'datetime.time' self.assertEqual(repr(t1), d + "(7, 47, tzinfo=est)") self.assertEqual(repr(t2), d + "(12, 47, tzinfo=utc)") *************** *** 1799,1803 **** yuck = FixedOffset(-1439, "%z %Z %%z%%Z") ! t1 = timetz(23, 59, tzinfo=yuck) self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"), "23:59 %Z='%z %Z %%z%%Z' %z='-2359'") --- 1816,1820 ---- yuck = FixedOffset(-1439, "%z %Z %%z%%Z") ! t1 = time(23, 59, tzinfo=yuck) self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"), "23:59 %Z='%z %Z %%z%%Z' %z='-2359'") *************** *** 1806,1810 **** class Badtzname(tzinfo): def tzname(self, dt): return 42 ! t = timetz(2, 3, 4, tzinfo=Badtzname()) self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04") self.assertRaises(TypeError, t.strftime, "%Z") --- 1823,1827 ---- class Badtzname(tzinfo): def tzname(self, dt): return 42 ! t = time(2, 3, 4, tzinfo=Badtzname()) self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04") self.assertRaises(TypeError, t.strftime, "%Z") *************** *** 1927,1931 **** def test_mixed_compare(self): t1 = time(1, 2, 3) ! t2 = timetz(1, 2, 3) self.assertEqual(t1, t2) t2 = t2.replace(tzinfo=None) --- 1944,1948 ---- def test_mixed_compare(self): t1 = time(1, 2, 3) ! t2 = time(1, 2, 3) self.assertEqual(t1, t2) t2 = t2.replace(tzinfo=None) *************** *** 1933,1940 **** t2 = t2.replace(tzinfo=FixedOffset(None, "")) self.assertEqual(t1, t2) ! t2 = t2.replace(tzinfo=FixedOffset(0, "")) ! self.assertRaises(TypeError, lambda: t1 == t2) ! # In timetz w/ identical tzinfo objects, utcoffset is ignored. class Varies(tzinfo): def __init__(self): --- 1950,1958 ---- t2 = t2.replace(tzinfo=FixedOffset(None, "")) self.assertEqual(t1, t2) ! if CMP_BUG_FIXED: ! t2 = t2.replace(tzinfo=FixedOffset(0, "")) ! self.assertRaises(TypeError, lambda: t1 == t2) ! # In time w/ identical tzinfo objects, utcoffset is ignored. class Varies(tzinfo): def __init__(self): *************** *** 1956,1961 **** class TestDateTimeTZ(TestDateTime, TZInfoBase): ! theclass = datetimetz def test_trivial(self): --- 1974,1981 ---- + # Testing datetime objects with a non-None tzinfo. + class TestDateTimeTZ(TestDateTime, TZInfoBase): ! theclass = datetime def test_trivial(self): *************** *** 2092,2098 **** utc = FixedOffset(0, "UTC") met = FixedOffset(60, "MET") ! t1 = datetimetz(2002, 3, 19, 7, 47, tzinfo=est) ! t2 = datetimetz(2002, 3, 19, 12, 47, tzinfo=utc) ! t3 = datetimetz(2002, 3, 19, 13, 47, tzinfo=met) self.assertEqual(t1.tzinfo, est) self.assertEqual(t2.tzinfo, utc) --- 2112,2118 ---- utc = FixedOffset(0, "UTC") met = FixedOffset(60, "MET") ! t1 = datetime(2002, 3, 19, 7, 47, tzinfo=est) ! t2 = datetime(2002, 3, 19, 12, 47, tzinfo=utc) ! t3 = datetime(2002, 3, 19, 13, 47, tzinfo=met) self.assertEqual(t1.tzinfo, est) self.assertEqual(t2.tzinfo, utc) *************** *** 2113,2117 **** self.assertEqual(str(t2), "2002-03-19 12:47:00+00:00") self.assertEqual(str(t3), "2002-03-19 13:47:00+01:00") ! d = 'datetime.datetimetz(2002, 3, 19, ' self.assertEqual(repr(t1), d + "7, 47, tzinfo=est)") self.assertEqual(repr(t2), d + "12, 47, tzinfo=utc)") --- 2133,2137 ---- self.assertEqual(str(t2), "2002-03-19 12:47:00+00:00") self.assertEqual(str(t3), "2002-03-19 13:47:00+01:00") ! d = 'datetime.datetime(2002, 3, 19, ' self.assertEqual(repr(t1), d + "7, 47, tzinfo=est)") self.assertEqual(repr(t2), d + "12, 47, tzinfo=utc)") *************** *** 2121,2127 **** met = FixedOffset(60, "MET") d = date(2002, 3, 4) ! tz = timetz(18, 45, 3, 1234, tzinfo=met) ! dt = datetimetz.combine(d, tz) ! self.assertEqual(dt, datetimetz(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met)) --- 2141,2147 ---- met = FixedOffset(60, "MET") d = date(2002, 3, 4) ! tz = time(18, 45, 3, 1234, tzinfo=met) ! dt = datetime.combine(d, tz) ! self.assertEqual(dt, datetime(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met)) *************** *** 2131,2135 **** self.assertEqual(dt.date(), date(2002, 3, 4)) self.assertEqual(dt.time(), time(18, 45, 3, 1234)) ! self.assertEqual(dt.timetz(), timetz(18, 45, 3, 1234, tzinfo=met)) def test_tz_aware_arithmetic(self): --- 2151,2155 ---- self.assertEqual(dt.date(), date(2002, 3, 4)) self.assertEqual(dt.time(), time(18, 45, 3, 1234)) ! self.assertEqual(dt.timetz(), time(18, 45, 3, 1234, tzinfo=met)) def test_tz_aware_arithmetic(self): *************** *** 2138,2142 **** now = self.theclass.now() tz55 = FixedOffset(-330, "west 5:30") ! timeaware = now.timetz().replace(tzinfo=tz55) nowaware = self.theclass.combine(now.date(), timeaware) self.failUnless(nowaware.tzinfo is tz55) --- 2158,2162 ---- now = self.theclass.now() tz55 = FixedOffset(-330, "west 5:30") ! timeaware = now.time().replace(tzinfo=tz55) nowaware = self.theclass.combine(now.date(), timeaware) self.failUnless(nowaware.tzinfo is tz55) *************** *** 2147,2151 **** self.assertRaises(TypeError, lambda: nowaware - now) ! # And adding datetimetz's doesn't make sense, aware or not. self.assertRaises(TypeError, lambda: now + nowaware) self.assertRaises(TypeError, lambda: nowaware + now) --- 2167,2171 ---- self.assertRaises(TypeError, lambda: nowaware - now) ! # And adding datetime's doesn't make sense, aware or not. self.assertRaises(TypeError, lambda: now + nowaware) self.assertRaises(TypeError, lambda: nowaware + now) *************** *** 2258,2262 **** def test_tzinfo_timetuple(self): ! # TestDateTime tested most of this. datetimetz adds a twist to the # DST flag. class DST(tzinfo): --- 2278,2282 ---- def test_tzinfo_timetuple(self): ! # TestDateTime tested most of this. datetime adds a twist to the # DST flag. class DST(tzinfo): *************** *** 2499,2503 **** def test_mixed_compare(self): t1 = datetime(1, 2, 3, 4, 5, 6, 7) ! t2 = datetimetz(1, 2, 3, 4, 5, 6, 7) self.assertEqual(t1, t2) t2 = t2.replace(tzinfo=None) --- 2519,2523 ---- def test_mixed_compare(self): t1 = datetime(1, 2, 3, 4, 5, 6, 7) ! t2 = datetime(1, 2, 3, 4, 5, 6, 7) self.assertEqual(t1, t2) t2 = t2.replace(tzinfo=None) *************** *** 2505,2512 **** t2 = t2.replace(tzinfo=FixedOffset(None, "")) self.assertEqual(t1, t2) ! t2 = t2.replace(tzinfo=FixedOffset(0, "")) ! self.assertRaises(TypeError, lambda: t1 == t2) ! # In datetimetz w/ identical tzinfo objects, utcoffset is ignored. class Varies(tzinfo): def __init__(self): --- 2525,2533 ---- t2 = t2.replace(tzinfo=FixedOffset(None, "")) self.assertEqual(t1, t2) ! if CMP_BUG_FIXED: ! t2 = t2.replace(tzinfo=FixedOffset(0, "")) ! self.assertRaises(TypeError, lambda: t1 == t2) ! # In datetime w/ identical tzinfo objects, utcoffset is ignored. class Varies(tzinfo): def __init__(self): *************** *** 2597,2604 **** class TestTimezoneConversions(unittest.TestCase): # The DST switch times for 2002, in local time. ! dston = datetimetz(2002, 4, 7, 2) ! dstoff = datetimetz(2002, 10, 27, 2) ! theclass = datetimetz # Check a time that's inside DST. --- 2618,2625 ---- class TestTimezoneConversions(unittest.TestCase): # The DST switch times for 2002, in local time. ! dston = datetime(2002, 4, 7, 2) ! dstoff = datetime(2002, 10, 27, 2) ! theclass = datetime # Check a time that's inside DST. From tim_one@users.sourceforge.net Wed Jan 8 20:40:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 08 Jan 2003 12:40:34 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.608,1.609 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv5753/python/Misc Modified Files: NEWS Log Message: Utterly minimal changes to collapse datetimetz into datetime, and timetz into time. This is little more than *exporting* the datetimetz object under the name "datetime", and similarly for timetz. A good implementation of this change requires more work, but this is fully functional if you don't stare too hard at the internals (e.g., right now a type named "datetime" shows up as a base class of the type named "datetime"). The docs also need extensive revision, not part of this checkin. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.608 retrieving revision 1.609 diff -C2 -d -r1.608 -r1.609 *** NEWS 8 Jan 2003 16:29:17 -0000 1.608 --- NEWS 8 Jan 2003 20:39:54 -0000 1.609 *************** *** 32,35 **** --- 32,42 ---- - datetime changes: + The datetime and datetimetz classes have been collapsed into a single + datetime class, and likewise the time and timetz classes into a single + time class. Previously, a datetimetz object with tzinfo=None acted + exactly like a datetime object, and similarly for timetz. This wasn't + enough of a difference to justify distinct classes, and life is simpler + now. + today() and now() now round system timestamps to the closest microsecond . This repairs an *************** *** 1203,1207 **** - MacPython no longer maps both \r and \n to \n on input for any text file. This feature has been replaced by universal newline support (PEP278). ! - The default encoding for Python sourcefiles in MacPython-OS9 is no longer mac-roman (or whatever your local Mac encoding was but "ascii", like on --- 1210,1214 ---- - MacPython no longer maps both \r and \n to \n on input for any text file. This feature has been replaced by universal newline support (PEP278). ! - The default encoding for Python sourcefiles in MacPython-OS9 is no longer mac-roman (or whatever your local Mac encoding was but "ascii", like on From tim_one@users.sourceforge.net Wed Jan 8 20:40:42 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 08 Jan 2003 12:40:42 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv5753/python/Modules Modified Files: datetimemodule.c Log Message: Utterly minimal changes to collapse datetimetz into datetime, and timetz into time. This is little more than *exporting* the datetimetz object under the name "datetime", and similarly for timetz. A good implementation of this change requires more work, but this is fully functional if you don't stare too hard at the internals (e.g., right now a type named "datetime" shows up as a base class of the type named "datetime"). The docs also need extensive revision, not part of this checkin. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** datetimemodule.c 8 Jan 2003 16:28:45 -0000 1.33 --- datetimemodule.c 8 Jan 2003 20:40:01 -0000 1.34 *************** *** 3346,3353 **** datetime_gettime(PyDateTime_DateTime *self) { ! return new_time(DATE_GET_HOUR(self), ! DATE_GET_MINUTE(self), ! DATE_GET_SECOND(self), ! DATE_GET_MICROSECOND(self)); } --- 3346,3354 ---- datetime_gettime(PyDateTime_DateTime *self) { ! return new_timetz(DATE_GET_HOUR(self), ! DATE_GET_MINUTE(self), ! DATE_GET_SECOND(self), ! DATE_GET_MICROSECOND(self), ! Py_None); } *************** *** 3458,3463 **** {"time", (PyCFunction)datetime_gettime, METH_NOARGS, ! PyDoc_STR("Return time object with same hour, minute, second and " ! "microsecond.")}, {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS, --- 3459,3463 ---- {"time", (PyCFunction)datetime_gettime, METH_NOARGS, ! PyDoc_STR("Return time object with same time but with tzinfo=None.")}, {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS, *************** *** 4404,4408 **** PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "datetime.timetz", /* tp_name */ sizeof(PyDateTime_TimeTZ), /* tp_basicsize */ 0, /* tp_itemsize */ --- 4404,4408 ---- PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "datetime.time", /* tp_name */ sizeof(PyDateTime_TimeTZ), /* tp_basicsize */ 0, /* tp_itemsize */ *************** *** 5120,5124 **** PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "datetime.datetimetz", /* tp_name */ sizeof(PyDateTime_DateTimeTZ), /* tp_basicsize */ 0, /* tp_itemsize */ --- 5120,5124 ---- PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "datetime.datetime", /* tp_name */ sizeof(PyDateTime_DateTimeTZ), /* tp_basicsize */ 0, /* tp_itemsize */ *************** *** 5425,5446 **** PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType); - Py_INCREF(&PyDateTime_DateTimeType); - PyModule_AddObject(m, "datetime", - (PyObject *) &PyDateTime_DateTimeType); - Py_INCREF(&PyDateTime_DeltaType); PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType); - Py_INCREF(&PyDateTime_TimeType); - PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType); - Py_INCREF(&PyDateTime_TZInfoType); PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); Py_INCREF(&PyDateTime_TimeTZType); ! PyModule_AddObject(m, "timetz", (PyObject *) &PyDateTime_TimeTZType); Py_INCREF(&PyDateTime_DateTimeTZType); ! PyModule_AddObject(m, "datetimetz", (PyObject *)&PyDateTime_DateTimeTZType); --- 5425,5439 ---- PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType); Py_INCREF(&PyDateTime_DeltaType); PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType); Py_INCREF(&PyDateTime_TZInfoType); PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); Py_INCREF(&PyDateTime_TimeTZType); ! PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeTZType); Py_INCREF(&PyDateTime_DateTimeTZType); ! PyModule_AddObject(m, "datetime", (PyObject *)&PyDateTime_DateTimeTZType); From tim_one@users.sourceforge.net Wed Jan 8 20:51:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 08 Jan 2003 12:51:41 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv10350/python/Modules Modified Files: datetimemodule.c Log Message: Deleted pickle/unpickle code for the old datetime and time classes -- it's unreachable now. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** datetimemodule.c 8 Jan 2003 20:40:01 -0000 1.34 --- datetimemodule.c 8 Jan 2003 20:51:36 -0000 1.35 *************** *** 1400,1407 **** /* Callables to support unpickling. */ static PyObject *date_unpickler_object = NULL; - static PyObject *datetime_unpickler_object = NULL; static PyObject *datetimetz_unpickler_object = NULL; static PyObject *tzinfo_unpickler_object = NULL; - static PyObject *time_unpickler_object = NULL; static PyObject *timetz_unpickler_object = NULL; --- 1400,1405 ---- *************** *** 3381,3430 **** } - /* XXX This seems a ridiculously inefficient way to pickle a short string. */ - static PyObject * - datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime) - { - PyObject *state; - PyObject *result = NULL; - - if (! PyDateTime_CheckExact(datetime)) { - PyErr_Format(PyExc_TypeError, - "bad type passed to datetime pickler: %s", - datetime->ob_type->tp_name); - return NULL; - } - state = datetime_getstate(datetime); - if (state) { - result = Py_BuildValue("O(O)", - datetime_unpickler_object, - state); - Py_DECREF(state); - } - return result; - } - - static PyObject * - datetime_unpickler(PyObject *module, PyObject *arg) - { - PyDateTime_DateTime *self; - - if (! PyString_CheckExact(arg)) { - PyErr_Format(PyExc_TypeError, - "bad type passed to datetime unpickler: %s", - arg->ob_type->tp_name); - return NULL; - } - self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType); - if (self != NULL) { - PyObject *res = datetime_setstate(self, arg); - if (res == NULL) { - Py_DECREF(self); - return NULL; - } - Py_DECREF(res); - } - return (PyObject *)self; - } - static PyMethodDef datetime_methods[] = { /* Class methods: */ --- 3379,3382 ---- *************** *** 3850,3899 **** } - /* XXX This seems a ridiculously inefficient way to pickle a short string. */ - static PyObject * - time_pickler(PyObject *module, PyDateTime_Time *time) - { - PyObject *state; - PyObject *result = NULL; - - if (! PyTime_CheckExact(time)) { - PyErr_Format(PyExc_TypeError, - "bad type passed to time pickler: %s", - time->ob_type->tp_name); - return NULL; - } - state = time_getstate(time); - if (state) { - result = Py_BuildValue("O(O)", - time_unpickler_object, - state); - Py_DECREF(state); - } - return result; - } - - static PyObject * - time_unpickler(PyObject *module, PyObject *arg) - { - PyDateTime_Time *self; - - if (! PyString_CheckExact(arg)) { - PyErr_Format(PyExc_TypeError, - "bad type passed to time unpickler: %s", - arg->ob_type->tp_name); - return NULL; - } - self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType); - if (self != NULL) { - PyObject *res = time_setstate(self, arg); - if (res == NULL) { - Py_DECREF(self); - return NULL; - } - Py_DECREF(res); - } - return (PyObject *)self; - } - static PyMethodDef time_methods[] = { {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS, --- 3802,3805 ---- *************** *** 5171,5180 **** {"_date_pickler", (PyCFunction)date_pickler, METH_O, NULL}, {"_date_unpickler", (PyCFunction)date_unpickler, METH_O, NULL}, - {"_datetime_pickler", (PyCFunction)datetime_pickler, METH_O, NULL}, - {"_datetime_unpickler", (PyCFunction)datetime_unpickler,METH_O, NULL}, {"_datetimetz_pickler", (PyCFunction)datetimetz_pickler,METH_O, NULL}, {"_datetimetz_unpickler",(PyCFunction)datetimetz_unpickler,METH_O, NULL}, - {"_time_pickler", (PyCFunction)time_pickler, METH_O, NULL}, - {"_time_unpickler", (PyCFunction)time_unpickler, METH_O, NULL}, {"_timetz_pickler", (PyCFunction)timetz_pickler, METH_O, NULL}, {"_timetz_unpickler", (PyCFunction)timetz_unpickler, METH_O, NULL}, --- 5077,5082 ---- *************** *** 5237,5266 **** Py_DECREF(pickler); - pickler = PyObject_GetAttrString(m, "_datetime_pickler"); - if (pickler == NULL) return; - datetime_unpickler_object = PyObject_GetAttrString(m, - "_datetime_unpickler"); - if (datetime_unpickler_object == NULL) return; - x = PyObject_CallMethod(copyreg, "pickle", "OOO", - &PyDateTime_DateTimeType, - pickler, - datetime_unpickler_object); - if (x == NULL) return; - Py_DECREF(x); - Py_DECREF(pickler); - - pickler = PyObject_GetAttrString(m, "_time_pickler"); - if (pickler == NULL) return; - time_unpickler_object = PyObject_GetAttrString(m, - "_time_unpickler"); - if (time_unpickler_object == NULL) return; - x = PyObject_CallMethod(copyreg, "pickle", "OOO", - &PyDateTime_TimeType, - pickler, - time_unpickler_object); - if (x == NULL) return; - Py_DECREF(x); - Py_DECREF(pickler); - pickler = PyObject_GetAttrString(m, "_timetz_pickler"); if (pickler == NULL) return; --- 5139,5142 ---- *************** *** 5340,5379 **** x = new_delta(1, 0, 0, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return; - Py_DECREF(x); - - /* datetime values */ - d = PyDateTime_DateTimeType.tp_dict; - - x = new_datetime(1, 1, 1, 0, 0, 0, 0); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return; - Py_DECREF(x); - - x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return; - Py_DECREF(x); - - x = new_delta(0, 0, 1, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return; - Py_DECREF(x); - - /* time values */ - d = PyDateTime_TimeType.tp_dict; - - x = new_time(0, 0, 0, 0); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return; - Py_DECREF(x); - - x = new_time(23, 59, 59, 999999); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return; - Py_DECREF(x); - - x = new_delta(0, 0, 1, 0); if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) return; --- 5216,5219 ---- From holdenweb@users.sourceforge.net Wed Jan 8 21:17:52 2003 From: holdenweb@users.sourceforge.net (holdenweb@users.sourceforge.net) Date: Wed, 08 Jan 2003 13:17:52 -0800 Subject: [Python-checkins] python/dist/src/Lib CGIHTTPServer.py,1.20.8.3,1.20.8.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv17400 Modified Files: Tag: release22-maint CGIHTTPServer.py Log Message: Retrospectively fix code to handle IE's additional characters on certain web transactions more gracefully (through a fairly ugly hack). See bugs 430610 and 427345. Index: CGIHTTPServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/CGIHTTPServer.py,v retrieving revision 1.20.8.3 retrieving revision 1.20.8.4 diff -C2 -d -r1.20.8.3 -r1.20.8.4 *** CGIHTTPServer.py 20 Aug 2002 23:59:33 -0000 1.20.8.3 --- CGIHTTPServer.py 8 Jan 2003 21:17:35 -0000 1.20.8.4 *************** *** 27,30 **** --- 27,31 ---- import BaseHTTPServer import SimpleHTTPServer + import select *************** *** 200,203 **** --- 201,207 ---- # Parent pid, sts = os.waitpid(pid, 0) + # throw away additional data [see bug #427345] + while select.select([self.rfile], [], [], 0)[0]: + waste = self.rfile.read(1) if sts: self.log_error("CGI script exit status %#x", sts) *************** *** 245,248 **** --- 249,255 ---- data = self.rfile.read(nbytes) fi.write(data) + # throw away additional data [see bug #427345] + while select.select([self.rfile._sock], [], [], 0)[0]: + waste = self.rfile._sock.recv(1) fi.close() shutil.copyfileobj(fo, self.wfile) From tim_one@users.sourceforge.net Wed Jan 8 21:21:03 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 08 Jan 2003 13:21:03 -0800 Subject: [Python-checkins] python/dist/src/Lib os.py,1.64,1.65 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19631/python/Lib Modified Files: os.py Log Message: SF patch 661583: Remove old code from lib\os.py A patch from Andrew Wilkinson to change some bizarre old exec statements specific to NT and CE. Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** os.py 8 Jan 2003 16:33:40 -0000 1.64 --- os.py 8 Jan 2003 21:20:57 -0000 1.65 *************** *** 62,70 **** defpath = '.;C:\\bin' from nt import * ! for i in ['_exit']: ! try: ! exec "from nt import " + i ! except ImportError: ! pass import ntpath path = ntpath --- 62,69 ---- defpath = '.;C:\\bin' from nt import * ! try: ! from nt import _exit ! except ImportError: ! pass import ntpath path = ntpath *************** *** 128,136 **** defpath = '\\Windows' from ce import * ! for i in ['_exit']: ! try: ! exec "from ce import " + i ! except ImportError: ! pass # We can use the standard Windows path. import ntpath --- 127,134 ---- defpath = '\\Windows' from ce import * ! try: ! from ce import _exit ! except ImportError: ! pass # We can use the standard Windows path. import ntpath From doerwalter@users.sourceforge.net Wed Jan 8 22:01:51 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Wed, 08 Jan 2003 14:01:51 -0800 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c,2.177,2.178 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv4164/Objects Modified Files: unicodeobject.c Log Message: Fix charmapencode_lookup(), so that a None value in the mapping is treated as "character maps to " and not as "character mapping must return integer, None or str". Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.177 retrieving revision 2.178 diff -C2 -d -r2.177 -r2.178 *** unicodeobject.c 8 Jan 2003 20:38:39 -0000 2.177 --- unicodeobject.c 8 Jan 2003 22:01:33 -0000 2.178 *************** *** 2737,2740 **** --- 2737,2742 ---- return NULL; } + else if (x == Py_None) + return x; else if (PyInt_Check(x)) { long value = PyInt_AS_LONG(x); From guido@python.org Wed Jan 8 22:07:41 2003 From: guido@python.org (Guido van Rossum) Date: Wed, 08 Jan 2003 17:07:41 -0500 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c,2.176,2.177 In-Reply-To: Your message of "Wed, 08 Jan 2003 12:38:45 PST." References: Message-ID: <200301082207.h08M7gS12857@pcp02138704pcs.reston01.va.comcast.net> > Modified Files: > unicodeobject.c > Log Message: > Remove variable owned from PyUnicode_FromEncodedObject, which is unused > (except for Py_DECREF calls) since the introduction of __unicode__. > > > Index: unicodeobject.c > =================================================================== > RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v > retrieving revision 2.176 > retrieving revision 2.177 > diff -C2 -d -r2.176 -r2.177 > *** unicodeobject.c 29 Dec 2002 19:44:06 -0000 2.176 > --- unicodeobject.c 8 Jan 2003 20:38:39 -0000 2.177 > *************** > *** 453,457 **** > const char *s = NULL; > int len; > - int owned = 0; > PyObject *v; > > --- 453,456 ---- > *************** > *** 511,523 **** > v = PyUnicode_Decode(s, len, encoding, errors); > > - if (owned) { > - Py_DECREF(obj); > - } > return v; > > onError: > - if (owned) { > - Py_DECREF(obj); > - } > return NULL; > } > --- 510,516 ---- Are you sure that the real problem isn't that the assignment owned = 1; somewhere got lost? --Guido van Rossum (home page: http://www.python.org/~guido/) From walter@livinglogic.de Wed Jan 8 22:22:27 2003 From: walter@livinglogic.de (=?ISO-8859-15?Q?Walter_D=F6rwald?=) Date: Wed, 08 Jan 2003 23:22:27 +0100 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c,2.176,2.177 In-Reply-To: <200301082207.h08M7gS12857@pcp02138704pcs.reston01.va.comcast.net> References: <200301082207.h08M7gS12857@pcp02138704pcs.reston01.va.comcast.net> Message-ID: <3E1CA4A3.3010900@livinglogic.de> Guido van Rossum wrote: >>Modified Files: >> unicodeobject.c >>Log Message: >>Remove variable owned from PyUnicode_FromEncodedObject, which is unused >>(except for Py_DECREF calls) since the introduction of __unicode__. > > [...] > > Are you sure that the real problem isn't that the assignment > > owned = 1; > > somewhere got lost? If I interpret the CVS correctly, owned was introduced in 2.40 by MAL to deal with classes that implement __str__. After it was decided that unicode conversion was to be done via __unicode__, the code branch that had owned = 1 was removed by you (using MAL patch #470578) in revision 2.119, so I'm pretty sure owned no longer has any use. Bye, Walter Dörwald From doerwalter@users.sourceforge.net Wed Jan 8 23:02:40 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Wed, 08 Jan 2003 15:02:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_unicode.py,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv26335/Lib/test Modified Files: test_unicode.py Log Message: Add a test that exercises the error handling part of PyUnicode_EncodeDecimal(). Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** test_unicode.py 29 Dec 2002 19:44:06 -0000 1.74 --- test_unicode.py 8 Jan 2003 23:02:34 -0000 1.75 *************** *** 680,683 **** --- 680,689 ---- else: raise TestFailed, '"\\".decode("unicode-escape") should fail' + try: + int(u"\u0200") + except UnicodeError: + pass + else: + raise TestFailed, "int(u'\\u0200') failed to raise an exception" verify(u'hello'.encode('ascii') == 'hello') From doerwalter@users.sourceforge.net Wed Jan 8 23:22:17 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Wed, 08 Jan 2003 15:22:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_codeccallbacks.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv31654/Lib/test Modified Files: test_codeccallbacks.py Log Message: Add a few test cases to increase code coverage: From: 69.73% of 294 source lines executed in file ./Modules/_codecsmodule.c 79.47% of 487 source lines executed in file Python/codecs.c 78.45% of 3643 source lines executed in file Objects/unicodeobject.c To: 70.41% of 294 source lines executed in file ./Modules/_codecsmodule.c 82.75% of 487 source lines executed in file Python/codecs.c 80.76% of 3638 source lines executed in file Objects/unicodeobject.c This actually unearthed a bug in the handling of None values in PyUnicode_EncodeCharmap. Index: test_codeccallbacks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codeccallbacks.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_codeccallbacks.py 25 Nov 2002 17:58:02 -0000 1.5 --- test_codeccallbacks.py 8 Jan 2003 23:22:13 -0000 1.6 *************** *** 490,493 **** --- 490,608 ---- ) + def test_badregistercall(self): + # enhance coverage of: + # Modules/_codecsmodule.c::register_error() + # Python/codecs.c::PyCodec_RegisterError() + self.assertRaises(TypeError, codecs.register_error, 42) + self.assertRaises(TypeError, codecs.register_error, "test.dummy", 42) + + def test_unknownhandler(self): + # enhance coverage of: + # Modules/_codecsmodule.c::lookup_error() + self.assertRaises(LookupError, codecs.lookup_error, "test.unknown") + + def test_xmlcharrefvalues(self): + # enhance coverage of: + # Python/codecs.c::PyCodec_XMLCharRefReplaceErrors() + # and inline implementations + v = (1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000) + if sys.maxunicode>50000: + v += (100000, 500000, 1000000) + s = u"".join([unichr(x) for x in v]) + codecs.register_error("test.xmlcharrefreplace", codecs.xmlcharrefreplace_errors) + for enc in ("ascii", "iso-8859-15"): + for err in ("xmlcharrefreplace", "test.xmlcharrefreplace"): + s.encode(enc, err) + + def test_decodehelper(self): + # enhance coverage of: + # Objects/unicodeobject.c::unicode_decode_call_errorhandler() + # and callers + self.assertRaises(LookupError, "\xff".decode, "ascii", "test.unknown") + + def baddecodereturn1(exc): + return 42 + codecs.register_error("test.baddecodereturn1", baddecodereturn1) + self.assertRaises(TypeError, "\xff".decode, "ascii", "test.baddecodereturn1") + self.assertRaises(TypeError, "\\".decode, "unicode-escape", "test.baddecodereturn1") + self.assertRaises(TypeError, "\\x0".decode, "unicode-escape", "test.baddecodereturn1") + self.assertRaises(TypeError, "\\x0y".decode, "unicode-escape", "test.baddecodereturn1") + self.assertRaises(TypeError, "\\Uffffeeee".decode, "unicode-escape", "test.baddecodereturn1") + self.assertRaises(TypeError, "\\uyyyy".decode, "raw-unicode-escape", "test.baddecodereturn1") + + def baddecodereturn2(exc): + return (u"?", None) + codecs.register_error("test.baddecodereturn2", baddecodereturn2) + self.assertRaises(TypeError, "\xff".decode, "ascii", "test.baddecodereturn2") + + pos = [-42] + def negposreturn(exc): + pos[0] += 1 # use list to work around scoping problem + return (u"?", pos[0]) + codecs.register_error("test.negposreturn", negposreturn) + "\xff".decode("ascii", "test.negposreturn") + + def hugeposreturn(exc): + return (u"?", 424242) + codecs.register_error("test.hugeposreturn", hugeposreturn) + "\xff".decode("ascii", "test.hugeposreturn") + "\\uyyyy".decode("raw-unicode-escape", "test.hugeposreturn") + + class D(dict): + def __getitem__(self, key): + raise ValueError + self.assertRaises(UnicodeError, codecs.charmap_decode, "\xff", "strict", {0xff: None}) + self.assertRaises(ValueError, codecs.charmap_decode, "\xff", "strict", D()) + self.assertRaises(TypeError, codecs.charmap_decode, "\xff", "strict", {0xff: sys.maxunicode+1}) + + def test_encodehelper(self): + # enhance coverage of: + # Objects/unicodeobject.c::unicode_encode_call_errorhandler() + # and callers + self.assertRaises(LookupError, u"\xff".encode, "ascii", "test.unknown") + + def badencodereturn1(exc): + return 42 + codecs.register_error("test.badencodereturn1", badencodereturn1) + self.assertRaises(TypeError, u"\xff".encode, "ascii", "test.badencodereturn1") + + def badencodereturn2(exc): + return (u"?", None) + codecs.register_error("test.badencodereturn2", badencodereturn2) + self.assertRaises(TypeError, u"\xff".encode, "ascii", "test.badencodereturn2") + + pos = [-42] + def negposreturn(exc): + pos[0] += 1 # use list to work around scoping problem + return (u"?", pos[0]) + codecs.register_error("test.negposreturn", negposreturn) + u"\xff".encode("ascii", "test.negposreturn") + + def hugeposreturn(exc): + return (u"?", 424242) + codecs.register_error("test.hugeposreturn", hugeposreturn) + u"\xff".encode("ascii", "test.hugeposreturn") + + class D(dict): + def __getitem__(self, key): + raise ValueError + for err in ("strict", "replace", "xmlcharrefreplace", "backslashreplace", "test.hugeposreturn"): + self.assertRaises(UnicodeError, codecs.charmap_encode, u"\xff", err, {0xff: None}) + self.assertRaises(ValueError, codecs.charmap_encode, u"\xff", err, D()) + self.assertRaises(TypeError, codecs.charmap_encode, u"\xff", err, {0xff: 300}) + + def test_translatehelper(self): + # enhance coverage of: + # Objects/unicodeobject.c::unicode_encode_call_errorhandler() + # and callers + # (Unfortunately the errors argument is not directly accessible + # from Python, so we can't test that much) + class D(dict): + def __getitem__(self, key): + raise ValueError + self.assertRaises(ValueError, u"\xff".translate, D()) + self.assertRaises(TypeError, u"\xff".translate, {0xff: sys.maxunicode+1}) + self.assertRaises(TypeError, u"\xff".translate, {0xff: ()}) + def test_main(): suite = unittest.TestSuite() From tim_one@users.sourceforge.net Thu Jan 9 04:10:07 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 08 Jan 2003 20:10:07 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv8938/python/Doc/lib Modified Files: libdatetime.tex Log Message: Massive fiddling to reflect that datetimetz and timetz no longer exist. WARNING: It would be a minor miracle if the LaTeX stuff still worked. s/field/member/ generally everywhere, to conform with most other usage in the docs. s/daylight savings time/daylight saving time/ generally everywhere, because the latter spelling is anally correct. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** libdatetime.tex 6 Jan 2003 15:03:11 -0000 1.31 --- libdatetime.tex 9 Jan 2003 04:10:05 -0000 1.32 *************** *** 17,26 **** and times in both simple and complex ways. While date and time arithmetic is supported, the focus of the implementation is on ! efficient field extraction, for output formatting and manipulation. There are two kinds of date and time objects: ``naive'' and ``aware''. This distinction refers to whether the object has any notion of time ! zone, daylight savings time, or other kind of algorithmic or political ! time adjustment. Whether a {naive} \class{datetime} object represents Coordinated Universal Time (UTC), local time, or time in some other timezone is purely up to the program, just like it's up to the program [...1421 lines suppressed...] \subsection{\method{strftime()} Behavior} ! \class{date}, \class{datetime}, and \class{time} ! objects all support a \code{strftime(\var{format})} method, to create a string representing the time under the control of an explicit format string. Broadly speaking, *************** *** 1466,1470 **** although not all objects support a \method{timetuple()} method. ! For \class{time} and \class{timetz} objects, the format codes for year, month, and day should not be used, as time objects have no such values. If they're used anyway, \code{1900} is substituted for the --- 1176,1180 ---- although not all objects support a \method{timetuple()} method. ! For \class{time} objects, the format codes for year, month, and day should not be used, as time objects have no such values. If they're used anyway, \code{1900} is substituted for the From gvanrossum@users.sourceforge.net Thu Jan 9 05:43:10 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 08 Jan 2003 21:43:10 -0800 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.34.2.6,1.34.2.7 urlparse.py,1.29.4.1,1.29.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv1803 Modified Files: Tag: release21-maint httplib.py urlparse.py Log Message: Roll back the introduction of urlsplit() and urlunsplit() to urlparse.py. These were new features in 2.2, and shouldn't be added to 2.1 this late in the game. There was one use of urlsplit() in httplib.py (the urlparse.py change was done as part of a backport of a bugfix to httplib.py); this use is replaced with a call to urlparse() without changing the effect (only the returned netloc is used). Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.34.2.6 retrieving revision 1.34.2.7 diff -C2 -d -r1.34.2.6 -r1.34.2.7 *** httplib.py 29 Aug 2002 20:12:26 -0000 1.34.2.6 --- httplib.py 9 Jan 2003 05:43:08 -0000 1.34.2.7 *************** *** 70,74 **** import mimetools import socket ! from urlparse import urlsplit try: --- 70,74 ---- import mimetools import socket ! from urlparse import urlparse try: *************** *** 611,615 **** netloc = '' if url.startswith('http'): ! nil, netloc, nil, nil, nil = urlsplit(url) if netloc: --- 611,615 ---- netloc = '' if url.startswith('http'): ! nil, netloc, nil, nil, nil, nil = urlparse(url) if netloc: Index: urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urlparse.py,v retrieving revision 1.29.4.1 retrieving revision 1.29.4.2 diff -C2 -d -r1.29.4.1 -r1.29.4.2 *** urlparse.py 2 Jul 2002 20:42:50 -0000 1.29.4.1 --- urlparse.py 9 Jan 2003 05:43:08 -0000 1.29.4.2 *************** *** 44,48 **** ! def urlparse(url, scheme='', allow_fragments=1): """Parse a URL into 6 components: :///;?# --- 44,48 ---- ! def urlparse(url, scheme = '', allow_fragments = 1): """Parse a URL into 6 components: :///;?# *************** *** 50,76 **** Note that we don't break the components up in smaller bits (e.g. netloc is a single string) and we don't expand % escapes.""" - tuple = urlsplit(url, scheme, allow_fragments) - scheme, netloc, url, query, fragment = tuple - if scheme in uses_params and ';' in url: - url, params = _splitparams(url) - else: - params = '' - return scheme, netloc, url, params, query, fragment - - def _splitparams(url): - if '/' in url: - i = url.find(';', url.rfind('/')) - if i < 0: - return url, '' - else: - i = url.find(';') - return url[:i], url[i+1:] - - def urlsplit(url, scheme='', allow_fragments=1): - """Parse a URL into 5 components: - :///?# - Return a 5-tuple: (scheme, netloc, path, query, fragment). - Note that we don't break the components up in smaller bits - (e.g. netloc is a single string) and we don't expand % escapes.""" key = url, scheme, allow_fragments cached = _parse_cache.get(key, None) --- 50,53 ---- *************** *** 79,83 **** if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth clear_cache() ! netloc = query = fragment = '' i = url.find(':') if i > 0: --- 56,60 ---- if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth clear_cache() ! netloc = path = params = query = fragment = '' i = url.find(':') if i > 0: *************** *** 88,101 **** i = url.find('/', 2) if i < 0: ! i = url.find('#') ! if i < 0: ! i = len(url) netloc = url[2:i] url = url[i:] ! if allow_fragments and '#' in url: ! url, fragment = url.split('#', 1) ! if '?' in url: ! url, query = url.split('?', 1) ! tuple = scheme, netloc, url, query, fragment _parse_cache[key] = tuple return tuple --- 65,85 ---- i = url.find('/', 2) if i < 0: ! i = len(url) netloc = url[2:i] url = url[i:] ! if allow_fragments: ! i = url.rfind('#') ! if i >= 0: ! fragment = url[i+1:] ! url = url[:i] ! i = url.find('?') ! if i >= 0: ! query = url[i+1:] ! url = url[:i] ! i = url.find(';') ! if i >= 0: ! params = url[i+1:] ! url = url[:i] ! tuple = scheme, netloc, url, params, query, fragment _parse_cache[key] = tuple return tuple *************** *** 111,119 **** i = len(url) netloc, url = url[2:i], url[i:] ! if allow_fragments and scheme in uses_fragment and '#' in url: ! url, fragment = url.split('#', 1) ! if scheme in uses_query and '?' in url: ! url, query = url.split('?', 1) ! tuple = scheme, netloc, url, query, fragment _parse_cache[key] = tuple return tuple --- 95,111 ---- i = len(url) netloc, url = url[2:i], url[i:] ! if allow_fragments and scheme in uses_fragment: ! i = url.rfind('#') ! if i >= 0: ! url, fragment = url[:i], url[i+1:] ! if scheme in uses_query: ! i = url.find('?') ! if i >= 0: ! url, query = url[:i], url[i+1:] ! if scheme in uses_params: ! i = url.find(';') ! if i >= 0: ! url, params = url[:i], url[i+1:] ! tuple = scheme, netloc, url, params, query, fragment _parse_cache[key] = tuple return tuple *************** *** 124,132 **** originally had redundant delimiters, e.g. a ? with an empty query (the draft states that these are equivalent).""" - if params: - url = "%s;%s" % (url, params) - return urlunsplit((scheme, netloc, url, query, fragment)) - - def urlunsplit((scheme, netloc, url, query, fragment)): if netloc or (scheme in uses_netloc and url[:2] == '//'): if url and url[:1] != '/': url = '/' + url --- 116,119 ---- *************** *** 134,137 **** --- 121,126 ---- if scheme: url = scheme + ':' + url + if params: + url = url + ';' + params if query: url = url + '?' + query *************** *** 199,208 **** empty string. """ ! if '#' in url: ! s, n, p, a, q, frag = urlparse(url) ! defrag = urlunparse((s, n, p, a, q, '')) ! return defrag, frag ! else: ! return url, '' --- 188,194 ---- empty string. """ ! s, n, p, a, q, frag = urlparse(url) ! defrag = urlunparse((s, n, p, a, q, '')) ! return defrag, frag From gvanrossum@users.sourceforge.net Thu Jan 9 06:12:50 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 08 Jan 2003 22:12:50 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.146.2.18,1.146.2.19 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv10036 Modified Files: Tag: release21-maint NEWS Log Message: Complete list of news since 2.1.3 was release. Just in case I feel like releasing 2.1.4 tomorrow. :-) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.146.2.18 retrieving revision 1.146.2.19 diff -C2 -d -r1.146.2.18 -r1.146.2.19 *** NEWS 17 Apr 2002 04:36:15 -0000 1.146.2.18 --- NEWS 9 Jan 2003 06:12:47 -0000 1.146.2.19 *************** *** 1,2 **** --- 1,56 ---- + What's New in Python 2.1.4? + Release date: XX-XXX-2003 + =========================== + + - Some documentation fixes. + + - SF #577530, #533625: security fixes for rexec.py. I still wouldn't + trust it as the only line of defense between a machine and the + Internet! + + - SF #590294, #601077: os._execvpe security fix (plus fix for the fix). + + - Link errno extension statically. + + - Backported various httplib.py fixes. + + - Backported various SSL fixes. + + - Fix posixpath.py so that when stat() fails with EOVERFLOW (meaning a + file larger than 2 GB in a build that doesn't support LFS), this is + correctly taken as an indication of the file's existence. + + - SF #523473: raise exceptions on error conditions. + + - SF #561858: avoid assertion when writing code objects with stacksize + >= 2**16. + + - SF #210682: fixed an old bug that caused bdb to be unable to + continue in the bottom frame, after a breakpoint was set + + - Fix rfc822.py to support dots in the "real name" part of email + addresses, per RFC 2822. + + - Repaired widespread misuse of _PyString_Resize. + + - SF #544473: use try/finally to ensire all Queue locks remain stable. + + - Fixed two obscure bugs in nested scopes. + + - Changes to the configure script to avoid problems with binutils 2.12. + + - SF #543318: fix bogus initialization in DatagramRequestHandler.setup(). + + - SF #541730: provisional fix to IDLE for losing data when attempting + to save a file containing non-ASCII characters. The fix consists of + raising an exception *before* overwriting the file rather than + after. You still can't save files with non-ASCII characters (this + is fixed in Python 2.2). + + - Sometimes the uninstall executable (UNWISE.EXE) vanishes. One cause + of that has been fixed in the installer (disabled Wise's "delete in- + use files" uninstall option). + + What's New in Python 2.1.3? Release date: 08-April-2002 *************** *** 27,34 **** Windows - - - Sometimes the uninstall executable (UNWISE.EXE) vanishes. One cause - of that has been fixed in the installer (disabled Wise's "delete in- - use files" uninstall option). - The installer now installs Start menu shortcuts under (the local --- 81,84 ---- From gvanrossum@users.sourceforge.net Thu Jan 9 06:37:29 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 08 Jan 2003 22:37:29 -0800 Subject: [Python-checkins] python/dist/src/Include patchlevel.h,2.49.2.8,2.49.2.9 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv15381 Modified Files: Tag: release21-maint patchlevel.h Log Message: Change string version to "2.1.3+". Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.49.2.8 retrieving revision 2.49.2.9 diff -C2 -d -r2.49.2.8 -r2.49.2.9 *** patchlevel.h 8 Apr 2002 06:05:49 -0000 2.49.2.8 --- patchlevel.h 9 Jan 2003 06:37:25 -0000 2.49.2.9 *************** *** 27,34 **** /* Version as a string */ ! #define PY_VERSION "2.1.3" /* Historic */ ! #define PATCHLEVEL "2.1.3" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 27,34 ---- /* Version as a string */ ! #define PY_VERSION "2.1.3+" /* Historic */ ! #define PATCHLEVEL "2.1.3+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From jvr@users.sourceforge.net Thu Jan 9 10:47:22 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 09 Jan 2003 02:47:22 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac buildtools.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv31289 Modified Files: buildtools.py Log Message: add newline to source before compilation Index: buildtools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/buildtools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** buildtools.py 30 Dec 2002 22:04:20 -0000 1.1 --- buildtools.py 9 Jan 2003 10:47:20 -0000 1.2 *************** *** 86,90 **** fp.close() try: ! code = compile(text, filename, "exec") except SyntaxError, arg: raise BuildError, "Syntax error in script %s: %s" % (filename, arg) --- 86,90 ---- fp.close() try: ! code = compile(text + '\n', filename, "exec") except SyntaxError, arg: raise BuildError, "Syntax error in script %s: %s" % (filename, arg) From doerwalter@users.sourceforge.net Thu Jan 9 11:38:52 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Thu, 09 Jan 2003 03:38:52 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_codeccallbacks.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv18201/Lib/test Modified Files: test_codeccallbacks.py Log Message: Make the test scripts work again with narrow Python builds. Index: test_codeccallbacks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codeccallbacks.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_codeccallbacks.py 8 Jan 2003 23:22:13 -0000 1.6 --- test_codeccallbacks.py 9 Jan 2003 11:38:50 -0000 1.7 *************** *** 507,511 **** # and inline implementations v = (1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000) ! if sys.maxunicode>50000: v += (100000, 500000, 1000000) s = u"".join([unichr(x) for x in v]) --- 507,511 ---- # and inline implementations v = (1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000) ! if sys.maxunicode>=100000: v += (100000, 500000, 1000000) s = u"".join([unichr(x) for x in v]) From akuchling@users.sourceforge.net Thu Jan 9 12:51:52 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 09 Jan 2003 04:51:52 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv5476 Modified Files: libdatetime.tex Log Message: Markup fix Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** libdatetime.tex 9 Jan 2003 04:10:05 -0000 1.32 --- libdatetime.tex 9 Jan 2003 12:51:50 -0000 1.33 *************** *** 305,308 **** --- 305,309 ---- seconds in their notion of a timestamp, leap seconds are ignored by \method{fromtimestamp()}. + \end{methoddesc} \begin{methoddesc}{fromordinal}{ordinal} From akuchling@users.sourceforge.net Thu Jan 9 13:46:32 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Thu, 09 Jan 2003 05:46:32 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv32281 Modified Files: libdatetime.tex Log Message: Various minor edits Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** libdatetime.tex 9 Jan 2003 12:51:50 -0000 1.33 --- libdatetime.tex 9 Jan 2003 13:46:30 -0000 1.34 *************** *** 17,21 **** and times in both simple and complex ways. While date and time arithmetic is supported, the focus of the implementation is on ! efficient member extraction, for output formatting and manipulation. There are two kinds of date and time objects: ``naive'' and ``aware''. --- 17,21 ---- and times in both simple and complex ways. While date and time arithmetic is supported, the focus of the implementation is on ! efficient member extraction for output formatting and manipulation. There are two kinds of date and time objects: ``naive'' and ``aware''. *************** *** 29,41 **** the cost of ignoring some aspects of reality. ! For applications requiring more, \class{datetime} and \class{time} objects ! have an optional time zone information member. ! These \class{tzinfo} objects capture information about the offset from ! UTC time, the time zone name, and whether Daylight Saving Time is in ! effect. Note that no concrete \class{tzinfo} classes are supplied by ! the \module{datetime} module. Instead, they provide a framework for ! incorporating the level of detail an app may require. The rules for ! time adjustment across the world are more political than rational, and ! there is no standard suitable for every app. The \module{datetime} module exports the following constants: --- 29,43 ---- the cost of ignoring some aspects of reality. ! For applications requiring more, \class{datetime} and \class{time} ! objects have an optional time zone information member, ! \member{tzinfo}, that can contain an instance of a subclass of ! the abstract \class{tzinfo} class. These \class{tzinfo} objects ! capture information about the offset from UTC time, the time zone ! name, and whether Daylight Saving Time is in effect. Note that no ! concrete \class{tzinfo} classes are supplied by the \module{datetime} ! module. Instead, they provide a framework for incorporating the level ! of detail an application may require. The rules for time adjustment across ! the world are more political than rational, and there is no standard ! suitable for every application. The \module{datetime} module exports the following constants: *************** *** 74,78 **** \begin{classdesc*}{datetime} ! A combination of a naive date and a time. Attributes: \member{year}, \member{month}, \member{day}, \member{hour}, \member{minute}, \member{second}, --- 76,80 ---- \begin{classdesc*}{datetime} ! A combination of a date and a time. Attributes: \member{year}, \member{month}, \member{day}, \member{hour}, \member{minute}, \member{second}, *************** *** 81,86 **** \begin{classdesc*}{timedelta} ! A duration, expressing the difference between two \class{date}, ! \class{time}, or \class{datetime} instances, to microsecond resolution. \end{classdesc*} --- 83,88 ---- \begin{classdesc*}{timedelta} ! A duration expressing the difference between two \class{date}, ! \class{time}, or \class{datetime} instances to microsecond resolution. \end{classdesc*} *************** *** 89,93 **** An abstract base class for time zone information objects. These are used by the \class{datetime} and \class{time} classes to ! provided a customizable notion of time adjustment (for example, to account for time zone and/or daylight saving time). \end{classdesc*} --- 91,95 ---- An abstract base class for time zone information objects. These are used by the \class{datetime} and \class{time} classes to ! provide a customizable notion of time adjustment (for example, to account for time zone and/or daylight saving time). \end{classdesc*} *************** *** 99,103 **** An object \var{d} of type \class{time} or \class{datetime} may be naive or aware. \var{d} is aware if \code{\var{d}.tzinfo} is not ! \code{None}, and \code{\var{d}.tzinfo.utcoffset(\var{d})} does not return \code{None}. If \code{\var{d}.tzinfo} is \code{None}, or if \code{\var{d}.tzinfo} is not \code{None} but --- 101,105 ---- An object \var{d} of type \class{time} or \class{datetime} may be naive or aware. \var{d} is aware if \code{\var{d}.tzinfo} is not ! \code{None} and \code{\var{d}.tzinfo.utcoffset(\var{d})} does not return \code{None}. If \code{\var{d}.tzinfo} is \code{None}, or if \code{\var{d}.tzinfo} is not \code{None} but *************** *** 133,142 **** internally. Arguments are converted to those units: ! \begin{verbatim} ! A millisecond is converted to 1000 microseconds. ! A minute is converted to 60 seconds. ! An hour is converted to 3600 seconds. ! A week is converted to 7 days. ! \end{verbatim} and days, seconds and microseconds are then normalized so that the --- 135,144 ---- internally. Arguments are converted to those units: ! \begin{itemize} ! \item A millisecond is converted to 1000 microseconds. ! \item A minute is converted to 60 seconds. ! \item An hour is converted to 3600 seconds. ! \item A week is converted to 7 days. ! \end{itemize} and days, seconds and microseconds are then normalized so that the *************** *** 149,153 **** \end{itemize} ! If any argument is a float, and there are fractional microseconds, the fractional microseconds left over from all arguments are combined and their sum is rounded to the nearest microsecond. If no --- 151,155 ---- \end{itemize} ! If any argument is a float and there are fractional microseconds, the fractional microseconds left over from all arguments are combined and their sum is rounded to the nearest microsecond. If no *************** *** 200,203 **** --- 202,206 ---- Supported operations: + % XXX this table is too wide! \begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes} \lineiii{\var{t1} = \var{t2} + \var{t3}} *************** *** 225,234 **** \lineiii{-\var{t1}} {equivalent to \class{timedelta}(-\var{t1.days}, -\var{t1.seconds}, ! -\var{t1.microseconds}),and to \var{t1}* -1.} {(1)(4)} \lineiii{abs(\var{t})} {equivalent to +\var{t} when \code{t.days >= 0}, and to ! -\var{t} when \code{t.days < 0}. ! overflow.} {(2)} \end{tableiii} --- 228,236 ---- \lineiii{-\var{t1}} {equivalent to \class{timedelta}(-\var{t1.days}, -\var{t1.seconds}, ! -\var{t1.microseconds}), and to \var{t1}* -1.} {(1)(4)} \lineiii{abs(\var{t})} {equivalent to +\var{t} when \code{t.days >= 0}, and to ! -\var{t} when \code{t.days < 0}.} {(2)} \end{tableiii} *************** *** 258,262 **** to be the smaller timedelta. ! \class{timedelta} objects are hashable (usable as dictionary key), support efficient pickling, and in Boolean contexts, a \class{timedelta} object is considered to be true if and only if it isn't equal to --- 260,264 ---- to be the smaller timedelta. ! \class{timedelta} objects are hashable (usable as dictionary keys), support efficient pickling, and in Boolean contexts, a \class{timedelta} object is considered to be true if and only if it isn't equal to *************** *** 333,337 **** \begin{memberdesc}{year} ! Between \constant{MINYEAR} and \constant{MAXYEAR} inclusive \end{memberdesc} --- 335,339 ---- \begin{memberdesc}{year} ! Between \constant{MINYEAR} and \constant{MAXYEAR} inclusive. \end{memberdesc} *************** *** 347,350 **** --- 349,353 ---- Supported operations: + % XXX rewrite to be a table \begin{itemize} \item From tim_one@users.sourceforge.net Thu Jan 9 19:52:20 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 09 Jan 2003 11:52:20 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib tzinfo-examples.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv18885/python/Doc/lib Modified Files: tzinfo-examples.py Log Message: Purged reference to defunct datetimetz. Index: tzinfo-examples.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/tzinfo-examples.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** tzinfo-examples.py 4 Jan 2003 06:03:14 -0000 1.4 --- tzinfo-examples.py 9 Jan 2003 19:52:17 -0000 1.5 *************** *** 118,122 **** # An exception may be sensible here, in one or both cases. # It depends on how you want to treat them. The astimezone() ! # implementation always passes a datetimetz with # dt.tzinfo == self. return ZERO --- 118,122 ---- # An exception may be sensible here, in one or both cases. # It depends on how you want to treat them. The astimezone() ! # implementation always passes a datetime with # dt.tzinfo == self. return ZERO From rhettinger@users.sourceforge.net Thu Jan 9 15:24:40 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 09 Jan 2003 07:24:40 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.342,2.343 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv9854 Modified Files: ceval.c Log Message: SF patch #664320: Replace push/pop clusters in ceval.c Replaced groups of pushes and pops with indexed access to the stack and a single adjustment (if needed) to the stacklevel. Avoids scores of unnecessary increments and decrements to the stackpointer. Removes unnecessary sequential dependencies so that the compiler has more freedom for optimizations. Frees the processor for more parallel and pipelined execution by using mostly read-only access and having few pointer adjustments just prior to a read or write. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.342 retrieving revision 2.343 diff -C2 -d -r2.342 -r2.343 *** ceval.c 10 Nov 2002 14:33:26 -0000 2.342 --- ceval.c 9 Jan 2003 15:24:30 -0000 2.343 *************** *** 551,554 **** --- 551,564 ---- #define EMPTY() (STACK_LEVEL() == 0) #define TOP() (stack_pointer[-1]) + #define SECOND() (stack_pointer[-2]) + #define THIRD() (stack_pointer[-3]) + #define FOURTH() (stack_pointer[-4]) + #define FIFTH() (stack_pointer[-5]) + #define SET_TOP(v) (stack_pointer[-1] = (v)) + #define SET_SECOND(v) (stack_pointer[-2] = (v)) + #define SET_THIRD(v) (stack_pointer[-3] = (v)) [...1127 lines suppressed...] v = POP(); ! u = POP(); x = PySlice_New(u, v, w); Py_DECREF(u); Py_DECREF(v); Py_XDECREF(w); ! PUSH(x); if (x != NULL) continue; break; --- 2139,2148 ---- w = NULL; v = POP(); ! u = TOP(); x = PySlice_New(u, v, w); Py_DECREF(u); Py_DECREF(v); Py_XDECREF(w); ! SET_TOP(x); if (x != NULL) continue; break; From jvr@users.sourceforge.net Thu Jan 9 22:27:15 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 09 Jan 2003 14:27:15 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_zipimport.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv24797 Modified Files: test_zipimport.py Log Message: cleaned up Jack's Mac OS9 changes Index: test_zipimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zipimport.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_zipimport.py 8 Jan 2003 16:37:03 -0000 1.4 --- test_zipimport.py 9 Jan 2003 22:27:10 -0000 1.5 *************** *** 39,46 **** TESTPACK2 = "ziptestpackage2" TEMP_ZIP = os.path.abspath("junk95142.zip") - if sys.platform == 'mac': - CURDIRPREFIX=':' - else: - CURDIRPREFIX='' class UncompressedZipImportTestCase(ImportHooksBaseTestCase): --- 39,42 ---- *************** *** 69,73 **** file = mod.get_file() self.assertEquals(file, os.path.join(TEMP_ZIP, ! CURDIRPREFIX + os.sep.join(modules) + expected_ext)) finally: z.close() --- 65,69 ---- file = mod.get_file() self.assertEquals(file, os.path.join(TEMP_ZIP, ! *modules) + expected_ext) finally: z.close() From jvr@users.sourceforge.net Thu Jan 9 23:18:42 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 09 Jan 2003 15:18:42 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac FrameWork.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv11929/Lib/plat-mac Modified Files: FrameWork.py Log Message: support unicode in menu items Index: FrameWork.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/FrameWork.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** FrameWork.py 8 Jan 2003 16:32:09 -0000 1.2 --- FrameWork.py 9 Jan 2003 23:18:39 -0000 1.3 *************** *** 562,566 **** self.items.append((label, shortcut, callback, kind)) item = len(self.items) ! self.menu.SetMenuItemText(item, label) # set the actual text if shortcut and type(shortcut) == type(()): modifiers, char = shortcut[:2] --- 562,569 ---- self.items.append((label, shortcut, callback, kind)) item = len(self.items) ! if isinstance(label, unicode): ! self.menu.SetMenuItemTextWithCFString(item, label) ! else: ! self.menu.SetMenuItemText(item, label) if shortcut and type(shortcut) == type(()): modifiers, char = shortcut[:2] From jvr@users.sourceforge.net Thu Jan 9 23:20:34 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 09 Jan 2003 15:20:34 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE Wapplication.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv12502 Modified Files: Wapplication.py Log Message: interpret utf-8 file names on OSX Index: Wapplication.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wapplication.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** Wapplication.py 31 Aug 2002 01:20:53 -0000 1.19 --- Wapplication.py 9 Jan 2003 23:20:31 -0000 1.20 *************** *** 294,297 **** --- 294,299 ---- continue name = string.strip(name) + if os.name == "posix": + name = unicode(name, "utf-8") if name[-3:] == '---': menu.addseparator() From jackjansen@users.sourceforge.net Thu Jan 9 23:37:39 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 09 Jan 2003 15:37:39 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/file filescan.py,1.5,1.6 filesupport.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/file In directory sc8-pr-cvs1:/tmp/cvs-serv18453 Modified Files: filescan.py filesupport.py Log Message: Started on implementing support for FSCatalogInfo. Doesn't work yet, don't try it. Index: filescan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filescan.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** filescan.py 18 Dec 2002 23:17:26 -0000 1.5 --- filescan.py 9 Jan 2003 23:37:36 -0000 1.6 *************** *** 135,140 **** "CatPositionRec", # State variable, not too difficult - "FSCatalogInfo", # Lots of fields, difficult struct - "FSCatalogInfo_ptr", # Lots of fields, difficult struct "FSIterator", # Should become an object "FSForkInfo", # Lots of fields, difficult struct --- 135,138 ---- *************** *** 181,184 **** --- 179,193 ---- ([('FSRef_ptr', 'fromFile', 'InMode')], [('OptFSRefPtr', 'fromFile', 'InMode')]), + + # FSCatalogInfo input handling + ([('FSCatalogInfoBitmap', 'whichInfo', 'InMode'), + ('FSCatalogInfo_ptr', 'catalogInfo', 'InMode')], + [('FSCatalogInfoAndBitmap_in', 'catalogInfo', 'InMode')]), + + # FSCatalogInfo output handling + ([('FSCatalogInfoBitmap', 'whichInfo', 'InMode'), + ('FSCatalogInfo', 'catalogInfo', 'OutMode')], + [('FSCatalogInfoAndBitmap_out', 'catalogInfo', 'InOutMode')]), + ] Index: filesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filesupport.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** filesupport.py 26 Dec 2002 20:45:43 -0000 1.9 --- filesupport.py 9 Jan 2003 23:37:37 -0000 1.10 *************** *** 51,54 **** --- 51,101 ---- Output("%s %s__buf__;", self.typeName, name) Output("%s *%s = &%s__buf__;", self.typeName, name, name) + + class FSCatalogInfoAndBitmapType(InputOnlyType): + + def __init__(self): + InputOnlyType.__init__(self, "BUG", "BUG") + + def declare(self, name): + Output("PyObject *%s__object;", name) + Output("FSCatalogInfoBitname %s__bitmap;", name) + Output("FSCatalogInfo %s;", name) + + def getargsFormat(self): + return "lO" + + def getargsArgs(self, name): + return "%s__bitmap, %s__object"%(name, name) + + def getargsCheck(self, name): + Output("convert_FSCatalogInfo(%s__object, %s__bitmap, %s);", name, name, name) + + def passOutput(self, name): + return "%s__bitmap, %s"% (name, name) + + def mkvalueFormat(self): + return "O" + + def mkvalueArgs(self, name): + return "%s__object" % (name) + + def xxxxmkvalueCheck(self, name): + Output("%s__object = new_FSCatalogInfo(%s__bitmap, %s);", name, name) + + class FSCatalogInfoAndBitmap_inType(FSCatalogInfoAndBitmapType, InputOnlyMixIn): + + def xxxxmkvalueCheck(self, name): + pass + + class FSCatalogInfoAndBitmap_outType(FSCatalogInfoAndBitmapType): + + def getargsFormat(self): + return "l" + + def getargsArgs(self, name): + return "%s__bitmap" % name + + def getargsCheck(self, name): + pass FInfo = OpaqueType("FInfo", "FInfo") *************** *** 61,64 **** --- 108,113 ---- FSRef_ptr = OpaqueType("FSRef", "FSRef") OptFSRefPtr = OptionalFSxxxType("FSRef", "BUG", "myPyMac_GetOptFSRefPtr") + FSCatalogInfoAndBitmap_in = FSCatalogInfoAndBitmap_inType() + FSCatalogInfoAndBitmap_out = FSCatalogInfoAndBitmap_outType() # To be done: From jvr@users.sourceforge.net Thu Jan 9 22:54:40 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 09 Jan 2003 14:54:40 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE Wmenus.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv3486 Modified Files: Wmenus.py Log Message: removed silly & mask, avoiding FutureWarning Index: Wmenus.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/Wmenus.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Wmenus.py 24 Nov 2002 01:01:07 -0000 1.7 --- Wmenus.py 9 Jan 2003 22:54:37 -0000 1.8 *************** *** 112,116 **** reply = self.menu.menu.PopUpMenuSelect(t, l, 1) if reply: ! id = (reply & 0xffff0000) >> 16 item = reply & 0xffff self._menu_callback(id, item) --- 112,116 ---- reply = self.menu.menu.PopUpMenuSelect(t, l, 1) if reply: ! id = reply >> 16 item = reply & 0xffff self._menu_callback(id, item) *************** *** 201,205 **** reply = self.menu.menu.PopUpMenuSelect(t, l, 1) if reply: ! id = (reply & 0xffff0000) >> 16 item = reply & 0xffff self._menu_callback(id, item) --- 201,205 ---- reply = self.menu.menu.PopUpMenuSelect(t, l, 1) if reply: ! id = reply >> 16 item = reply & 0xffff self._menu_callback(id, item) From tim_one@users.sourceforge.net Fri Jan 10 02:05:18 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 09 Jan 2003 18:05:18 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv654/python/Modules Modified Files: datetimemodule.c Log Message: Removed more now-pointless pickle code. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** datetimemodule.c 8 Jan 2003 20:51:36 -0000 1.35 --- datetimemodule.c 10 Jan 2003 02:05:14 -0000 1.36 *************** *** 622,626 **** assert(check_tzinfo_subclass(newtzinfo) >= 0); Py_INCREF(newtzinfo); ! Py_DECREF(((PyDateTime_DateTimeTZ *)self)->tzinfo); ((PyDateTime_DateTimeTZ *)self)->tzinfo = newtzinfo; } --- 622,626 ---- assert(check_tzinfo_subclass(newtzinfo) >= 0); Py_INCREF(newtzinfo); ! Py_XDECREF(((PyDateTime_DateTimeTZ *)self)->tzinfo); ((PyDateTime_DateTimeTZ *)self)->tzinfo = newtzinfo; } *************** *** 3234,3239 **** } - static PyObject *datetime_getstate(PyDateTime_DateTime *self); - static long datetime_hash(PyDateTime_DateTime *self) --- 3234,3237 ---- *************** *** 3252,3256 **** /* Reduce this to a hash of another object. */ if (n == OFFSET_NAIVE) ! temp = datetime_getstate(self); else { int days; --- 3250,3256 ---- /* Reduce this to a hash of another object. */ if (n == OFFSET_NAIVE) ! temp = PyString_FromStringAndSize( ! (char *)self->data, ! _PyDateTime_DATETIME_DATASIZE); else { int days; *************** *** 3351,3382 **** } - /* Pickle support. Quite a maze! */ - - static PyObject * - datetime_getstate(PyDateTime_DateTime *self) - { - return PyString_FromStringAndSize((char *)self->data, - _PyDateTime_DATETIME_DATASIZE); - } - - static PyObject * - datetime_setstate(PyDateTime_DateTime *self, PyObject *state) - { - const int len = PyString_Size(state); - unsigned char *pdata = (unsigned char*)PyString_AsString(state); - - if (! PyString_Check(state) || - len != _PyDateTime_DATETIME_DATASIZE) { - PyErr_SetString(PyExc_TypeError, - "bad argument to datetime.__setstate__"); - return NULL; - } - memcpy(self->data, pdata, _PyDateTime_DATETIME_DATASIZE); - self->hashcode = -1; - - Py_INCREF(Py_None); - return Py_None; - } - static PyMethodDef datetime_methods[] = { /* Class methods: */ --- 3351,3354 ---- *************** *** 3429,3437 **** PyDoc_STR("tz -> datetimetz with same date & time, and tzinfo=tz\n")}, - {"__setstate__", (PyCFunction)datetime_setstate, METH_O, - PyDoc_STR("__setstate__(state)")}, - - {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS, - PyDoc_STR("__getstate__() -> state")}, {NULL, NULL} }; --- 3401,3404 ---- *************** *** 3697,3702 **** } - static PyObject *time_getstate(PyDateTime_Time *self); - static long time_hash(PyDateTime_Time *self) --- 3664,3667 ---- *************** *** 3714,3718 **** /* Reduce this to a hash of another object. */ if (offset == 0) ! temp = time_getstate(self); else { int hour; --- 3679,3684 ---- /* Reduce this to a hash of another object. */ if (offset == 0) ! temp = PyString_FromStringAndSize((char *)self->data, ! _PyDateTime_TIME_DATASIZE); else { int hour; *************** *** 3774,3805 **** } - /* Pickle support. Quite a maze! */ - - static PyObject * - time_getstate(PyDateTime_Time *self) - { - return PyString_FromStringAndSize((char *)self->data, - _PyDateTime_TIME_DATASIZE); - } - - static PyObject * - time_setstate(PyDateTime_Time *self, PyObject *state) - { - const int len = PyString_Size(state); - unsigned char *pdata = (unsigned char*)PyString_AsString(state); - - if (! PyString_Check(state) || - len != _PyDateTime_TIME_DATASIZE) { - PyErr_SetString(PyExc_TypeError, - "bad argument to time.__setstate__"); - return NULL; - } - memcpy(self->data, pdata, _PyDateTime_TIME_DATASIZE); - self->hashcode = -1; - - Py_INCREF(Py_None); - return Py_None; - } - static PyMethodDef time_methods[] = { {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS, --- 3740,3743 ---- *************** *** 3811,3820 **** {"replace", (PyCFunction)time_replace, METH_KEYWORDS, PyDoc_STR("Return datetime with new specified fields.")}, - - {"__setstate__", (PyCFunction)time_setstate, METH_O, - PyDoc_STR("__setstate__(state)")}, - - {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS, - PyDoc_STR("__getstate__() -> state")}, {NULL, NULL} }; --- 3749,3752 ---- *************** *** 4177,4181 **** */ ! /* Let basestate be the state string returned by time_getstate. * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). * So it's a tuple in any (non-error) case. --- 4109,4113 ---- */ ! /* Let basestate be the non-tzinfo data string. * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). * So it's a tuple in any (non-error) case. *************** *** 4187,4191 **** PyObject *result = NULL; ! basestate = time_getstate((PyDateTime_Time *)self); if (basestate != NULL) { if (self->tzinfo == Py_None) --- 4119,4124 ---- PyObject *result = NULL; ! basestate = PyString_FromStringAndSize((char *)self->data, ! _PyDateTime_TIME_DATASIZE); if (basestate != NULL) { if (self->tzinfo == Py_None) *************** *** 4201,4205 **** timetz_setstate(PyDateTime_TimeTZ *self, PyObject *state) { - PyObject *temp; PyObject *basestate; PyObject *tzinfo = Py_None; --- 4134,4137 ---- *************** *** 4209,4221 **** &tzinfo)) return NULL; ! temp = time_setstate((PyDateTime_Time *)self, basestate); ! if (temp == NULL) return NULL; ! Py_DECREF(temp); ! Py_INCREF(tzinfo); Py_XDECREF(self->tzinfo); self->tzinfo = tzinfo; - Py_INCREF(Py_None); return Py_None; --- 4141,4157 ---- &tzinfo)) return NULL; ! if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE || ! check_tzinfo_subclass(tzinfo) < 0) { ! PyErr_SetString(PyExc_TypeError, ! "bad argument to time.__setstate__"); return NULL; ! } ! memcpy((char *)self->data, ! PyString_AsString(basestate), ! _PyDateTime_TIME_DATASIZE); ! self->hashcode = -1; Py_INCREF(tzinfo); Py_XDECREF(self->tzinfo); self->tzinfo = tzinfo; Py_INCREF(Py_None); return Py_None; *************** *** 4865,4869 **** */ ! /* Let basestate be the state string returned by datetime_getstate. * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). * So it's a tuple in any (non-error) case. --- 4801,4808 ---- */ ! ! /* Pickle support. Quite a maze! */ ! ! /* Let basestate be the state string returned by the date & time fields. * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). * So it's a tuple in any (non-error) case. *************** *** 4875,4879 **** PyObject *result = NULL; ! basestate = datetime_getstate((PyDateTime_DateTime *)self); if (basestate != NULL) { if (self->tzinfo == Py_None) --- 4814,4819 ---- PyObject *result = NULL; ! basestate = PyString_FromStringAndSize((char *)self->data, ! _PyDateTime_DATETIME_DATASIZE); if (basestate != NULL) { if (self->tzinfo == Py_None) *************** *** 4889,4893 **** datetimetz_setstate(PyDateTime_DateTimeTZ *self, PyObject *state) { - PyObject *temp; PyObject *basestate; PyObject *tzinfo = Py_None; --- 4829,4832 ---- *************** *** 4897,4909 **** &tzinfo)) return NULL; ! temp = datetime_setstate((PyDateTime_DateTime *)self, basestate); ! if (temp == NULL) return NULL; ! Py_DECREF(temp); ! ! Py_INCREF(tzinfo); ! Py_XDECREF(self->tzinfo); ! self->tzinfo = tzinfo; ! Py_INCREF(Py_None); return Py_None; --- 4836,4850 ---- &tzinfo)) return NULL; ! if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE || ! check_tzinfo_subclass(tzinfo) < 0) { ! PyErr_SetString(PyExc_TypeError, ! "bad argument to datetime.__setstate__"); return NULL; ! } ! memcpy((char *)self->data, ! PyString_AsString(basestate), ! _PyDateTime_DATETIME_DATASIZE); ! self->hashcode = -1; ! replace_tzinfo((PyObject *)self, tzinfo); Py_INCREF(Py_None); return Py_None; From tim_one@users.sourceforge.net Fri Jan 10 03:49:05 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 09 Jan 2003 19:49:05 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv26942/python/Lib/test Modified Files: test_datetime.py Log Message: Got rid of the timetz type entirely. This was a bit trickier than I hoped it would be, but not too bad. A test had to change: time.__setstate__() can no longer add a non-None tzinfo member to a time object that didn't already have one, since storage for a tzinfo member doesn't exist in that case. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** test_datetime.py 8 Jan 2003 20:39:52 -0000 1.23 --- test_datetime.py 10 Jan 2003 03:49:02 -0000 1.24 *************** *** 1858,1862 **** orig = self.theclass(5, 6, 7, tzinfo=tinfo) state = orig.__getstate__() ! derived = self.theclass() derived.__setstate__(state) self.assertEqual(orig, derived) --- 1858,1862 ---- orig = self.theclass(5, 6, 7, tzinfo=tinfo) state = orig.__getstate__() ! derived = self.theclass(tzinfo=FixedOffset(0, "UTC", 0)) derived.__setstate__(state) self.assertEqual(orig, derived) From tim_one@users.sourceforge.net Fri Jan 10 03:49:05 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 09 Jan 2003 19:49:05 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv26942/python/Modules Modified Files: datetimemodule.c Log Message: Got rid of the timetz type entirely. This was a bit trickier than I hoped it would be, but not too bad. A test had to change: time.__setstate__() can no longer add a non-None tzinfo member to a time object that didn't already have one, since storage for a tzinfo member doesn't exist in that case. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** datetimemodule.c 10 Jan 2003 02:05:14 -0000 1.36 --- datetimemodule.c 10 Jan 2003 03:49:02 -0000 1.37 *************** *** 83,87 **** static PyTypeObject PyDateTime_TimeType; static PyTypeObject PyDateTime_TZInfoType; - static PyTypeObject PyDateTime_TimeTZType; /* --------------------------------------------------------------------------- --- 83,86 ---- *************** *** 608,613 **** if (PyDateTimeTZ_Check(self)) tzinfo = ((PyDateTime_DateTimeTZ *)self)->tzinfo; [...1425 lines suppressed...] Py_DECREF(x); ! x = new_time(23, 59, 59, 999999, Py_None); if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) return; *************** *** 5212,5217 **** PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); ! Py_INCREF(&PyDateTime_TimeTZType); ! PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeTZType); Py_INCREF(&PyDateTime_DateTimeTZType); --- 5072,5077 ---- PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); ! Py_INCREF(&PyDateTime_TimeType); ! PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType); Py_INCREF(&PyDateTime_DateTimeTZType); From tim_one@users.sourceforge.net Fri Jan 10 03:49:04 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 09 Jan 2003 19:49:04 -0800 Subject: [Python-checkins] python/dist/src/Include datetime.h,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv26942/python/Include Modified Files: datetime.h Log Message: Got rid of the timetz type entirely. This was a bit trickier than I hoped it would be, but not too bad. A test had to change: time.__setstate__() can no longer add a non-None tzinfo member to a time object that didn't already have one, since storage for a tzinfo member doesn't exist in that case. Index: datetime.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/datetime.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** datetime.h 16 Dec 2002 20:17:53 -0000 1.1 --- datetime.h 10 Jan 2003 03:49:02 -0000 1.2 *************** *** 28,31 **** --- 28,36 ---- #define _PyDateTime_DATETIME_DATASIZE 10 + #define _PyTZINFO_HEAD \ + PyObject_HEAD \ + long hashcode; \ + char hastzinfo; /* boolean flag */ + typedef struct { *************** *** 50,67 **** } PyDateTime_DateTimeTZ; typedef struct { ! PyObject_HEAD ! long hashcode; ! unsigned char data[_PyDateTime_TIME_DATASIZE]; ! } PyDateTime_Time; typedef struct { ! PyObject_HEAD ! long hashcode; ! unsigned char data[_PyDateTime_TIME_DATASIZE]; PyObject *tzinfo; ! } PyDateTime_TimeTZ; typedef struct --- 55,75 ---- } PyDateTime_DateTimeTZ; + + + #define _PyDateTime_TIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_TIME_DATASIZE]; + typedef struct { ! _PyDateTime_TIMEHEAD ! } _PyDateTime_BaseTime; /* hastzinfo false */ typedef struct { ! _PyDateTime_TIMEHEAD PyObject *tzinfo; ! } PyDateTime_Time; /* hastzinfo true */ ! typedef struct *************** *** 93,97 **** ((PyDateTime_DateTime*)o)->data[9]) ! /* Apply for time and timetz instances. */ #define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) #define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) --- 101,105 ---- ((PyDateTime_DateTime*)o)->data[9]) ! /* Apply for time instances. */ #define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) #define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) *************** *** 113,119 **** #define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) #define PyTime_CheckExact(op) ((op)->ob_type == &PyDateTime_TimeType) - - #define PyTimeTZ_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeTZType) - #define PyTimeTZ_CheckExact(op) ((op)->ob_type == &PyDateTime_TimeTZType) #define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType) --- 121,124 ---- From tim_one@users.sourceforge.net Fri Jan 10 03:52:28 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 09 Jan 2003 19:52:28 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.96,1.97 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv27471 Modified Files: test_datetime.py Log Message: Patching a test for compatibility with the 2.3 C implementation: because a time object has two different allocations under the covers (depending on whether it has a non-None tzinfo member), time.__setstate__() can no longer add a non-None tzinfo member to a time object that didn't already have one. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -d -r1.96 -r1.97 *** test_datetime.py 8 Jan 2003 19:43:46 -0000 1.96 --- test_datetime.py 10 Jan 2003 03:52:25 -0000 1.97 *************** *** 1856,1860 **** orig = self.theclass(5, 6, 7, tzinfo=tinfo) state = orig.__getstate__() ! derived = self.theclass() derived.__setstate__(state) self.assertEqual(orig, derived) --- 1856,1860 ---- orig = self.theclass(5, 6, 7, tzinfo=tinfo) state = orig.__getstate__() ! derived = self.theclass(tzinfo=FixedOffset(0, "UTC", 0)) derived.__setstate__(state) self.assertEqual(orig, derived) From rhettinger@users.sourceforge.net Fri Jan 10 09:33:11 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 10 Jan 2003 01:33:11 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libtypes.tex,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv15885 Modified Files: libtypes.tex Log Message: SF bug #652888: bad documentation for the "type" builtin Clarified that not all types are included. The OP was looking for a StaticMethodType. Also, added a note and example suggesting the use of int,str, etc. instead of IntType, StrType, etc. Renamed the crummy variable name in the example from "list" to "mylist". Index: libtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtypes.tex,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** libtypes.tex 22 May 2002 02:44:24 -0000 1.54 --- libtypes.tex 10 Jan 2003 09:33:08 -0000 1.55 *************** *** 1,12 **** \section{\module{types} --- ! Names for all built-in types} \declaremodule{standard}{types} ! \modulesynopsis{Names for all built-in types.} ! This module defines names for all object types that are used by the ! standard Python interpreter, but not for the types defined by various ! extension modules. It is safe to use \samp{from types import *} --- the module does not export any names besides the ones listed here. New names exported by future versions of this module will all end in --- 1,14 ---- \section{\module{types} --- ! Names for built-in types} \declaremodule{standard}{types} ! \modulesynopsis{Names for built-in types.} ! This module defines names for types some object types that are used by ! the standard Python interpreter, but not for the types defined by various ! extension modules. Also, it does not include some of the types that ! arise during processing such the \code{listiterator} type. ! It is safe to use \samp{from types import *} --- the module does not export any names besides the ones listed here. New names exported by future versions of this module will all end in *************** *** 18,23 **** \begin{verbatim} from types import * ! def delete(list, item): if type(item) is IntType: del list[item] else: --- 20,39 ---- \begin{verbatim} from types import * ! def delete(mylist, item): if type(item) is IntType: + del mylist[item] + else: + mylist.remove(item) + \end{verbatim} + + Starting in Python 2.2, built-in factory functions such as + \function{int()} and \function{str()} are also names for the + corresponding types. This is now the preferred way to access + the type instead of using the \module{types} module. Accordingly, + the example above should be written as follows: + + \begin{verbatim} + def delete(mylist, item): + if isinstance(item, int): del list[item] else: From nnorwitz@users.sourceforge.net Fri Jan 10 13:52:34 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 05:52:34 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libtypes.tex,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv25220/Doc/lib Modified Files: libtypes.tex Log Message: Remove extra 'types' Change a couple of list -> mylist Index: libtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtypes.tex,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** libtypes.tex 10 Jan 2003 09:33:08 -0000 1.55 --- libtypes.tex 10 Jan 2003 13:52:30 -0000 1.56 *************** *** 6,10 **** ! This module defines names for types some object types that are used by the standard Python interpreter, but not for the types defined by various extension modules. Also, it does not include some of the types that --- 6,10 ---- ! This module defines names for some object types that are used by the standard Python interpreter, but not for the types defined by various extension modules. Also, it does not include some of the types that *************** *** 36,42 **** def delete(mylist, item): if isinstance(item, int): ! del list[item] else: ! list.remove(item) \end{verbatim} --- 36,42 ---- def delete(mylist, item): if isinstance(item, int): ! del mylist[item] else: ! mylist.remove(item) \end{verbatim} From nnorwitz@users.sourceforge.net Fri Jan 10 15:29:24 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 07:29:24 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.37,1.38 posixmodule.c,2.281,2.282 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv3975/Modules Modified Files: datetimemodule.c posixmodule.c Log Message: Get rid of compiler warnings Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** datetimemodule.c 10 Jan 2003 03:49:02 -0000 1.37 --- datetimemodule.c 10 Jan 2003 15:29:14 -0000 1.38 *************** *** 3669,3674 **** time_dealloc(PyDateTime_Time *self) { ! if (self->hastzinfo) Py_XDECREF(self->tzinfo); self->ob_type->tp_free((PyObject *)self); } --- 3669,3675 ---- time_dealloc(PyDateTime_Time *self) { ! if (self->hastzinfo) { Py_XDECREF(self->tzinfo); + } self->ob_type->tp_free((PyObject *)self); } *************** *** 4031,4035 **** { PyDateTime_Time *self; - PyObject *tzinfo = Py_None; /* We don't want to allocate space for tzinfo if it's not needed. --- 4032,4035 ---- Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.281 retrieving revision 2.282 diff -C2 -d -r2.281 -r2.282 *** posixmodule.c 7 Jan 2003 20:57:09 -0000 2.281 --- posixmodule.c 10 Jan 2003 15:29:16 -0000 2.282 *************** *** 7659,7711 **** #ifdef EX_OK if (ins(d, "EX_OK", (long)EX_OK)) return -1; ! #endif EX_OK #ifdef EX_USAGE if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1; ! #endif EX_USAGE #ifdef EX_DATAERR if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1; ! #endif EX_DATAERR #ifdef EX_NOINPUT if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1; ! #endif EX_NOINPUT #ifdef EX_NOUSER if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1; ! #endif EX_NOUSER #ifdef EX_NOHOST if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1; ! #endif EX_NOHOST #ifdef EX_UNAVAILABLE if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1; ! #endif EX_UNAVAILABLE #ifdef EX_SOFTWARE if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1; ! #endif EX_SOFTWARE #ifdef EX_OSERR if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1; ! #endif EX_OSERR #ifdef EX_OSFILE if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1; ! #endif EX_OSFILE #ifdef EX_CANTCREAT if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1; ! #endif EX_CANTCREAT #ifdef EX_IOERR if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1; ! #endif EX_IOERR #ifdef EX_TEMPFAIL if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1; ! #endif EX_TEMPFAIL #ifdef EX_PROTOCOL if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1; ! #endif EX_PROTOCOL #ifdef EX_NOPERM if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1; ! #endif EX_NOPERM #ifdef EX_CONFIG if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1; ! #endif EX_CONFIG #ifdef EX_NOTFOUND if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1; ! #endif EX_NOTFOUND #ifdef HAVE_SPAWNV --- 7659,7711 ---- #ifdef EX_OK if (ins(d, "EX_OK", (long)EX_OK)) return -1; ! #endif /* EX_OK */ #ifdef EX_USAGE if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1; ! #endif /* EX_USAGE */ #ifdef EX_DATAERR if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1; ! #endif /* EX_DATAERR */ #ifdef EX_NOINPUT if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1; ! #endif /* EX_NOINPUT */ #ifdef EX_NOUSER if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1; ! #endif /* EX_NOUSER */ #ifdef EX_NOHOST if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1; ! #endif /* EX_NOHOST */ #ifdef EX_UNAVAILABLE if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1; ! #endif /* EX_UNAVAILABLE */ #ifdef EX_SOFTWARE if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1; ! #endif /* EX_SOFTWARE */ #ifdef EX_OSERR if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1; ! #endif /* EX_OSERR */ #ifdef EX_OSFILE if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1; ! #endif /* EX_OSFILE */ #ifdef EX_CANTCREAT if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1; ! #endif /* EX_CANTCREAT */ #ifdef EX_IOERR if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1; ! #endif /* EX_IOERR */ #ifdef EX_TEMPFAIL if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1; ! #endif /* EX_TEMPFAIL */ #ifdef EX_PROTOCOL if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1; ! #endif /* EX_PROTOCOL */ #ifdef EX_NOPERM if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1; ! #endif /* EX_NOPERM */ #ifdef EX_CONFIG if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1; ! #endif /* EX_CONFIG */ #ifdef EX_NOTFOUND if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1; ! #endif /* EX_NOTFOUND */ #ifdef HAVE_SPAWNV From nnorwitz@users.sourceforge.net Fri Jan 10 15:31:20 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 07:31:20 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.343,2.344 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv4635/Python Modified Files: ceval.c Log Message: As discussed briefly on python-dev, add Pending Deprecation Warning when a string exception is raised. Note that raising string exceptions is deprecated in an exception message. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.343 retrieving revision 2.344 diff -C2 -d -r2.343 -r2.344 *** ceval.c 9 Jan 2003 15:24:30 -0000 2.343 --- ceval.c 10 Jan 2003 15:31:15 -0000 2.344 *************** *** 2734,2738 **** * do nothing. Raising an instance of a new-style str * subclass is right out. */ ! ; else if (PyClass_Check(type)) --- 2734,2739 ---- * do nothing. Raising an instance of a new-style str * subclass is right out. */ ! PyErr_Warn(PyExc_PendingDeprecationWarning, ! "raising a string exception is deprecated"); else if (PyClass_Check(type)) *************** *** 2758,2763 **** anyway, just not what you specified :-) */ PyErr_Format(PyExc_TypeError, ! "exceptions must be strings, classes, or " ! "instances, not %s", type->ob_type->tp_name); goto raise_error; } --- 2759,2765 ---- anyway, just not what you specified :-) */ PyErr_Format(PyExc_TypeError, ! "exceptions must be classes, instances, or " ! "strings (deprecated), not %s", ! type->ob_type->tp_name); goto raise_error; } From rhettinger@users.sourceforge.net Fri Jan 10 16:45:26 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 10 Jan 2003 08:45:26 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.344,2.345 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv5195 Modified Files: ceval.c Log Message: As discussed on python-dev, removed from DUP_TOPX support for the parameter being either four or five. Currently, compile.c does not generate calls with a parameter higher than three. May have to be reverted if the second alpha or beta shakes out some other tool generating this op code with a parameter of four or five. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.344 retrieving revision 2.345 diff -C2 -d -r2.344 -r2.345 *** ceval.c 10 Jan 2003 15:31:15 -0000 2.344 --- ceval.c 10 Jan 2003 16:45:17 -0000 2.345 *************** *** 554,563 **** #define THIRD() (stack_pointer[-3]) #define FOURTH() (stack_pointer[-4]) - #define FIFTH() (stack_pointer[-5]) #define SET_TOP(v) (stack_pointer[-1] = (v)) #define SET_SECOND(v) (stack_pointer[-2] = (v)) #define SET_THIRD(v) (stack_pointer[-3] = (v)) #define SET_FOURTH(v) (stack_pointer[-4] = (v)) - #define SET_FIFTH(v) (stack_pointer[-5] = (v)) #define BASIC_STACKADJ(n) (stack_pointer += n) #define BASIC_PUSH(v) (*stack_pointer++ = (v)) --- 554,561 ---- *************** *** 885,921 **** SET_SECOND(w); SET_THIRD(v); - continue; - case 4: - x = TOP(); - Py_INCREF(x); - w = SECOND(); - Py_INCREF(w); - v = THIRD(); - Py_INCREF(v); - u = FOURTH(); - Py_INCREF(u); - STACKADJ(4); - SET_TOP(x); - SET_SECOND(w); - SET_THIRD(v); - SET_FOURTH(u); - continue; - case 5: - x = TOP(); - Py_INCREF(x); - w = SECOND(); - Py_INCREF(w); - v = THIRD(); - Py_INCREF(v); - u = FOURTH(); - Py_INCREF(u); - t = FIFTH(); - Py_INCREF(t); - STACKADJ(5); - SET_TOP(x); - SET_SECOND(w); - SET_THIRD(v); - SET_FOURTH(u); - SET_FIFTH(t); continue; default: --- 883,886 ---- From bwarsaw@users.sourceforge.net Fri Jan 10 19:03:32 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 10 Jan 2003 11:03:32 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb/test test_thread.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb/test In directory sc8-pr-cvs1:/tmp/cvs-serv6333 Modified Files: test_thread.py Log Message: Cleanups, and conversion of assert to assertEqual() Index: test_thread.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_thread.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_thread.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_thread.py 10 Jan 2003 19:03:29 -0000 1.4 *************** *** 1,22 **** ! """ ! TestCases for multi-threaded access to a DB. """ ! import sys, os, string ! import tempfile import time from pprint import pprint from whrandom import random try: from threading import Thread, currentThread ! have_threads = 1 except ImportError: ! have_threads = 0 ! import unittest from test_all import verbose - from bsddb import db, dbutils --- 1,30 ---- ! """TestCases for multi-threaded access to a DB. """ ! import os ! import sys import time + import errno + import shutil + import tempfile from pprint import pprint from whrandom import random try: + True, False + except NameError: + True = 1 + False = 0 + + DASH = '-' + + try: from threading import Thread, currentThread ! have_threads = True except ImportError: ! have_threads = False import unittest from test_all import verbose from bsddb import db, dbutils *************** *** 29,33 **** envflags = 0 - def setUp(self): if verbose: --- 37,40 ---- *************** *** 36,41 **** homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home') self.homeDir = homeDir ! try: os.mkdir(homeDir) ! except os.error: pass self.env = db.DBEnv() self.setEnvOpts() --- 43,50 ---- homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home') self.homeDir = homeDir ! try: ! os.mkdir(homeDir) ! except OSError, e: ! if e.errno <> errno.EEXIST: raise self.env = db.DBEnv() self.setEnvOpts() *************** *** 48,67 **** self.d.open(self.filename, self.dbtype, self.dbopenflags|db.DB_CREATE) - def tearDown(self): self.d.close() self.env.close() ! import glob ! files = glob.glob(os.path.join(self.homeDir, '*')) ! for file in files: ! os.remove(file) ! def setEnvOpts(self): pass - def makeData(self, key): ! return string.join([key] * 5, '-') --- 57,70 ---- self.d.open(self.filename, self.dbtype, self.dbopenflags|db.DB_CREATE) def tearDown(self): self.d.close() self.env.close() ! shutil.rmtree(self.homeDir) def setEnvOpts(self): pass def makeData(self, key): ! return DASH.join([key] * 5) *************** *** 76,80 **** records = 1000 - def test01_1WriterMultiReaders(self): if verbose: --- 79,82 ---- *************** *** 103,111 **** t.join() - def writerThread(self, d, howMany, writerNum): #time.sleep(0.01 * writerNum + 0.01) name = currentThread().getName() ! start, stop = howMany * writerNum, howMany * (writerNum + 1) - 1 if verbose: print "%s: creating records %d - %d" % (name, start, stop) --- 105,113 ---- t.join() def writerThread(self, d, howMany, writerNum): #time.sleep(0.01 * writerNum + 0.01) name = currentThread().getName() ! start = howMany * writerNum ! stop = howMany * (writerNum + 1) - 1 if verbose: print "%s: creating records %d - %d" % (name, start, stop) *************** *** 118,122 **** print "%s: records %d - %d finished" % (name, start, x) ! if verbose: print "%s: finished creating records" % name ## # Each write-cursor will be exclusive, the only one that can update the DB... --- 120,125 ---- print "%s: records %d - %d finished" % (name, start, x) ! if verbose: ! print "%s: finished creating records" % name ## # Each write-cursor will be exclusive, the only one that can update the DB... *************** *** 131,136 **** ## c.close() ! if verbose: print "%s: thread finished" % name ! def readerThread(self, d, readerNum): --- 134,139 ---- ## c.close() ! if verbose: ! print "%s: thread finished" % name def readerThread(self, d, readerNum): *************** *** 143,156 **** rec = c.first() while rec: ! count = count + 1 key, data = rec ! assert self.makeData(key) == data rec = c.next() ! if verbose: print "%s: found %d records" % (name, count) c.close() time.sleep(0.05) ! if verbose: print "%s: thread finished" % name ! --- 146,160 ---- rec = c.first() while rec: ! count += 1 key, data = rec ! self.assertEqual(self.makeData(key), data) rec = c.next() ! if verbose: ! print "%s: found %d records" % (name, count) c.close() time.sleep(0.05) ! if verbose: ! print "%s: thread finished" % name *************** *** 168,171 **** --- 172,176 ---- records = 1000 + #---------------------------------------------------------------------- *************** *** 177,185 **** records = 1000 - def setEnvOpts(self): self.env.set_lk_detect(db.DB_LOCK_DEFAULT) - def test02_SimpleLocks(self): if verbose: --- 182,188 ---- *************** *** 206,214 **** t.join() - - def writerThread(self, d, howMany, writerNum): name = currentThread().getName() ! start, stop = howMany * writerNum, howMany * (writerNum + 1) - 1 if verbose: print "%s: creating records %d - %d" % (name, start, stop) --- 209,216 ---- t.join() def writerThread(self, d, howMany, writerNum): name = currentThread().getName() ! start = howMany * writerNum ! stop = howMany * (writerNum + 1) - 1 if verbose: print "%s: creating records %d - %d" % (name, start, stop) *************** *** 228,232 **** key = '%04d' % x data = dbutils.DeadlockWrap(d.get, key, max_retries=12) ! assert data == self.makeData(key) # flush them --- 230,234 ---- key = '%04d' % x data = dbutils.DeadlockWrap(d.get, key, max_retries=12) ! self.assertEqual(data, self.makeData(key)) # flush them *************** *** 243,247 **** if verbose and x % 100 == 0: print "%s: fetched record (%s, %s)" % (name, key, data) ! assert data == self.makeData(key), (key, data, self.makeData(key)) if random() <= 0.10: dbutils.DeadlockWrap(d.delete, key, max_retries=12) --- 245,249 ---- if verbose and x % 100 == 0: print "%s: fetched record (%s, %s)" % (name, key, data) ! self.assertEqual(data, self.makeData(key)) if random() <= 0.10: dbutils.DeadlockWrap(d.delete, key, max_retries=12) *************** *** 249,254 **** print "%s: deleted record %s" % (name, key) ! if verbose: print "%s: thread finished" % name ! def readerThread(self, d, readerNum): --- 251,256 ---- print "%s: deleted record %s" % (name, key) ! if verbose: ! print "%s: thread finished" % name def readerThread(self, d, readerNum): *************** *** 261,275 **** rec = c.first() while rec: ! count = count + 1 key, data = rec ! assert self.makeData(key) == data rec = c.next() ! if verbose: print "%s: found %d records" % (name, count) c.close() time.sleep(0.05) ! if verbose: print "%s: thread finished" % name ! ! --- 263,277 ---- rec = c.first() while rec: ! count += 1 key, data = rec ! self.assertEqual(self.makeData(key), data) rec = c.next() ! if verbose: ! print "%s: found %d records" % (name, count) c.close() time.sleep(0.05) ! if verbose: ! print "%s: thread finished" % name *************** *** 285,289 **** - class ThreadedTransactionsBase(BaseThreadedTestCase): dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT --- 287,290 ---- *************** *** 297,309 **** writers = 0 records = 2000 - txnFlag = 0 - def setEnvOpts(self): #self.env.set_lk_detect(db.DB_LOCK_DEFAULT) pass - def test03_ThreadedTransactions(self): if verbose: --- 298,307 ---- *************** *** 335,344 **** t.join() ! self.doLockDetect = 0 dt.join() - def doWrite(self, d, name, start, stop): ! finished = 0 while not finished: try: --- 333,341 ---- t.join() ! self.doLockDetect = False dt.join() def doWrite(self, d, name, start, stop): ! finished = False while not finished: try: *************** *** 350,354 **** print "%s: records %d - %d finished" % (name, start, x) txn.commit() ! finished = 1 except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val: if verbose: --- 347,351 ---- print "%s: records %d - %d finished" % (name, start, x) txn.commit() ! finished = True except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val: if verbose: *************** *** 357,365 **** time.sleep(0.05) - - def writerThread(self, d, howMany, writerNum): name = currentThread().getName() ! start, stop = howMany * writerNum, howMany * (writerNum + 1) - 1 if verbose: print "%s: creating records %d - %d" % (name, start, stop) --- 354,361 ---- time.sleep(0.05) def writerThread(self, d, howMany, writerNum): name = currentThread().getName() ! start = howMany * writerNum ! stop = howMany * (writerNum + 1) - 1 if verbose: print "%s: creating records %d - %d" % (name, start, stop) *************** *** 369,376 **** self.doWrite(d, name, x, min(stop, x+step)) ! if verbose: print "%s: finished creating records" % name ! if verbose: print "%s: deleting a few records" % name ! finished = 0 while not finished: try: --- 365,374 ---- self.doWrite(d, name, x, min(stop, x+step)) ! if verbose: ! print "%s: finished creating records" % name ! if verbose: ! print "%s: deleting a few records" % name ! finished = False while not finished: try: *************** *** 385,390 **** recs.append(key) txn.commit() ! finished = 1 ! if verbose: print "%s: deleted records %s" % (name, recs) except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val: if verbose: --- 383,389 ---- recs.append(key) txn.commit() ! finished = True ! if verbose: ! print "%s: deleted records %s" % (name, recs) except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val: if verbose: *************** *** 393,398 **** time.sleep(0.05) ! if verbose: print "%s: thread finished" % name ! def readerThread(self, d, readerNum): --- 392,397 ---- time.sleep(0.05) ! if verbose: ! print "%s: thread finished" % name def readerThread(self, d, readerNum): *************** *** 401,405 **** for loop in range(5): ! finished = 0 while not finished: try: --- 400,404 ---- for loop in range(5): ! finished = False while not finished: try: *************** *** 409,420 **** rec = c.first() while rec: ! count = count + 1 key, data = rec ! assert self.makeData(key) == data rec = c.next() if verbose: print "%s: found %d records" % (name, count) c.close() txn.commit() ! finished = 1 except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val: if verbose: --- 408,419 ---- rec = c.first() while rec: ! count += 1 key, data = rec ! self.assertEqual(self.makeData(key), data) rec = c.next() if verbose: print "%s: found %d records" % (name, count) c.close() txn.commit() ! finished = True except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val: if verbose: *************** *** 426,434 **** time.sleep(0.05) ! if verbose: print "%s: thread finished" % name ! def deadlockThread(self): ! self.doLockDetect = 1 while self.doLockDetect: time.sleep(0.5) --- 425,433 ---- time.sleep(0.05) ! if verbose: ! print "%s: thread finished" % name def deadlockThread(self): ! self.doLockDetect = True while self.doLockDetect: time.sleep(0.5) *************** *** 441,445 **** except db.DBError: pass - --- 440,443 ---- From bwarsaw@users.sourceforge.net Fri Jan 10 19:13:50 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 10 Jan 2003 11:13:50 -0800 Subject: [Python-checkins] python/nondist/peps pep-0291.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv10831 Modified Files: pep-0291.txt Log Message: Mark bsddb package as b/c with Python 2.1. I'll be responsible for that. Index: pep-0291.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0291.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pep-0291.txt 30 Nov 2002 01:50:39 -0000 1.3 --- pep-0291.txt 10 Jan 2003 19:13:46 -0000 1.4 *************** *** 69,72 **** --- 69,73 ---- Package/Module Maintainer(s) Python Version -------------- ------------- -------------- + bsddb Barry Warsaw 2.1 compiler Jeremy Hylton 2.1 distutils Andrew Kuchling 1.5.2 From bwarsaw@users.sourceforge.net Fri Jan 10 19:28:18 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 10 Jan 2003 11:28:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb/test test_recno.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb/test In directory sc8-pr-cvs1:/tmp/cvs-serv16589 Modified Files: test_recno.py Log Message: Python 2.1's string module doesn't have ascii_letters, so let's just hard code it. We want this module to work with Python 2.1 for now. Index: test_recno.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_recno.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_recno.py 31 Dec 2002 19:27:45 -0000 1.4 --- test_recno.py 10 Jan 2003 19:28:15 -0000 1.5 *************** *** 1,9 **** ! """ ! TestCases for exercising a Recno DB. """ import os import sys ! import string import tempfile from pprint import pprint --- 1,8 ---- ! """TestCases for exercising a Recno DB. """ import os import sys ! import errno import tempfile from pprint import pprint *************** *** 11,17 **** from bsddb import db - from test_all import verbose #---------------------------------------------------------------------- --- 10,18 ---- from bsddb import db from test_all import verbose + letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + + #---------------------------------------------------------------------- *************** *** 23,30 **** try: os.remove(self.filename) ! except os.error: ! pass ! ! def test01_basic(self): --- 24,29 ---- try: os.remove(self.filename) ! except OSError, e: ! if e.errno <> errno.EEXIST: raise def test01_basic(self): *************** *** 32,36 **** d.open(self.filename, db.DB_RECNO, db.DB_CREATE) ! for x in string.ascii_letters: recno = d.append(x * 60) assert type(recno) == type(0) --- 31,35 ---- d.open(self.filename, db.DB_RECNO, db.DB_CREATE) ! for x in letters: recno = d.append(x * 60) assert type(recno) == type(0) *************** *** 78,82 **** assert len(keys) == len(d) - items = d.items() if verbose: --- 77,80 ---- *************** *** 165,169 **** d.close() - def test02_WithSource(self): """ --- 163,166 ---- *************** *** 221,225 **** "The quick reddish-brown fox jumped over the comatose dog".split() - def test03_FixedLength(self): d = db.DB() --- 218,221 ---- *************** *** 229,233 **** d.open(self.filename, db.DB_RECNO, db.DB_CREATE) ! for x in string.ascii_letters: d.append(x * 35) # These will be padded --- 225,229 ---- d.open(self.filename, db.DB_RECNO, db.DB_CREATE) ! for x in letters: d.append(x * 35) # These will be padded *************** *** 251,254 **** --- 247,251 ---- c.close() d.close() + #---------------------------------------------------------------------- From nnorwitz@users.sourceforge.net Fri Jan 10 20:52:18 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 12:52:18 -0800 Subject: [Python-checkins] python/dist/src/Modules mmapmodule.c,2.41,2.42 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv20383/Modules Modified Files: mmapmodule.c Log Message: SF #665913, Fix mmap module core dump with unix Closing an mmap'ed file (calling munmap) twice on Solaris caused a core dump. Will backport. Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.41 retrieving revision 2.42 diff -C2 -d -r2.41 -r2.42 *** mmapmodule.c 5 Sep 2002 21:48:05 -0000 2.41 --- mmapmodule.c 10 Jan 2003 20:52:15 -0000 2.42 *************** *** 142,147 **** #ifdef UNIX ! munmap(self->data, self->size); ! self->data = NULL; #endif --- 142,149 ---- #ifdef UNIX ! if (self->data != NULL) { ! munmap(self->data, self->size); ! self->data = NULL; ! } #endif From nnorwitz@users.sourceforge.net Fri Jan 10 20:52:19 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 12:52:19 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_mmap.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv20383/Lib/test Modified Files: test_mmap.py Log Message: SF #665913, Fix mmap module core dump with unix Closing an mmap'ed file (calling munmap) twice on Solaris caused a core dump. Will backport. Index: test_mmap.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mmap.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** test_mmap.py 11 Sep 2002 02:56:42 -0000 1.28 --- test_mmap.py 10 Jan 2003 20:52:16 -0000 1.29 *************** *** 298,301 **** --- 298,319 ---- pass + # make sure a double close doesn't crash on Solaris (Bug# 665913) + f = open(TESTFN, 'w+') + + try: # unlink TESTFN no matter what + f.write(2**24 * 'a') # Arbitrary character + f.close() + + f = open(TESTFN) + mf = mmap.mmap(f.fileno(), 2**24, access=mmap.ACCESS_READ) + mf.close() + mf.close() + f.close() + + finally: + try: + os.unlink(TESTFN) + except OSError: + pass From nnorwitz@users.sourceforge.net Fri Jan 10 21:02:48 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 13:02:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_mmap.py,1.19.8.5,1.19.8.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25944/Lib/test Modified Files: Tag: release22-maint test_mmap.py Log Message: backport: SF #665913, Fix mmap module core dump with unix Closing an mmap'ed file (calling munmap) twice on Solaris caused a core dump. Index: test_mmap.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mmap.py,v retrieving revision 1.19.8.5 retrieving revision 1.19.8.6 diff -C2 -d -r1.19.8.5 -r1.19.8.6 *** test_mmap.py 24 Sep 2002 16:21:36 -0000 1.19.8.5 --- test_mmap.py 10 Jan 2003 21:02:41 -0000 1.19.8.6 *************** *** 298,301 **** --- 298,319 ---- pass + # make sure a double close doesn't crash on Solaris (Bug# 665913) + f = open(TESTFN, 'w+') + + try: # unlink TESTFN no matter what + f.write(2**24 * 'a') # Arbitrary character + f.close() + + f = open(TESTFN) + mf = mmap.mmap(f.fileno(), 2**24, access=mmap.ACCESS_READ) + mf.close() + mf.close() + f.close() + + finally: + try: + os.unlink(TESTFN) + except OSError: + pass From nnorwitz@users.sourceforge.net Fri Jan 10 21:03:14 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 13:03:14 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.51,1.337.2.4.2.52 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv25944/Misc Modified Files: Tag: release22-maint NEWS Log Message: backport: SF #665913, Fix mmap module core dump with unix Closing an mmap'ed file (calling munmap) twice on Solaris caused a core dump. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.51 retrieving revision 1.337.2.4.2.52 diff -C2 -d -r1.337.2.4.2.51 -r1.337.2.4.2.52 *** NEWS 7 Jan 2003 23:10:48 -0000 1.337.2.4.2.51 --- NEWS 10 Jan 2003 21:02:37 -0000 1.337.2.4.2.52 *************** *** 52,55 **** --- 52,57 ---- - New codec for Ukrainian Cyrillic. + - SF #665913: fix crash on Solaris when closing an mmap'ed file which + was already closed. What's New in Python 2.2.2 (final) ? From nnorwitz@users.sourceforge.net Fri Jan 10 21:03:14 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 13:03:14 -0800 Subject: [Python-checkins] python/dist/src/Modules mmapmodule.c,2.35.6.3,2.35.6.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv25944/Modules Modified Files: Tag: release22-maint mmapmodule.c Log Message: backport: SF #665913, Fix mmap module core dump with unix Closing an mmap'ed file (calling munmap) twice on Solaris caused a core dump. Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.35.6.3 retrieving revision 2.35.6.4 diff -C2 -d -r2.35.6.3 -r2.35.6.4 *** mmapmodule.c 5 Sep 2002 22:30:03 -0000 2.35.6.3 --- mmapmodule.c 10 Jan 2003 21:02:40 -0000 2.35.6.4 *************** *** 142,147 **** #ifdef UNIX ! munmap(self->data, self->size); ! self->data = NULL; #endif --- 142,149 ---- #ifdef UNIX ! if (self->data != NULL) { ! munmap(self->data, self->size); ! self->data = NULL; ! } #endif From nnorwitz@users.sourceforge.net Fri Jan 10 20:57:58 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 12:57:58 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.609,1.610 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv23550/Misc Modified Files: NEWS Log Message: SF #665913, Fix mmap module core dump with unix Closing an mmap'ed file (calling munmap) twice on Solaris caused a core dump. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.609 retrieving revision 1.610 diff -C2 -d -r1.609 -r1.610 *** NEWS 8 Jan 2003 20:39:54 -0000 1.609 --- NEWS 10 Jan 2003 20:57:54 -0000 1.610 *************** *** 70,73 **** --- 70,76 ---- datetimes constructed from them are equal. + - Fix a crash on Solaris that occurred when calling close() on + an mmap'ed file which was already closed. (SF patch #665913) + Library ------- From nnorwitz@users.sourceforge.net Fri Jan 10 21:27:57 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 13:27:57 -0800 Subject: [Python-checkins] python/dist/src/Modules ossaudiodev.c,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv4605/Modules Modified Files: ossaudiodev.c Log Message: Get build working on Redhat 7.2 linux 2.4.7 Index: ossaudiodev.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/ossaudiodev.c,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** ossaudiodev.c 31 Dec 2002 03:23:59 -0000 1.20 --- ossaudiodev.c 10 Jan 2003 21:27:54 -0000 1.21 *************** *** 1017,1021 **** --- 1017,1023 ---- _EXPORT_INT(m, SNDCTL_DSP_GETOPTR); _EXPORT_INT(m, SNDCTL_DSP_GETOSPACE); + #ifdef SNDCTL_DSP_GETSPDIF _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF); + #endif _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER); _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF); *************** *** 1029,1033 **** --- 1031,1037 ---- _EXPORT_INT(m, SNDCTL_DSP_SETFMT); _EXPORT_INT(m, SNDCTL_DSP_SETFRAGMENT); + #ifdef SNDCTL_DSP_SETSPDIF _EXPORT_INT(m, SNDCTL_DSP_SETSPDIF); + #endif _EXPORT_INT(m, SNDCTL_DSP_SETSYNCRO); _EXPORT_INT(m, SNDCTL_DSP_SETTRIGGER); From nnorwitz@users.sourceforge.net Fri Jan 10 23:24:34 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 15:24:34 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.610,1.611 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv19656/Misc Modified Files: NEWS Log Message: Fix SF bug # 602259, 3rd parameter for Tkinter.scan_dragto Add the optional gain parameter and pass it to Tk. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.610 retrieving revision 1.611 diff -C2 -d -r1.610 -r1.611 *** NEWS 10 Jan 2003 20:57:54 -0000 1.610 --- NEWS 10 Jan 2003 23:24:31 -0000 1.611 *************** *** 89,92 **** --- 89,95 ---- - urlparse can now parse imap:// URLs. See SF feature request #618024. + - Tkinter.Canvas.scan_dragto() provides an optional parameter to support + the gain value which is passed to Tk. SF bug# 602259. + Tools/Demos ----------- From nnorwitz@users.sourceforge.net Fri Jan 10 23:24:34 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 15:24:34 -0800 Subject: [Python-checkins] python/dist/src/Lib/lib-tk Tkinter.py,1.167,1.168 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory sc8-pr-cvs1:/tmp/cvs-serv19656/Lib/lib-tk Modified Files: Tkinter.py Log Message: Fix SF bug # 602259, 3rd parameter for Tkinter.scan_dragto Add the optional gain parameter and pass it to Tk. Index: Tkinter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Tkinter.py,v retrieving revision 1.167 retrieving revision 1.168 diff -C2 -d -r1.167 -r1.168 *** Tkinter.py 26 Nov 2002 21:39:48 -0000 1.167 --- Tkinter.py 10 Jan 2003 23:24:32 -0000 1.168 *************** *** 2140,2148 **** """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) ! def scan_dragto(self, x, y): ! """Adjust the view of the canvas to 10 times the difference between X and Y and the coordinates given in scan_mark.""" ! self.tk.call(self._w, 'scan', 'dragto', x, y) def select_adjust(self, tagOrId, index): """Adjust the end of the selection near the cursor of an item TAGORID to index.""" --- 2140,2148 ---- """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) ! def scan_dragto(self, x, y, gain=10): ! """Adjust the view of the canvas to GAIN times the difference between X and Y and the coordinates given in scan_mark.""" ! self.tk.call(self._w, 'scan', 'dragto', x, y, gain) def select_adjust(self, tagOrId, index): """Adjust the end of the selection near the cursor of an item TAGORID to index.""" From nnorwitz@users.sourceforge.net Fri Jan 10 23:29:51 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 15:29:51 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.611,1.612 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv21813/Misc Modified Files: NEWS Log Message: SF #639945 was fixed in alpha 1 Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.611 retrieving revision 1.612 diff -C2 -d -r1.611 -r1.612 *** NEWS 10 Jan 2003 23:24:31 -0000 1.611 --- NEWS 10 Jan 2003 23:29:48 -0000 1.612 *************** *** 500,503 **** --- 500,505 ---- This fixes a number of minor bugs (see bug #624807). + - Fix problem with dynamic loading on 64-bit AIX (see bug #639945). + Extension modules ----------------- From nnorwitz@users.sourceforge.net Fri Jan 10 23:32:04 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 15:32:04 -0800 Subject: [Python-checkins] python/dist/src/Python dynload_aix.c,2.11,2.11.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv22369/Python Modified Files: Tag: release22-maint dynload_aix.c Log Message: Backport 2.12: Fix for SF #639945, 64-bit bug on AIX when loading dynamic modules Index: dynload_aix.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/dynload_aix.c,v retrieving revision 2.11 retrieving revision 2.11.6.1 diff -C2 -d -r2.11 -r2.11.6.1 *** dynload_aix.c 28 Nov 2001 21:35:49 -0000 2.11 --- dynload_aix.c 10 Jan 2003 23:32:02 -0000 2.11.6.1 *************** *** 78,83 **** */ offset = (unsigned int)ldiptr->ldinfo_next; ! ldiptr = (struct ld_info *)((unsigned int) ! ldiptr + offset); continue; } --- 78,82 ---- */ offset = (unsigned int)ldiptr->ldinfo_next; ! ldiptr = (struct ld_info *)((char*)ldiptr + offset); continue; } *************** *** 99,103 **** prevmodptr = modptr; offset = (unsigned int)ldiptr->ldinfo_next; ! ldiptr = (struct ld_info *)((unsigned int)ldiptr + offset); } while (offset); free(ldibuf); --- 98,102 ---- prevmodptr = modptr; offset = (unsigned int)ldiptr->ldinfo_next; ! ldiptr = (struct ld_info *)((char*)ldiptr + offset); } while (offset); free(ldibuf); From nnorwitz@users.sourceforge.net Fri Jan 10 23:34:04 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 15:34:04 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.52,1.337.2.4.2.53 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv23182/Misc Modified Files: Tag: release22-maint NEWS Log Message: Fix for SF #639945, 64-bit bug on AIX when loading dynamic modules Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.52 retrieving revision 1.337.2.4.2.53 diff -C2 -d -r1.337.2.4.2.52 -r1.337.2.4.2.53 *** NEWS 10 Jan 2003 21:02:37 -0000 1.337.2.4.2.52 --- NEWS 10 Jan 2003 23:34:01 -0000 1.337.2.4.2.53 *************** *** 55,58 **** --- 55,60 ---- was already closed. + - SF #639945: fix crash on 64-bit AIX when loading dynamic modules. + What's New in Python 2.2.2 (final) ? Release date: 14-Oct-2002 From nnorwitz@users.sourceforge.net Fri Jan 10 23:47:56 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 15:47:56 -0800 Subject: [Python-checkins] python/dist/src/Lib dospath.py,1.25,1.25.10.1 macpath.py,1.31,1.31.10.1 ntpath.py,1.44.8.1,1.44.8.2 posixpath.py,1.46.10.1,1.46.10.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv27967 Modified Files: Tag: release22-maint dospath.py macpath.py ntpath.py posixpath.py Log Message: Backport for SF # 659228, 'realpath' function missing from os.path Index: dospath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/Attic/dospath.py,v retrieving revision 1.25 retrieving revision 1.25.10.1 diff -C2 -d -r1.25 -r1.25.10.1 *** dospath.py 10 Oct 2001 04:16:20 -0000 1.25 --- dospath.py 10 Jan 2003 23:47:52 -0000 1.25.10.1 *************** *** 7,11 **** "basename","dirname","commonprefix","getsize","getmtime", "getatime","islink","exists","isdir","isfile","ismount", ! "walk","expanduser","expandvars","normpath","abspath"] def normcase(s): --- 7,11 ---- "basename","dirname","commonprefix","getsize","getmtime", "getatime","islink","exists","isdir","isfile","ismount", ! "walk","expanduser","expandvars","normpath","abspath","realpath"] def normcase(s): Index: macpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/macpath.py,v retrieving revision 1.31 retrieving revision 1.31.10.1 diff -C2 -d -r1.31 -r1.31.10.1 *** macpath.py 10 Oct 2001 04:16:20 -0000 1.31 --- macpath.py 10 Jan 2003 23:47:53 -0000 1.31.10.1 *************** *** 7,11 **** "basename","dirname","commonprefix","getsize","getmtime", "getatime","islink","exists","isdir","isfile", ! "walk","expanduser","expandvars","normpath","abspath"] # Normalize the case of a pathname. Dummy in Posix, but .lower() here. --- 7,12 ---- "basename","dirname","commonprefix","getsize","getmtime", "getatime","islink","exists","isdir","isfile", ! "walk","expanduser","expandvars","normpath","abspath", ! "realpath","supports_unicode_filenames"] # Normalize the case of a pathname. Dummy in Posix, but .lower() here. Index: ntpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ntpath.py,v retrieving revision 1.44.8.1 retrieving revision 1.44.8.2 diff -C2 -d -r1.44.8.1 -r1.44.8.2 *** ntpath.py 6 Oct 2002 04:34:44 -0000 1.44.8.1 --- ntpath.py 10 Jan 2003 23:47:53 -0000 1.44.8.2 *************** *** 12,16 **** "basename","dirname","commonprefix","getsize","getmtime", "getatime","islink","exists","isdir","isfile","ismount", ! "walk","expanduser","expandvars","normpath","abspath","splitunc"] # Normalize the case of a pathname and map slashes to backslashes. --- 12,17 ---- "basename","dirname","commonprefix","getsize","getmtime", "getatime","islink","exists","isdir","isfile","ismount", ! "walk","expanduser","expandvars","normpath","abspath","splitunc", ! "realpath","supports_unicode_filenames"] # Normalize the case of a pathname and map slashes to backslashes. Index: posixpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/posixpath.py,v retrieving revision 1.46.10.1 retrieving revision 1.46.10.2 diff -C2 -d -r1.46.10.1 -r1.46.10.2 *** posixpath.py 6 Oct 2002 22:11:13 -0000 1.46.10.1 --- posixpath.py 10 Jan 2003 23:47:53 -0000 1.46.10.2 *************** *** 18,22 **** "getatime","islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath", ! "samefile","sameopenfile","samestat"] # Normalize the case of a pathname. Trivial in Posix, string.lower on Mac. --- 18,22 ---- "getatime","islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath", ! "samefile","sameopenfile","samestat","realpath"] # Normalize the case of a pathname. Trivial in Posix, string.lower on Mac. From nnorwitz@users.sourceforge.net Fri Jan 10 23:51:59 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Fri, 10 Jan 2003 15:51:59 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.53,1.337.2.4.2.54 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29273/Misc Modified Files: Tag: release22-maint NEWS Log Message: SF #659228, fix realpath() not being exported from os.path Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.53 retrieving revision 1.337.2.4.2.54 diff -C2 -d -r1.337.2.4.2.53 -r1.337.2.4.2.54 *** NEWS 10 Jan 2003 23:34:01 -0000 1.337.2.4.2.53 --- NEWS 10 Jan 2003 23:51:56 -0000 1.337.2.4.2.54 *************** *** 57,60 **** --- 57,62 ---- - SF #639945: fix crash on 64-bit AIX when loading dynamic modules. + - SF #659228, fix realpath() not being exported from os.path + What's New in Python 2.2.2 (final) ? Release date: 14-Oct-2002 From tim_one@users.sourceforge.net Sat Jan 11 00:15:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 10 Jan 2003 16:15:56 -0800 Subject: [Python-checkins] python/dist/src/Include datetime.h,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv4090/Include Modified Files: datetime.h Log Message: Minor fiddling to make the next part easier. Introduced an internal HASTZINFO() macro. Index: datetime.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/datetime.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** datetime.h 10 Jan 2003 03:49:02 -0000 1.2 --- datetime.h 11 Jan 2003 00:15:53 -0000 1.3 *************** *** 28,49 **** #define _PyDateTime_DATETIME_DATASIZE 10 - #define _PyTZINFO_HEAD \ - PyObject_HEAD \ - long hashcode; \ - char hastzinfo; /* boolean flag */ typedef struct { PyObject_HEAD ! long hashcode; ! unsigned char data[_PyDateTime_DATE_DATASIZE]; ! } PyDateTime_Date; typedef struct { ! PyObject_HEAD ! long hashcode; ! unsigned char data[_PyDateTime_DATETIME_DATASIZE]; ! } PyDateTime_DateTime; typedef struct --- 28,45 ---- #define _PyDateTime_DATETIME_DATASIZE 10 typedef struct { PyObject_HEAD ! long hashcode; /* -1 when unknown */ ! int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ ! int seconds; /* 0 <= seconds < 24*3600 is invariant */ ! int microseconds; /* 0 <= microseconds < 1000000 is invariant */ ! } PyDateTime_Delta; typedef struct { ! PyObject_HEAD /* a pure abstract base clase */ ! } PyDateTime_TZInfo; typedef struct *************** *** 51,60 **** PyObject_HEAD long hashcode; ! unsigned char data[_PyDateTime_DATETIME_DATASIZE]; ! PyObject *tzinfo; ! } PyDateTime_DateTimeTZ; #define _PyDateTime_TIMEHEAD \ _PyTZINFO_HEAD \ --- 47,77 ---- PyObject_HEAD long hashcode; ! unsigned char data[_PyDateTime_DATE_DATASIZE]; ! } PyDateTime_Date; ! + /* The datetime and time types have hashcodes, and an optional tzinfo member, + * present if and only if hastzinfo is true. + */ + #define _PyTZINFO_HEAD \ + PyObject_HEAD \ + long hashcode; \ + char hastzinfo; /* boolean flag */ + /* No _PyDateTime_BaseTZInfo is allocated; it's just to have something + * convenient to cast to, when getting at the hastzinfo member of objects + * starting with _PyTZINFO_HEAD. + */ + typedef struct + { + _PyTZINFO_HEAD + } _PyDateTime_BaseTZInfo; + /* All time objects are of PyDateTime_TimeType, but that can be allocated + * in two ways, with or without a tzinfo member. Without is the same as + * tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an + * internal struct used to allocate the right amount of space for the + * "without" case. + */ #define _PyDateTime_TIMEHEAD \ _PyTZINFO_HEAD \ *************** *** 72,89 **** } PyDateTime_Time; /* hastzinfo true */ typedef struct { PyObject_HEAD ! long hashcode; /* -1 when unknown */ ! int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ ! int seconds; /* 0 <= seconds < 24*3600 is invariant */ ! int microseconds; /* 0 <= microseconds < 1000000 is invariant */ ! } PyDateTime_Delta; typedef struct { ! PyObject_HEAD /* a pure abstract base clase */ ! } PyDateTime_TZInfo; /* Apply for date, datetime, and datetimetz instances. */ --- 89,109 ---- } PyDateTime_Time; /* hastzinfo true */ + /* XXX The date type will be reworked similarly. */ typedef struct { PyObject_HEAD ! long hashcode; ! unsigned char data[_PyDateTime_DATETIME_DATASIZE]; ! } PyDateTime_DateTime; typedef struct { ! PyObject_HEAD ! long hashcode; ! unsigned char data[_PyDateTime_DATETIME_DATASIZE]; ! PyObject *tzinfo; ! } PyDateTime_DateTimeTZ; ! /* Apply for date, datetime, and datetimetz instances. */ From tim_one@users.sourceforge.net Sat Jan 11 00:15:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 10 Jan 2003 16:15:56 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv4090/Modules Modified Files: datetimemodule.c Log Message: Minor fiddling to make the next part easier. Introduced an internal HASTZINFO() macro. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** datetimemodule.c 10 Jan 2003 15:29:14 -0000 1.38 --- datetimemodule.c 11 Jan 2003 00:15:54 -0000 1.39 *************** *** 76,79 **** --- 76,84 ---- #define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v)) + /* p is a pointer to a time or a datetime object; HASTZINFO(p) returns + * p->hastzinfo. + */ + #define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo) + /* Forward declarations. */ static PyTypeObject PyDateTime_DateType; *************** *** 607,611 **** if (PyDateTimeTZ_Check(self)) tzinfo = ((PyDateTime_DateTimeTZ *)self)->tzinfo; ! else if (PyTime_Check(self) && ((PyDateTime_Time *)self)->hastzinfo) tzinfo = ((PyDateTime_Time *)self)->tzinfo; --- 612,616 ---- if (PyDateTimeTZ_Check(self)) tzinfo = ((PyDateTime_DateTimeTZ *)self)->tzinfo; ! else if (PyTime_Check(self) && HASTZINFO(self)) tzinfo = ((PyDateTime_Time *)self)->tzinfo; *************** *** 2967,2973 **** TIME_GET_SECOND(time), TIME_GET_MICROSECOND(time)); ! if (result && ! ((PyDateTime_Time *)time)->hastzinfo && ! PyDateTimeTZ_Check(result)) { /* Copy the tzinfo field. */ replace_tzinfo(result, ((PyDateTime_Time *)time)->tzinfo); --- 2972,2976 ---- TIME_GET_SECOND(time), TIME_GET_MICROSECOND(time)); ! if (result && HASTZINFO(time) && PyDateTimeTZ_Check(result)) { /* Copy the tzinfo field. */ replace_tzinfo(result, ((PyDateTime_Time *)time)->tzinfo); *************** *** 3619,3623 **** time_tzinfo(PyDateTime_Time *self, void *unused) { ! PyObject *result = self->hastzinfo ? self->tzinfo : Py_None; Py_INCREF(result); return result; --- 3622,3626 ---- time_tzinfo(PyDateTime_Time *self, void *unused) { ! PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; Py_INCREF(result); return result; *************** *** 3669,3673 **** time_dealloc(PyDateTime_Time *self) { ! if (self->hastzinfo) { Py_XDECREF(self->tzinfo); } --- 3672,3676 ---- time_dealloc(PyDateTime_Time *self) { ! if (HASTZINFO(self)) { Py_XDECREF(self->tzinfo); } *************** *** 3682,3686 **** static PyObject * time_utcoffset(PyDateTime_Time *self, PyObject *unused) { ! return offset_as_timedelta(self->hastzinfo ? self->tzinfo : Py_None, "utcoffset", Py_None); } --- 3685,3689 ---- static PyObject * time_utcoffset(PyDateTime_Time *self, PyObject *unused) { ! return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None, "utcoffset", Py_None); } *************** *** 3688,3692 **** static PyObject * time_dst(PyDateTime_Time *self, PyObject *unused) { ! return offset_as_timedelta(self->hastzinfo ? self->tzinfo : Py_None, "dst", Py_None); } --- 3691,3695 ---- static PyObject * time_dst(PyDateTime_Time *self, PyObject *unused) { ! return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None, "dst", Py_None); } *************** *** 3694,3698 **** static PyObject * time_tzname(PyDateTime_Time *self, PyObject *unused) { ! return call_tzname(self->hastzinfo ? self->tzinfo : Py_None, Py_None); } --- 3697,3701 ---- static PyObject * time_tzname(PyDateTime_Time *self, PyObject *unused) { ! return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None, Py_None); } *************** *** 3723,3727 **** "%s(%d, %d)", typename, h, m); result = PyString_FromString(buffer); ! if (result != NULL && self->hastzinfo) result = append_keyword_tzinfo(result, self->tzinfo); return result; --- 3726,3730 ---- "%s(%d, %d)", typename, h, m); result = PyString_FromString(buffer); ! if (result != NULL && HASTZINFO(self)) result = append_keyword_tzinfo(result, self->tzinfo); return result; *************** *** 3750,3754 **** isoformat_time(pdatetime, buf, sizeof(buf)); result = PyString_FromString(buf); ! if (result == NULL || ! self->hastzinfo || self->tzinfo == Py_None) return result; --- 3753,3757 ---- isoformat_time(pdatetime, buf, sizeof(buf)); result = PyString_FromString(buf); ! if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None) return result; *************** *** 3877,3881 **** assert(n == OFFSET_AWARE); ! assert(self->hastzinfo); hour = divmod(TIME_GET_HOUR(self) * 60 + TIME_GET_MINUTE(self) - offset, --- 3880,3884 ---- assert(n == OFFSET_AWARE); ! assert(HASTZINFO(self)); hour = divmod(TIME_GET_HOUR(self) * 60 + TIME_GET_MINUTE(self) - offset, *************** *** 3910,3914 **** int ss = TIME_GET_SECOND(self); int us = TIME_GET_MICROSECOND(self); ! PyObject *tzinfo = self->hastzinfo ? self->tzinfo : Py_None; if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace", --- 3913,3917 ---- int ss = TIME_GET_SECOND(self); int us = TIME_GET_MICROSECOND(self); ! PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace", *************** *** 3937,3941 **** } offset = 0; ! if (self->hastzinfo && self->tzinfo != Py_None) { offset = call_utcoffset(self->tzinfo, Py_None, &none); if (offset == -1 && PyErr_Occurred()) --- 3940,3944 ---- } offset = 0; ! if (HASTZINFO(self) && self->tzinfo != Py_None) { offset = call_utcoffset(self->tzinfo, Py_None, &none); if (offset == -1 && PyErr_Occurred()) *************** *** 3962,3966 **** _PyDateTime_TIME_DATASIZE); if (basestate != NULL) { ! if (! self->hastzinfo || self->tzinfo == Py_None) result = Py_BuildValue("(O)", basestate); else --- 3965,3969 ---- _PyDateTime_TIME_DATASIZE); if (basestate != NULL) { ! if (! HASTZINFO(self) || self->tzinfo == Py_None) result = Py_BuildValue("(O)", basestate); else *************** *** 3987,3991 **** return NULL; } ! if (tzinfo != Py_None && ! self->hastzinfo) { PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't " "add a non-None tzinfo to a time object that " --- 3990,3994 ---- return NULL; } ! if (tzinfo != Py_None && ! HASTZINFO(self)) { PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't " "add a non-None tzinfo to a time object that " *************** *** 3997,4001 **** _PyDateTime_TIME_DATASIZE); self->hashcode = -1; ! if (self->hastzinfo) { Py_INCREF(tzinfo); Py_XDECREF(self->tzinfo); --- 4000,4004 ---- _PyDateTime_TIME_DATASIZE); self->hashcode = -1; ! if (HASTZINFO(self)) { Py_INCREF(tzinfo); Py_XDECREF(self->tzinfo); From tim_one@users.sourceforge.net Sat Jan 11 03:39:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 10 Jan 2003 19:39:13 -0800 Subject: [Python-checkins] python/dist/src/Include datetime.h,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv21453/python/Include Modified Files: datetime.h Log Message: Got rid of the internal datetimetz type. Index: datetime.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/datetime.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** datetime.h 11 Jan 2003 00:15:53 -0000 1.3 --- datetime.h 11 Jan 2003 03:39:11 -0000 1.4 *************** *** 43,53 **** } PyDateTime_TZInfo; - typedef struct - { - PyObject_HEAD - long hashcode; - unsigned char data[_PyDateTime_DATE_DATASIZE]; - } PyDateTime_Date; - /* The datetime and time types have hashcodes, and an optional tzinfo member, --- 43,46 ---- *************** *** 89,111 **** } PyDateTime_Time; /* hastzinfo true */ - /* XXX The date type will be reworked similarly. */ typedef struct { ! PyObject_HEAD ! long hashcode; unsigned char data[_PyDateTime_DATETIME_DATASIZE]; - } PyDateTime_DateTime; typedef struct { ! PyObject_HEAD ! long hashcode; ! unsigned char data[_PyDateTime_DATETIME_DATASIZE]; PyObject *tzinfo; ! } PyDateTime_DateTimeTZ; ! /* Apply for date, datetime, and datetimetz instances. */ #define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ ((PyDateTime_Date*)o)->data[1]) --- 82,114 ---- } PyDateTime_Time; /* hastzinfo true */ + /* All datetime objects are of PyDateTime_DateTimeType, but that can be + * allocated in two ways too, just like for time objects above. In addition, + * the plain date type is a base class for datetime, so it must also have + * a hastzinfo member (although it's unused there). + */ typedef struct { ! _PyTZINFO_HEAD ! unsigned char data[_PyDateTime_DATE_DATASIZE]; ! } PyDateTime_Date; ! ! #define _PyDateTime_DATETIMEHEAD \ ! _PyTZINFO_HEAD \ unsigned char data[_PyDateTime_DATETIME_DATASIZE]; typedef struct { ! _PyDateTime_DATETIMEHEAD ! } _PyDateTime_BaseDateTime; /* hastzinfo false */ ! ! typedef struct ! { ! _PyDateTime_DATETIMEHEAD PyObject *tzinfo; ! } PyDateTime_DateTime; /* hastzinfo true */ ! /* Apply for date and datetime instances. */ #define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ ((PyDateTime_Date*)o)->data[1]) *************** *** 135,141 **** #define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) #define PyDateTime_CheckExact(op) ((op)->ob_type == &PyDateTime_DateTimeType) - - #define PyDateTimeTZ_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeTZType) - #define PyDateTimeTZ_CheckExact(op) ((op)->ob_type == &PyDateTime_DateTimeTZType) #define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) --- 138,141 ---- From tim_one@users.sourceforge.net Sat Jan 11 03:39:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 10 Jan 2003 19:39:13 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv21453/python/Lib/test Modified Files: test_datetime.py Log Message: Got rid of the internal datetimetz type. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** test_datetime.py 10 Jan 2003 03:49:02 -0000 1.24 --- test_datetime.py 11 Jan 2003 03:39:11 -0000 1.25 *************** *** 2077,2081 **** orig = self.theclass(*args, **{'tzinfo': tinfo}) state = orig.__getstate__() ! derived = self.theclass(1, 1, 1) derived.__setstate__(state) self.assertEqual(orig, derived) --- 2077,2081 ---- orig = self.theclass(*args, **{'tzinfo': tinfo}) state = orig.__getstate__() ! derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0)) derived.__setstate__(state) self.assertEqual(orig, derived) From tim_one@users.sourceforge.net Sat Jan 11 03:39:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 10 Jan 2003 19:39:13 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv21453/python/Modules Modified Files: datetimemodule.c Log Message: Got rid of the internal datetimetz type. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** datetimemodule.c 11 Jan 2003 00:15:54 -0000 1.39 --- datetimemodule.c 11 Jan 2003 03:39:11 -0000 1.40 *************** *** 84,88 **** static PyTypeObject PyDateTime_DateType; static PyTypeObject PyDateTime_DateTimeType; - static PyTypeObject PyDateTime_DateTimeTZType; static PyTypeObject PyDateTime_DeltaType; static PyTypeObject PyDateTime_TimeType; --- 84,87 ---- *************** *** 610,615 **** PyObject *tzinfo = NULL; [...2541 lines suppressed...] 5. (x+k).n = x.n + k --- 4772,4776 ---- 4. (x+k).s = x.s ! This follows from #2, and that datimetime+timedelta preserves tzinfo. 5. (x+k).n = x.n + k *************** *** 5150,5154 **** None when called). ! The function wants to return a datetimetz y with timezone tz, equivalent to x. By #3, we want --- 4781,4785 ---- None when called). ! The function wants to return a datetime y with timezone tz, equivalent to x. By #3, we want From tim_one@users.sourceforge.net Sat Jan 11 03:44:16 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 10 Jan 2003 19:44:16 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.97,1.98 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv22869 Modified Files: test_datetime.py Log Message: Changed a test to reflect that the C implementation of datetime.__setstate__ can't add a non-None tzinfo to a datetime object that didn't already have a tzinfo member. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -d -r1.97 -r1.98 *** test_datetime.py 10 Jan 2003 03:52:25 -0000 1.97 --- test_datetime.py 11 Jan 2003 03:44:14 -0000 1.98 *************** *** 2075,2079 **** orig = self.theclass(*args, **{'tzinfo': tinfo}) state = orig.__getstate__() ! derived = self.theclass(1, 1, 1) derived.__setstate__(state) self.assertEqual(orig, derived) --- 2075,2079 ---- orig = self.theclass(*args, **{'tzinfo': tinfo}) state = orig.__getstate__() ! derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0)) derived.__setstate__(state) self.assertEqual(orig, derived) From fdrake@users.sourceforge.net Sat Jan 11 23:15:49 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Sat, 11 Jan 2003 15:15:49 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib liboperator.tex,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv22178 Modified Files: liboperator.tex Log Message: Minor correction and clarification. Index: liboperator.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liboperator.tex,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** liboperator.tex 19 Aug 2002 22:38:01 -0000 1.23 --- liboperator.tex 11 Jan 2003 23:15:47 -0000 1.24 *************** *** 60,64 **** \begin{funcdesc}{truth}{o} ! Return \code{1} if \var{o} is true, and 0 otherwise. \end{funcdesc} --- 60,66 ---- \begin{funcdesc}{truth}{o} ! Return \constant{True} if \var{o} is true, and \constant{False} ! otherwise. This is equivalent to the constructor of the \class{bool} ! constructor. \end{funcdesc} From rhettinger@users.sourceforge.net Sat Jan 11 23:42:09 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 11 Jan 2003 15:42:09 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.54,1.337.2.4.2.55 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29610 Modified Files: Tag: release22-maint NEWS Log Message: Since the WH generator never produced zero, it wasn't fair to characterize this as a fix to a long outstanding bug. Instead, it makes sure that the methods work as documented with any generator. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.54 retrieving revision 1.337.2.4.2.55 diff -C2 -d -r1.337.2.4.2.54 -r1.337.2.4.2.55 *** NEWS 10 Jan 2003 23:51:56 -0000 1.337.2.4.2.54 --- NEWS 11 Jan 2003 23:42:07 -0000 1.337.2.4.2.55 *************** *** 15,19 **** - Fixed sundry memory leaks. ! - Correct long standing bugs in the methods for random distributions. The range of u=random() is [0,1), so log(u) and 1/x can fail. Fix by setting u=1-random() or by reselecting for a usable value. --- 15,21 ---- - Fixed sundry memory leaks. ! - Improve the robustness of the methods for random distributions so ! they can work with generators producing a full range of values ! (unlike the Wichmann-Hill generator which never produces a zero). The range of u=random() is [0,1), so log(u) and 1/x can fail. Fix by setting u=1-random() or by reselecting for a usable value. From nnorwitz@users.sourceforge.net Sun Jan 12 14:56:21 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 12 Jan 2003 06:56:21 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libcurses.tex,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv26973/Doc/lib Modified Files: libcurses.tex Log Message: SF #665570, curses causes interpreter crash The interpreter doesn't crash, but it does call exit() in libncurses. Add a note to this effect. Will backport Index: libcurses.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcurses.tex,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** libcurses.tex 6 Nov 2002 14:17:21 -0000 1.40 --- libcurses.tex 12 Jan 2003 14:56:19 -0000 1.41 *************** *** 267,271 **** \begin{funcdesc}{initscr}{} Initialize the library. Returns a \class{WindowObject} which represents ! the whole screen. \end{funcdesc} --- 267,272 ---- \begin{funcdesc}{initscr}{} Initialize the library. Returns a \class{WindowObject} which represents ! the whole screen. \note{If there is an error opening the terminal, ! the underlying curses library may cause the interpreter to exit.} \end{funcdesc} From nnorwitz@users.sourceforge.net Sun Jan 12 14:57:55 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 12 Jan 2003 06:57:55 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libcurses.tex,1.37.6.1,1.37.6.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv27679/Doc/lib Modified Files: Tag: release22-maint libcurses.tex Log Message: Backport last change: SF #665570, curses causes interpreter crash The interpreter doesn't crash, but it does call exit() in libncurses. Add a note to this effect. Index: libcurses.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcurses.tex,v retrieving revision 1.37.6.1 retrieving revision 1.37.6.2 diff -C2 -d -r1.37.6.1 -r1.37.6.2 *** libcurses.tex 28 Dec 2001 04:31:36 -0000 1.37.6.1 --- libcurses.tex 12 Jan 2003 14:57:53 -0000 1.37.6.2 *************** *** 267,271 **** \begin{funcdesc}{initscr}{} Initialize the library. Returns a \class{WindowObject} which represents ! the whole screen. \end{funcdesc} --- 267,272 ---- \begin{funcdesc}{initscr}{} Initialize the library. Returns a \class{WindowObject} which represents ! the whole screen. \note{If there is an error opening the terminal, ! the underlying curses library may cause the interpreter to exit.} \end{funcdesc} From nnorwitz@users.sourceforge.net Sun Jan 12 15:04:57 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 12 Jan 2003 07:04:57 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib liboperator.tex,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv30126/Doc/lib Modified Files: liboperator.tex Log Message: Try to make a sentance more readable. Index: liboperator.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liboperator.tex,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** liboperator.tex 11 Jan 2003 23:15:47 -0000 1.24 --- liboperator.tex 12 Jan 2003 15:04:54 -0000 1.25 *************** *** 61,65 **** \begin{funcdesc}{truth}{o} Return \constant{True} if \var{o} is true, and \constant{False} ! otherwise. This is equivalent to the constructor of the \class{bool} constructor. \end{funcdesc} --- 61,65 ---- \begin{funcdesc}{truth}{o} Return \constant{True} if \var{o} is true, and \constant{False} ! otherwise. This is equivalent to using the \class{bool} constructor. \end{funcdesc} From jackjansen@users.sourceforge.net Sun Jan 12 23:01:51 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 12 Jan 2003 15:01:51 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/file _Filemodule.c,1.11,1.12 filescan.py,1.6,1.7 filesupport.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/file In directory sc8-pr-cvs1:/tmp/cvs-serv2822 Modified Files: _Filemodule.c filescan.py filesupport.py Log Message: Implemented FSCatalogInfo. Index: _Filemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/_Filemodule.c,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** _Filemodule.c 26 Dec 2002 20:45:43 -0000 1.11 --- _Filemodule.c 12 Jan 2003 23:01:44 -0000 1.12 *************** *** 55,58 **** --- 55,73 ---- /* + ** UTCDateTime records + */ + static int + UTCDateTime_Convert(PyObject *v, UTCDateTime *ptr) + { + return PyArg_Parse(v, "(HlH)", &ptr->highSeconds, &ptr->lowSeconds, &ptr->fraction); + } + + static PyObject * + UTCDateTime_New(UTCDateTime *ptr) + { + return Py_BuildValue("(HlH)", ptr->highSeconds, ptr->lowSeconds, ptr->fraction); + } + + /* ** Optional fsspec and fsref pointers. None will pass NULL */ *************** *** 87,93 **** } - static PyObject *File_Error; /* ----------------------- Object type FInfo ------------------------ */ --- 102,471 ---- } static PyObject *File_Error; + /* ------------------- Object type FSCatalogInfo -------------------- */ + + static PyTypeObject FSCatalogInfo_Type; + + #define FSCatalogInfo_Check(x) ((x)->ob_type == &FSCatalogInfo_Type || PyObject_TypeCheck((x), &FSCatalogInfo_Type)) + + typedef struct FSCatalogInfoObject { + PyObject_HEAD + FSCatalogInfo ob_itself; + } FSCatalogInfoObject; + + static PyObject *FSCatalogInfo_New(FSCatalogInfo *itself) + { + FSCatalogInfoObject *it; + if (itself == NULL) return Py_None; + it = PyObject_NEW(FSCatalogInfoObject, &FSCatalogInfo_Type); + if (it == NULL) return NULL; + it->ob_itself = *itself; + return (PyObject *)it; + } + static int FSCatalogInfo_Convert(PyObject *v, FSCatalogInfo *p_itself) + { + if (!FSCatalogInfo_Check(v)) + { + PyErr_SetString(PyExc_TypeError, "FSCatalogInfo required"); + return 0; + } + *p_itself = ((FSCatalogInfoObject *)v)->ob_itself; + return 1; + } + + static void FSCatalogInfo_dealloc(FSCatalogInfoObject *self) + { + /* Cleanup of self->ob_itself goes here */ + self->ob_type->tp_free((PyObject *)self); + } + + static PyMethodDef FSCatalogInfo_methods[] = { + {NULL, NULL, 0} + }; + + static PyObject *FSCatalogInfo_get_nodeFlags(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("H", self->ob_itself.nodeFlags); + } + + static int FSCatalogInfo_set_nodeFlags(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "H", &self->ob_itself.nodeFlags)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_volume(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("h", self->ob_itself.volume); + } + + static int FSCatalogInfo_set_volume(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "h", &self->ob_itself.volume)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_parentDirID(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("l", self->ob_itself.parentDirID); + } + + static int FSCatalogInfo_set_parentDirID(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "l", &self->ob_itself.parentDirID)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_nodeID(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("l", self->ob_itself.nodeID); + } + + static int FSCatalogInfo_set_nodeID(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "l", &self->ob_itself.nodeID)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_createDate(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.createDate); + } + + static int FSCatalogInfo_set_createDate(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.createDate)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_contentModDate(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.contentModDate); + } + + static int FSCatalogInfo_set_contentModDate(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.contentModDate)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_attributeModDate(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.attributeModDate); + } + + static int FSCatalogInfo_set_attributeModDate(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.attributeModDate)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_accessDate(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.accessDate); + } + + static int FSCatalogInfo_set_accessDate(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.accessDate)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_backupDate(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.backupDate); + } + + static int FSCatalogInfo_set_backupDate(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.backupDate)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_permissions(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("(llll)", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]); + } + + static int FSCatalogInfo_set_permissions(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "(llll)", &self->ob_itself.permissions[0], &self->ob_itself.permissions[1], &self->ob_itself.permissions[2], &self->ob_itself.permissions[3])-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_valence(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("l", self->ob_itself.valence); + } + + static int FSCatalogInfo_set_valence(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "l", &self->ob_itself.valence)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_dataLogicalSize(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("l", self->ob_itself.dataLogicalSize); + } + + static int FSCatalogInfo_set_dataLogicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "l", &self->ob_itself.dataLogicalSize)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_dataPhysicalSize(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("l", self->ob_itself.dataPhysicalSize); + } + + static int FSCatalogInfo_set_dataPhysicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "l", &self->ob_itself.dataPhysicalSize)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_rsrcLogicalSize(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("l", self->ob_itself.rsrcLogicalSize); + } + + static int FSCatalogInfo_set_rsrcLogicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "l", &self->ob_itself.rsrcLogicalSize)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_rsrcPhysicalSize(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("l", self->ob_itself.rsrcPhysicalSize); + } + + static int FSCatalogInfo_set_rsrcPhysicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "l", &self->ob_itself.rsrcPhysicalSize)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_sharingFlags(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("l", self->ob_itself.sharingFlags); + } + + static int FSCatalogInfo_set_sharingFlags(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "l", &self->ob_itself.sharingFlags)-1; + return 0; + } + + static PyObject *FSCatalogInfo_get_userPrivileges(FSCatalogInfoObject *self, void *closure) + { + return Py_BuildValue("b", self->ob_itself.userPrivileges); + } + + static int FSCatalogInfo_set_userPrivileges(FSCatalogInfoObject *self, PyObject *v, void *closure) + { + return PyArg_Parse(v, "b", &self->ob_itself.userPrivileges)-1; + return 0; + } + + static PyGetSetDef FSCatalogInfo_getsetlist[] = { + {"nodeFlags", (getter)FSCatalogInfo_get_nodeFlags, (setter)FSCatalogInfo_set_nodeFlags, NULL}, + {"volume", (getter)FSCatalogInfo_get_volume, (setter)FSCatalogInfo_set_volume, NULL}, + {"parentDirID", (getter)FSCatalogInfo_get_parentDirID, (setter)FSCatalogInfo_set_parentDirID, NULL}, + {"nodeID", (getter)FSCatalogInfo_get_nodeID, (setter)FSCatalogInfo_set_nodeID, NULL}, + {"createDate", (getter)FSCatalogInfo_get_createDate, (setter)FSCatalogInfo_set_createDate, NULL}, + {"contentModDate", (getter)FSCatalogInfo_get_contentModDate, (setter)FSCatalogInfo_set_contentModDate, NULL}, + {"attributeModDate", (getter)FSCatalogInfo_get_attributeModDate, (setter)FSCatalogInfo_set_attributeModDate, NULL}, + {"accessDate", (getter)FSCatalogInfo_get_accessDate, (setter)FSCatalogInfo_set_accessDate, NULL}, + {"backupDate", (getter)FSCatalogInfo_get_backupDate, (setter)FSCatalogInfo_set_backupDate, NULL}, + {"permissions", (getter)FSCatalogInfo_get_permissions, (setter)FSCatalogInfo_set_permissions, NULL}, + {"valence", (getter)FSCatalogInfo_get_valence, (setter)FSCatalogInfo_set_valence, NULL}, + {"dataLogicalSize", (getter)FSCatalogInfo_get_dataLogicalSize, (setter)FSCatalogInfo_set_dataLogicalSize, NULL}, + {"dataPhysicalSize", (getter)FSCatalogInfo_get_dataPhysicalSize, (setter)FSCatalogInfo_set_dataPhysicalSize, NULL}, + {"rsrcLogicalSize", (getter)FSCatalogInfo_get_rsrcLogicalSize, (setter)FSCatalogInfo_set_rsrcLogicalSize, NULL}, + {"rsrcPhysicalSize", (getter)FSCatalogInfo_get_rsrcPhysicalSize, (setter)FSCatalogInfo_set_rsrcPhysicalSize, NULL}, + {"sharingFlags", (getter)FSCatalogInfo_get_sharingFlags, (setter)FSCatalogInfo_set_sharingFlags, NULL}, + {"userPrivileges", (getter)FSCatalogInfo_get_userPrivileges, (setter)FSCatalogInfo_set_userPrivileges, NULL}, + {NULL, NULL, NULL, NULL}, + }; + + + #define FSCatalogInfo_compare NULL + + #define FSCatalogInfo_repr NULL + + #define FSCatalogInfo_hash NULL + static int FSCatalogInfo_tp_init(PyObject *self, PyObject *args, PyObject *kwds) + { + static char *kw[] = { + "nodeFlags", + "volume", + "parentDirID", + "nodeID", + "createDate", + "contentModDate", + "atributeModDate", + "accessDate", + "backupDate", + "permissions", + "valence", + "dataLogicalSize", + "dataPhysicalSize", + "rsrcLogicalSize", + "rsrcPhysicalSize", + "sharingFlags", + "userPrivileges" + , 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|HhllO&O&O&O&O&(llll)llllllb", kw, &((FSCatalogInfoObject *)self)->ob_itself.nodeFlags, + &((FSCatalogInfoObject *)self)->ob_itself.volume, + &((FSCatalogInfoObject *)self)->ob_itself.parentDirID, + &((FSCatalogInfoObject *)self)->ob_itself.nodeID, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.createDate, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.contentModDate, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.attributeModDate, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.accessDate, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.backupDate, + &((FSCatalogInfoObject *)self)->ob_itself.permissions[0], + &((FSCatalogInfoObject *)self)->ob_itself.permissions[1], + &((FSCatalogInfoObject *)self)->ob_itself.permissions[2], + &((FSCatalogInfoObject *)self)->ob_itself.permissions[3], + &((FSCatalogInfoObject *)self)->ob_itself.valence, + &((FSCatalogInfoObject *)self)->ob_itself.dataLogicalSize, + &((FSCatalogInfoObject *)self)->ob_itself.dataPhysicalSize, + &((FSCatalogInfoObject *)self)->ob_itself.rsrcLogicalSize, + &((FSCatalogInfoObject *)self)->ob_itself.rsrcPhysicalSize, + &((FSCatalogInfoObject *)self)->ob_itself.sharingFlags, + &((FSCatalogInfoObject *)self)->ob_itself.userPrivileges)) + { + return -1; + } + return 0; + } + + #define FSCatalogInfo_tp_alloc PyType_GenericAlloc + + static PyObject *FSCatalogInfo_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *self; + + if ((self = type->tp_alloc(type, 0)) == NULL) return NULL; + memset(&((FSCatalogInfoObject *)self)->ob_itself, 0, sizeof(FSCatalogInfo)); + return self; + } + + #define FSCatalogInfo_tp_free PyObject_Del + + + static PyTypeObject FSCatalogInfo_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Carbon.File.FSCatalogInfo", /*tp_name*/ + sizeof(FSCatalogInfoObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) FSCatalogInfo_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)0, /*tp_getattr*/ + (setattrfunc)0, /*tp_setattr*/ + (cmpfunc) FSCatalogInfo_compare, /*tp_compare*/ + (reprfunc) FSCatalogInfo_repr, /*tp_repr*/ + (PyNumberMethods *)0, /* tp_as_number */ + (PySequenceMethods *)0, /* tp_as_sequence */ + (PyMappingMethods *)0, /* tp_as_mapping */ + (hashfunc) FSCatalogInfo_hash, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + PyObject_GenericSetAttr, /*tp_setattro */ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + FSCatalogInfo_methods, /* tp_methods */ + 0, /*tp_members*/ + FSCatalogInfo_getsetlist, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + FSCatalogInfo_tp_init, /* tp_init */ + FSCatalogInfo_tp_alloc, /* tp_alloc */ + FSCatalogInfo_tp_new, /* tp_new */ + FSCatalogInfo_tp_free, /* tp_free */ + }; + + /* ----------------- End object type FSCatalogInfo ------------------ */ + + /* ----------------------- Object type FInfo ------------------------ */ *************** *** 204,208 **** { FInfo *itself = NULL; ! char *kw[] = {"itself", 0}; if (PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kw, FInfo_Convert, &itself)) --- 582,586 ---- { FInfo *itself = NULL; ! static char *kw[] = {"itself", 0}; if (PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kw, FInfo_Convert, &itself)) *************** *** 529,533 **** int rawdatalen = 0; Handle h; ! char *kw[] = {"itself", "rawdata", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&s#", kw, Alias_Convert, &itself, &rawdata, &rawdatalen)) --- 907,911 ---- int rawdatalen = 0; Handle h; ! static char *kw[] = {"itself", "rawdata", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&s#", kw, Alias_Convert, &itself, &rawdata, &rawdatalen)) *************** *** 991,995 **** char *rawdata = NULL; int rawdatalen = 0; ! char *kw[] = {"itself", "rawdata", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Os#", kw, &v, &rawdata, &rawdatalen)) --- 1369,1373 ---- char *rawdata = NULL; int rawdatalen = 0; ! static char *kw[] = {"itself", "rawdata", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Os#", kw, &v, &rawdata, &rawdatalen)) *************** *** 1147,1150 **** --- 1525,1591 ---- } + static PyObject *FSRef_FSCreateFileUnicode(FSRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + OSErr _err; + UniChar *nameLength__in__; + UniCharCount nameLength__len__; + int nameLength__in_len__; + FSCatalogInfoBitmap whichInfo; + FSCatalogInfo catalogInfo; + FSRef newRef; + FSSpec newSpec; + if (!PyArg_ParseTuple(_args, "u#lO&", + &nameLength__in__, &nameLength__in_len__, + &whichInfo, + FSCatalogInfo_Convert, &catalogInfo)) + return NULL; + nameLength__len__ = nameLength__in_len__; + _err = FSCreateFileUnicode(&_self->ob_itself, + nameLength__len__, nameLength__in__, + whichInfo, + &catalogInfo, + &newRef, + &newSpec); + if (_err != noErr) return PyMac_Error(_err); + _res = Py_BuildValue("O&O&", + FSRef_New, &newRef, + FSSpec_New, &newSpec); + return _res; + } + + static PyObject *FSRef_FSCreateDirectoryUnicode(FSRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + OSErr _err; + UniChar *nameLength__in__; + UniCharCount nameLength__len__; + int nameLength__in_len__; + FSCatalogInfoBitmap whichInfo; + FSCatalogInfo catalogInfo; + FSRef newRef; + FSSpec newSpec; + UInt32 newDirID; + if (!PyArg_ParseTuple(_args, "u#lO&", + &nameLength__in__, &nameLength__in_len__, + &whichInfo, + FSCatalogInfo_Convert, &catalogInfo)) + return NULL; + nameLength__len__ = nameLength__in_len__; + _err = FSCreateDirectoryUnicode(&_self->ob_itself, + nameLength__len__, nameLength__in__, + whichInfo, + &catalogInfo, + &newRef, + &newSpec, + &newDirID); + if (_err != noErr) return PyMac_Error(_err); + _res = Py_BuildValue("O&O&l", + FSRef_New, &newRef, + FSSpec_New, &newSpec, + newDirID); + return _res; + } + static PyObject *FSRef_FSDeleteObject(FSRefObject *_self, PyObject *_args) { *************** *** 1218,1221 **** --- 1659,1708 ---- } + static PyObject *FSRef_FSGetCatalogInfo(FSRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + OSErr _err; + FSCatalogInfoBitmap whichInfo; + FSCatalogInfo catalogInfo; + HFSUniStr255 outName; + FSSpec fsSpec; + FSRef parentRef; + if (!PyArg_ParseTuple(_args, "l", + &whichInfo)) + return NULL; + _err = FSGetCatalogInfo(&_self->ob_itself, + whichInfo, + &catalogInfo, + &outName, + &fsSpec, + &parentRef); + if (_err != noErr) return PyMac_Error(_err); + _res = Py_BuildValue("O&O&O&O&", + FSCatalogInfo_New, &catalogInfo, + PyMac_BuildHFSUniStr255, &outName, + FSSpec_New, &fsSpec, + FSRef_New, &parentRef); + return _res; + } + + static PyObject *FSRef_FSSetCatalogInfo(FSRefObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + OSErr _err; + FSCatalogInfoBitmap whichInfo; + FSCatalogInfo catalogInfo; + if (!PyArg_ParseTuple(_args, "lO&", + &whichInfo, + FSCatalogInfo_Convert, &catalogInfo)) + return NULL; + _err = FSSetCatalogInfo(&_self->ob_itself, + whichInfo, + &catalogInfo); + if (_err != noErr) return PyMac_Error(_err); + Py_INCREF(Py_None); + _res = Py_None; + return _res; + } + static PyObject *FSRef_FSCreateFork(FSRefObject *_self, PyObject *_args) { *************** *** 1369,1372 **** --- 1856,1863 ---- {"FSCompareFSRefs", (PyCFunction)FSRef_FSCompareFSRefs, 1, PyDoc_STR("(FSRef ref2) -> None")}, + {"FSCreateFileUnicode", (PyCFunction)FSRef_FSCreateFileUnicode, 1, + PyDoc_STR("(Buffer nameLength, FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> (FSRef newRef, FSSpec newSpec)")}, + {"FSCreateDirectoryUnicode", (PyCFunction)FSRef_FSCreateDirectoryUnicode, 1, + PyDoc_STR("(Buffer nameLength, FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> (FSRef newRef, FSSpec newSpec, UInt32 newDirID)")}, {"FSDeleteObject", (PyCFunction)FSRef_FSDeleteObject, 1, PyDoc_STR("() -> None")}, *************** *** 1377,1380 **** --- 1868,1875 ---- {"FSRenameUnicode", (PyCFunction)FSRef_FSRenameUnicode, 1, PyDoc_STR("(Buffer nameLength, TextEncoding textEncodingHint) -> (FSRef newRef)")}, + {"FSGetCatalogInfo", (PyCFunction)FSRef_FSGetCatalogInfo, 1, + PyDoc_STR("(FSCatalogInfoBitmap whichInfo) -> (FSCatalogInfo catalogInfo, HFSUniStr255 outName, FSSpec fsSpec, FSRef parentRef)")}, + {"FSSetCatalogInfo", (PyCFunction)FSRef_FSSetCatalogInfo, 1, + PyDoc_STR("(FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> None")}, {"FSCreateFork", (PyCFunction)FSRef_FSCreateFork, 1, PyDoc_STR("(Buffer forkNameLength) -> None")}, *************** *** 1422,1426 **** char *rawdata = NULL; int rawdatalen = 0; ! char *kw[] = {"itself", "rawdata", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Os#", kw, &v, &rawdata, &rawdatalen)) --- 1917,1921 ---- char *rawdata = NULL; int rawdatalen = 0; ! static char *kw[] = {"itself", "rawdata", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Os#", kw, &v, &rawdata, &rawdatalen)) *************** *** 2742,2745 **** --- 3237,3247 ---- PyDict_SetItemString(d, "Error", File_Error) != 0) return; + FSCatalogInfo_Type.ob_type = &PyType_Type; + if (PyType_Ready(&FSCatalogInfo_Type) < 0) return; + Py_INCREF(&FSCatalogInfo_Type); + PyModule_AddObject(m, "FSCatalogInfo", (PyObject *)&FSCatalogInfo_Type); + /* Backward-compatible name */ + Py_INCREF(&FSCatalogInfo_Type); + PyModule_AddObject(m, "FSCatalogInfoType", (PyObject *)&FSCatalogInfo_Type); FInfo_Type.ob_type = &PyType_Type; if (PyType_Ready(&FInfo_Type) < 0) return; Index: filescan.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filescan.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** filescan.py 9 Jan 2003 23:37:36 -0000 1.6 --- filescan.py 12 Jan 2003 23:01:46 -0000 1.7 *************** *** 180,193 **** [('OptFSRefPtr', 'fromFile', 'InMode')]), ! # FSCatalogInfo input handling ! ([('FSCatalogInfoBitmap', 'whichInfo', 'InMode'), ! ('FSCatalogInfo_ptr', 'catalogInfo', 'InMode')], ! [('FSCatalogInfoAndBitmap_in', 'catalogInfo', 'InMode')]), ! ! # FSCatalogInfo output handling ! ([('FSCatalogInfoBitmap', 'whichInfo', 'InMode'), ! ('FSCatalogInfo', 'catalogInfo', 'OutMode')], ! [('FSCatalogInfoAndBitmap_out', 'catalogInfo', 'InOutMode')]), ! ] --- 180,193 ---- [('OptFSRefPtr', 'fromFile', 'InMode')]), ! ## # FSCatalogInfo input handling ! ## ([('FSCatalogInfoBitmap', 'whichInfo', 'InMode'), ! ## ('FSCatalogInfo_ptr', 'catalogInfo', 'InMode')], ! ## [('FSCatalogInfoAndBitmap_in', 'catalogInfo', 'InMode')]), ! ## ! ## # FSCatalogInfo output handling ! ## ([('FSCatalogInfoBitmap', 'whichInfo', 'InMode'), ! ## ('FSCatalogInfo', 'catalogInfo', 'OutMode')], ! ## [('FSCatalogInfoAndBitmap_out', 'catalogInfo', 'InOutMode')]), ! ## ] Index: filesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filesupport.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** filesupport.py 9 Jan 2003 23:37:37 -0000 1.10 --- filesupport.py 12 Jan 2003 23:01:46 -0000 1.11 *************** *** 58,63 **** def declare(self, name): ! Output("PyObject *%s__object;", name) ! Output("FSCatalogInfoBitname %s__bitmap;", name) Output("FSCatalogInfo %s;", name) --- 58,63 ---- def declare(self, name): ! Output("PyObject *%s__object = NULL;", name) ! Output("FSCatalogInfoBitmap %s__bitmap = 0;", name) Output("FSCatalogInfo %s;", name) *************** *** 69,76 **** def getargsCheck(self, name): ! Output("convert_FSCatalogInfo(%s__object, %s__bitmap, %s);", name, name, name) def passOutput(self, name): ! return "%s__bitmap, %s"% (name, name) def mkvalueFormat(self): --- 69,79 ---- def getargsCheck(self, name): ! Output("if (!convert_FSCatalogInfo(%s__object, %s__bitmap, &%s)) return NULL;", name, name, name) + def passInput(self, name): + return "%s__bitmap, &%s"% (name, name) + def passOutput(self, name): ! return "%s__bitmap, &%s"% (name, name) def mkvalueFormat(self): *************** *** 81,85 **** def xxxxmkvalueCheck(self, name): ! Output("%s__object = new_FSCatalogInfo(%s__bitmap, %s);", name, name) class FSCatalogInfoAndBitmap_inType(FSCatalogInfoAndBitmapType, InputOnlyMixIn): --- 84,88 ---- def xxxxmkvalueCheck(self, name): ! Output("if ((%s__object = new_FSCatalogInfo(%s__bitmap, &%s)) == NULL) return NULL;", name, name) class FSCatalogInfoAndBitmap_inType(FSCatalogInfoAndBitmapType, InputOnlyMixIn): *************** *** 108,113 **** FSRef_ptr = OpaqueType("FSRef", "FSRef") OptFSRefPtr = OptionalFSxxxType("FSRef", "BUG", "myPyMac_GetOptFSRefPtr") ! FSCatalogInfoAndBitmap_in = FSCatalogInfoAndBitmap_inType() ! FSCatalogInfoAndBitmap_out = FSCatalogInfoAndBitmap_outType() # To be done: --- 111,116 ---- FSRef_ptr = OpaqueType("FSRef", "FSRef") OptFSRefPtr = OptionalFSxxxType("FSRef", "BUG", "myPyMac_GetOptFSRefPtr") ! FSCatalogInfo = OpaqueType("FSCatalogInfo", "FSCatalogInfo") ! FSCatalogInfo_ptr = OpaqueType("FSCatalogInfo", "FSCatalogInfo") # To be done: *************** *** 154,157 **** --- 157,175 ---- /* + ** UTCDateTime records + */ + static int + UTCDateTime_Convert(PyObject *v, UTCDateTime *ptr) + { + return PyArg_Parse(v, "(HlH)", &ptr->highSeconds, &ptr->lowSeconds, &ptr->fraction); + } + + static PyObject * + UTCDateTime_New(UTCDateTime *ptr) + { + return Py_BuildValue("(HlH)", ptr->highSeconds, ptr->lowSeconds, ptr->fraction); + } + + /* ** Optional fsspec and fsref pointers. None will pass NULL */ *************** *** 185,189 **** return Py_BuildValue("u#", itself->unicode, itself->length); } - """ --- 203,206 ---- *************** *** 306,309 **** --- 323,483 ---- # Our object types: + class FSCatalogInfoDefinition(PEP253Mixin, ObjectDefinition): + getsetlist = [ + ("nodeFlags", + "return Py_BuildValue(\"H\", self->ob_itself.nodeFlags);", + "return PyArg_Parse(v, \"H\", &self->ob_itself.nodeFlags)-1;", + None + ), + ("volume", + "return Py_BuildValue(\"h\", self->ob_itself.volume);", + "return PyArg_Parse(v, \"h\", &self->ob_itself.volume)-1;", + None + ), + ("parentDirID", + "return Py_BuildValue(\"l\", self->ob_itself.parentDirID);", + "return PyArg_Parse(v, \"l\", &self->ob_itself.parentDirID)-1;", + None + ), + ("nodeID", + "return Py_BuildValue(\"l\", self->ob_itself.nodeID);", + "return PyArg_Parse(v, \"l\", &self->ob_itself.nodeID)-1;", + None + ), + ("createDate", + "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.createDate);", + "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.createDate)-1;", + None + ), + ("contentModDate", + "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.contentModDate);", + "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.contentModDate)-1;", + None + ), + ("attributeModDate", + "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.attributeModDate);", + "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.attributeModDate)-1;", + None + ), + ("accessDate", + "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.accessDate);", + "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.accessDate)-1;", + None + ), + ("backupDate", + "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.backupDate);", + "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.backupDate)-1;", + None + ), + ("permissions", + "return Py_BuildValue(\"(llll)\", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]);", + "return PyArg_Parse(v, \"(llll)\", &self->ob_itself.permissions[0], &self->ob_itself.permissions[1], &self->ob_itself.permissions[2], &self->ob_itself.permissions[3])-1;", + None + ), + # XXXX FinderInfo TBD + # XXXX FinderXInfo TBD + ("valence", + "return Py_BuildValue(\"l\", self->ob_itself.valence);", + "return PyArg_Parse(v, \"l\", &self->ob_itself.valence)-1;", + None + ), + ("dataLogicalSize", + "return Py_BuildValue(\"l\", self->ob_itself.dataLogicalSize);", + "return PyArg_Parse(v, \"l\", &self->ob_itself.dataLogicalSize)-1;", + None + ), + ("dataPhysicalSize", + "return Py_BuildValue(\"l\", self->ob_itself.dataPhysicalSize);", + "return PyArg_Parse(v, \"l\", &self->ob_itself.dataPhysicalSize)-1;", + None + ), + ("rsrcLogicalSize", + "return Py_BuildValue(\"l\", self->ob_itself.rsrcLogicalSize);", + "return PyArg_Parse(v, \"l\", &self->ob_itself.rsrcLogicalSize)-1;", + None + ), + ("rsrcPhysicalSize", + "return Py_BuildValue(\"l\", self->ob_itself.rsrcPhysicalSize);", + "return PyArg_Parse(v, \"l\", &self->ob_itself.rsrcPhysicalSize)-1;", + None + ), + ("sharingFlags", + "return Py_BuildValue(\"l\", self->ob_itself.sharingFlags);", + "return PyArg_Parse(v, \"l\", &self->ob_itself.sharingFlags)-1;", + None + ), + ("userPrivileges", + "return Py_BuildValue(\"b\", self->ob_itself.userPrivileges);", + "return PyArg_Parse(v, \"b\", &self->ob_itself.userPrivileges)-1;", + None + ), + ] + # The same info, but in a different form + INITFORMAT = "HhllO&O&O&O&O&(llll)llllllb" + INITARGS = """&((FSCatalogInfoObject *)self)->ob_itself.nodeFlags, + &((FSCatalogInfoObject *)self)->ob_itself.volume, + &((FSCatalogInfoObject *)self)->ob_itself.parentDirID, + &((FSCatalogInfoObject *)self)->ob_itself.nodeID, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.createDate, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.contentModDate, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.attributeModDate, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.accessDate, + UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.backupDate, + &((FSCatalogInfoObject *)self)->ob_itself.permissions[0], + &((FSCatalogInfoObject *)self)->ob_itself.permissions[1], + &((FSCatalogInfoObject *)self)->ob_itself.permissions[2], + &((FSCatalogInfoObject *)self)->ob_itself.permissions[3], + &((FSCatalogInfoObject *)self)->ob_itself.valence, + &((FSCatalogInfoObject *)self)->ob_itself.dataLogicalSize, + &((FSCatalogInfoObject *)self)->ob_itself.dataPhysicalSize, + &((FSCatalogInfoObject *)self)->ob_itself.rsrcLogicalSize, + &((FSCatalogInfoObject *)self)->ob_itself.rsrcPhysicalSize, + &((FSCatalogInfoObject *)self)->ob_itself.sharingFlags, + &((FSCatalogInfoObject *)self)->ob_itself.userPrivileges""" + INITNAMES = """ + "nodeFlags", + "volume", + "parentDirID", + "nodeID", + "createDate", + "contentModDate", + "atributeModDate", + "accessDate", + "backupDate", + "permissions", + "valence", + "dataLogicalSize", + "dataPhysicalSize", + "rsrcLogicalSize", + "rsrcPhysicalSize", + "sharingFlags", + "userPrivileges" + """ + + def __init__(self, name, prefix, itselftype): + ObjectDefinition.__init__(self, name, prefix, itselftype) + self.argref = "*" # Store FSSpecs, but pass them by address + + def outputCheckNewArg(self): + Output("if (itself == NULL) return Py_None;") + + def output_tp_newBody(self): + Output("PyObject *self;"); + Output() + Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") + Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));", + self.objecttype, self.itselftype) + Output("return self;") + + def output_tp_initBody(self): + Output("static char *kw[] = {%s, 0};", self.INITNAMES) + Output() + Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|%s\", kw, %s))", + self.INITFORMAT, self.INITARGS) + OutLbrace() + Output("return -1;") + OutRbrace() + Output("return 0;") + class FInfoDefinition(PEP253Mixin, ObjectDefinition): getsetlist = [ *************** *** 353,357 **** def output_tp_initBody(self): Output("%s *itself = NULL;", self.itselftype) ! Output("char *kw[] = {\"itself\", 0};") Output() Output("if (PyArg_ParseTupleAndKeywords(args, kwds, \"|O&\", kw, FInfo_Convert, &itself))") --- 527,531 ---- def output_tp_initBody(self): Output("%s *itself = NULL;", self.itselftype) ! Output("static char *kw[] = {\"itself\", 0};") Output() Output("if (PyArg_ParseTupleAndKeywords(args, kwds, \"|O&\", kw, FInfo_Convert, &itself))") *************** *** 395,399 **** Output("char *rawdata = NULL;") Output("int rawdatalen = 0;") ! Output("char *kw[] = {\"itself\", \"rawdata\", 0};") Output() Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))") --- 569,573 ---- Output("char *rawdata = NULL;") Output("int rawdatalen = 0;") ! Output("static char *kw[] = {\"itself\", \"rawdata\", 0};") Output() Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))") *************** *** 468,472 **** Output("char *rawdata = NULL;") Output("int rawdatalen = 0;") ! Output("char *kw[] = {\"itself\", \"rawdata\", 0};") Output() Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))") --- 642,646 ---- Output("char *rawdata = NULL;") Output("int rawdatalen = 0;") ! Output("static char *kw[] = {\"itself\", \"rawdata\", 0};") Output() Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))") *************** *** 544,548 **** Output("int rawdatalen = 0;") Output("Handle h;") ! Output("char *kw[] = {\"itself\", \"rawdata\", 0};") Output() Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|O&s#\", kw, %s_Convert, &itself, &rawdata, &rawdatalen))", --- 718,722 ---- Output("int rawdatalen = 0;") Output("Handle h;") ! Output("static char *kw[] = {\"itself\", \"rawdata\", 0};") Output() Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|O&s#\", kw, %s_Convert, &itself, &rawdata, &rawdatalen))", *************** *** 596,599 **** --- 770,774 ---- longname=LONGMODNAME) + fscataloginfoobject = FSCatalogInfoDefinition('FSCatalogInfo', 'FSCatalogInfo', 'FSCatalogInfo') finfoobject = FInfoDefinition('FInfo', 'FInfo', 'FInfo') aliasobject = AliasDefinition('Alias', 'Alias', 'AliasHandle') *************** *** 601,604 **** --- 776,780 ---- fsrefobject = FSRefDefinition('FSRef', 'FSRef', 'FSRef') + module.addobject(fscataloginfoobject) module.addobject(finfoobject) module.addobject(aliasobject) From rhettinger@users.sourceforge.net Mon Jan 13 04:29:22 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 12 Jan 2003 20:29:22 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex,1.116,1.117 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv12902 Modified Files: libstdtypes.tex Log Message: SF patch 664183 and SF bug 664044: Note that both u'%s' % 'x' and '%s' % u'x' return a unicode object. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -d -r1.116 -r1.117 *** libstdtypes.tex 2 Jan 2003 20:51:03 -0000 1.116 --- libstdtypes.tex 13 Jan 2003 04:29:19 -0000 1.117 *************** *** 835,839 **** \function{repr()}).}{(3)} \lineiii{s}{String (converts any python object using ! \function{str()}).}{} \lineiii{\%}{No argument is converted, results in a \character{\%} character in the result.}{} --- 835,839 ---- \function{repr()}).}{(3)} \lineiii{s}{String (converts any python object using ! \function{str()}).}{(4)} \lineiii{\%}{No argument is converted, results in a \character{\%} character in the result.}{} *************** *** 856,859 **** --- 856,862 ---- \item[(3)] The \code{\%r} conversion was added in Python 2.0. + \item[(4)] + If the object or format provided is a \class{unicode} string, + the resulting string will also be \class{unicode}. \end{description} From rhettinger@users.sourceforge.net Mon Jan 13 04:33:39 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 12 Jan 2003 20:33:39 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex,1.80.6.17,1.80.6.18 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv14215 Modified Files: Tag: release22-maint libstdtypes.tex Log Message: SF patch 664183 and SF bug 664044: Note that both u'%s' % 'x' and '%s' % u'x' return a unicode object. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.80.6.17 retrieving revision 1.80.6.18 diff -C2 -d -r1.80.6.17 -r1.80.6.18 *** libstdtypes.tex 29 Dec 2002 05:59:08 -0000 1.80.6.17 --- libstdtypes.tex 13 Jan 2003 04:33:36 -0000 1.80.6.18 *************** *** 827,831 **** \function{repr()}).}{(3)} \lineiii{s}{String (converts any python object using ! \function{str()}).}{} \lineiii{\%}{No argument is converted, results in a \character{\%} character in the result.}{} --- 827,831 ---- \function{repr()}).}{(3)} \lineiii{s}{String (converts any python object using ! \function{str()}).}{(4)} \lineiii{\%}{No argument is converted, results in a \character{\%} character in the result.}{} *************** *** 848,851 **** --- 848,854 ---- \item[(3)] The \code{\%r} conversion was added in Python 2.0. + \item[(4)] + If the object or format provided is a \class{unicode} string, + the resulting string will also be \class{unicode}. \end{description} From akuchling@users.sourceforge.net Mon Jan 13 13:59:24 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 13 Jan 2003 05:59:24 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.106,1.107 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv13933 Modified Files: whatsnew23.tex Log Message: Link to MRO article Mention deprecation of string exceptions Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.106 retrieving revision 1.107 diff -C2 -d -r1.106 -r1.107 *** whatsnew23.tex 8 Jan 2003 05:27:42 -0000 1.106 --- whatsnew23.tex 13 Jan 2003 13:59:22 -0000 1.107 *************** *** 1055,1058 **** --- 1055,1062 ---- command line or use \function{warnings.filterwarnings()}. + \item The process of deprecating string-based exceptions, as + in \code{raise "Error occurred"}, has begun. Raising a string will + now trigger \exception{PendingDeprecationWarning}. + \item Using \code{None} as a variable name will now result in a \exception{SyntaxWarning} warning. In a future version of Python, *************** *** 1066,1071 **** the paper \ulink{``A Monotonic Superclass Linearization for Dylan''}{http://www.webcom.com/haahr/dylan/linearization-oopsla96.html}. ! To understand the motivation for this change, read the thread on ! python-dev starting with the message at \url{http://mail.python.org/pipermail/python-dev/2002-October/029035.html}. Samuele Pedroni first pointed out the problem and also implemented the --- 1070,1077 ---- the paper \ulink{``A Monotonic Superclass Linearization for Dylan''}{http://www.webcom.com/haahr/dylan/linearization-oopsla96.html}. ! To understand the motivation for this change, ! read Michele Simionato's article ! \ulink{``Python 2.3 Method Resolution Order''}{http://www.phyast.pitt.edu/~micheles/mro.html}, or ! read the thread on python-dev starting with the message at \url{http://mail.python.org/pipermail/python-dev/2002-October/029035.html}. Samuele Pedroni first pointed out the problem and also implemented the From gvanrossum@users.sourceforge.net Mon Jan 13 15:04:35 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 13 Jan 2003 07:04:35 -0800 Subject: [Python-checkins] python/dist/src/Lib imaplib.py,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv16013 Modified Files: imaplib.py Log Message: Fix NameError in getquotaroot(), sanctioned by Piers. Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** imaplib.py 24 Nov 2002 02:35:33 -0000 1.58 --- imaplib.py 13 Jan 2003 15:04:26 -0000 1.59 *************** *** 442,446 **** (typ, [[QUOTAROOT responses...], [QUOTA responses]]) = .getquotaroot(mailbox) """ ! typ, dat = self._simple_command('GETQUOTA', root) typ, quota = self._untagged_response(typ, dat, 'QUOTA') typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT') --- 442,446 ---- (typ, [[QUOTAROOT responses...], [QUOTA responses]]) = .getquotaroot(mailbox) """ ! typ, dat = self._simple_command('GETQUOTA', mailbox) typ, quota = self._untagged_response(typ, dat, 'QUOTA') typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT') From nnorwitz@users.sourceforge.net Mon Jan 13 16:09:00 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 08:09:00 -0800 Subject: [Python-checkins] python/dist/src/Include pydebug.h,2.21,2.22 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv30929/Include Modified Files: pydebug.h Log Message: Update comment, QnewFlag will go away in 3.0, not 2.3 Index: pydebug.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pydebug.h,v retrieving revision 2.21 retrieving revision 2.22 diff -C2 -d -r2.21 -r2.22 *** pydebug.h 29 Jul 2002 13:42:04 -0000 2.21 --- pydebug.h 13 Jan 2003 16:08:56 -0000 2.22 *************** *** 17,23 **** PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; PyAPI_DATA(int) Py_DivisionWarningFlag; ! /* _XXX Py_QnewFlag should go away in 2.3. It's true iff -Qnew is passed, on the command line, and is used in 2.2 by ceval.c to make all "/" divisions ! true divisions (which they will be in 2.3). */ PyAPI_DATA(int) _Py_QnewFlag; --- 17,23 ---- PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; PyAPI_DATA(int) Py_DivisionWarningFlag; ! /* _XXX Py_QnewFlag should go away in 3.0. It's true iff -Qnew is passed, on the command line, and is used in 2.2 by ceval.c to make all "/" divisions ! true divisions (which they will be in 3.0). */ PyAPI_DATA(int) _Py_QnewFlag; From akuchling@users.sourceforge.net Mon Jan 13 19:09:21 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 13 Jan 2003 11:09:21 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.107,1.108 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv14704 Modified Files: whatsnew23.tex Log Message: Move the date/time section into the modules section; it was in the C API section by mistake Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.107 retrieving revision 1.108 diff -C2 -d -r1.107 -r1.108 *** whatsnew23.tex 13 Jan 2003 13:59:22 -0000 1.107 --- whatsnew23.tex 13 Jan 2003 19:09:03 -0000 1.108 *************** *** 1649,1652 **** --- 1649,1713 ---- %====================================================================== + \subsection{Date/Time Type} + + Date and time types suitable for expressing timestamps were added as + the \module{datetime} module. The types don't support different + calendars or many fancy features, and just stick to the basics of + representing time. + + The three primary types are: \class{date}, representing a day, month, + and year; \class{time}, consisting of hour, minute, and second; and + \class{datetime}, which contains all the attributes of both + \class{date} and \class{time}. These basic types don't understand + time zones, but there are subclasses named \class{timetz} and + \class{datetimetz} that do. There's also a + \class{timedelta} class representing a difference between two points + in time, and time zone logic is implemented by classes inheriting from + the abstract \class{tzinfo} class. + + You can create instances of \class{date} and \class{time} by either + supplying keyword arguments to the appropriate constructor, + e.g. \code{datetime.date(year=1972, month=10, day=15)}, or by using + one of a number of class methods. For example, the \method{today()} + class method returns the current local date. + + Once created, instances of the date/time classes are all immutable. + There are a number of methods for producing formatted strings from + objects: + + \begin{verbatim} + >>> import datetime + >>> now = datetime.datetime.now() + >>> now.isoformat() + '2002-12-30T21:27:03.994956' + >>> now.ctime() # Only available on date, datetime + 'Mon Dec 30 21:27:03 2002' + >>> now.strftime('%Y %d %h') + '2002 30 Dec' + \end{verbatim} + + The \method{replace()} method allows modifying one or more fields + of a \class{date} or \class{datetime} instance: + + \begin{verbatim} + >>> d = datetime.datetime.now() + >>> d + datetime.datetime(2002, 12, 30, 22, 15, 38, 827738) + >>> d.replace(year=2001, hour = 12) + datetime.datetime(2001, 12, 30, 12, 15, 38, 827738) + >>> + \end{verbatim} + + Instances can be compared, hashed, and converted to strings (the + result is the same as that of \method{isoformat()}). \class{date} and + \class{datetime} instances can be subtracted from each other, and + added to \class{timedelta} instances. + + For more information, refer to the \ulink{module's reference + documentation}{http://www.python.org/dev/doc/devel/lib/module-datetime.html}. + (Contributed by Tim Peters.) + + + %====================================================================== \subsection{The \module{optparse} Module} *************** *** 1903,1967 **** \end{itemize} - - - %====================================================================== - \subsection{Date/Time Type} - - Date and time types suitable for expressing timestamps were added as - the \module{datetime} module. The types don't support different - calendars or many fancy features, and just stick to the basics of - representing time. - - The three primary types are: \class{date}, representing a day, month, - and year; \class{time}, consisting of hour, minute, and second; and - \class{datetime}, which contains all the attributes of both - \class{date} and \class{time}. These basic types don't understand - time zones, but there are subclasses named \class{timetz} and - \class{datetimetz} that do. There's also a - \class{timedelta} class representing a difference between two points - in time, and time zone logic is implemented by classes inheriting from - the abstract \class{tzinfo} class. - - You can create instances of \class{date} and \class{time} by either - supplying keyword arguments to the appropriate constructor, - e.g. \code{datetime.date(year=1972, month=10, day=15)}, or by using - one of a number of class methods. For example, the \method{today()} - class method returns the current local date. - - Once created, instances of the date/time classes are all immutable. - There are a number of methods for producing formatted strings from - objects: - - \begin{verbatim} - >>> import datetime - >>> now = datetime.datetime.now() - >>> now.isoformat() - '2002-12-30T21:27:03.994956' - >>> now.ctime() # Only available on date, datetime - 'Mon Dec 30 21:27:03 2002' - >>> now.strftime('%Y %d %h') - '2002 30 Dec' - \end{verbatim} - - The \method{replace()} method allows modifying one or more fields - of a \class{date} or \class{datetime} instance: - - \begin{verbatim} - >>> d = datetime.datetime.now() - >>> d - datetime.datetime(2002, 12, 30, 22, 15, 38, 827738) - >>> d.replace(year=2001, hour = 12) - datetime.datetime(2001, 12, 30, 12, 15, 38, 827738) - >>> - \end{verbatim} - - Instances can be compared, hashed, and converted to strings (the - result is the same as that of \method{isoformat()}). \class{date} and - \class{datetime} instances can be subtracted from each other, and - added to \class{timedelta} instances. - - For more information, refer to the \ulink{module's reference - documentation}{http://www.python.org/dev/doc/devel/lib/module-datetime.html}. - (Contributed by Tim Peters.) --- 1964,1967 ---- From nnorwitz@users.sourceforge.net Mon Jan 13 19:23:04 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 11:23:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.113.4.28,1.113.4.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv20748/Lib/test Modified Files: Tag: release22-maint test_descr.py Log Message: Get the test to pass again by backporting Guido's checkin 1.173: Disable the rexec test now that rexec is out of grace. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.113.4.28 retrieving revision 1.113.4.29 diff -C2 -d -r1.113.4.28 -r1.113.4.29 *** test_descr.py 7 Jan 2003 21:49:18 -0000 1.113.4.28 --- test_descr.py 13 Jan 2003 19:22:44 -0000 1.113.4.29 *************** *** 2159,2162 **** --- 2159,2164 ---- def restricted(): + # XXX This test is disabled because rexec is not deemed safe + return import rexec if verbose: From nnorwitz@users.sourceforge.net Mon Jan 13 19:24:10 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 11:24:10 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_bastion,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv21397/Lib/test/output Removed Files: Tag: release22-maint test_bastion Log Message: Backport Guido's checkins which disabled the bastion tests --- test_bastion DELETED --- From nnorwitz@users.sourceforge.net Mon Jan 13 19:24:41 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 11:24:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_bastion.py,1.1,1.1.24.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv21397/Lib/test Modified Files: Tag: release22-maint test_bastion.py Log Message: Backport Guido's checkins which disabled the bastion tests Index: test_bastion.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bastion.py,v retrieving revision 1.1 retrieving revision 1.1.24.1 diff -C2 -d -r1.1 -r1.1.24.1 *** test_bastion.py 19 Jan 2001 03:22:48 -0000 1.1 --- test_bastion.py 13 Jan 2003 19:24:01 -0000 1.1.24.1 *************** *** 1,3 **** ! import Bastion ! ! Bastion._test() --- 1,3 ---- ! ##import Bastion ! ## ! ##Bastion._test() From nnorwitz@users.sourceforge.net Mon Jan 13 19:29:47 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 11:29:47 -0800 Subject: [Python-checkins] python/dist/src/Lib macpath.py,1.31.10.1,1.31.10.2 ntpath.py,1.44.8.2,1.44.8.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv23967/Lib Modified Files: Tag: release22-maint macpath.py ntpath.py Log Message: supports_unicode_filenames should not have been backported, test___all__ now passed Index: macpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/macpath.py,v retrieving revision 1.31.10.1 retrieving revision 1.31.10.2 diff -C2 -d -r1.31.10.1 -r1.31.10.2 *** macpath.py 10 Jan 2003 23:47:53 -0000 1.31.10.1 --- macpath.py 13 Jan 2003 19:29:35 -0000 1.31.10.2 *************** *** 8,12 **** "getatime","islink","exists","isdir","isfile", "walk","expanduser","expandvars","normpath","abspath", ! "realpath","supports_unicode_filenames"] # Normalize the case of a pathname. Dummy in Posix, but .lower() here. --- 8,12 ---- "getatime","islink","exists","isdir","isfile", "walk","expanduser","expandvars","normpath","abspath", ! "realpath"] # Normalize the case of a pathname. Dummy in Posix, but .lower() here. Index: ntpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ntpath.py,v retrieving revision 1.44.8.2 retrieving revision 1.44.8.3 diff -C2 -d -r1.44.8.2 -r1.44.8.3 *** ntpath.py 10 Jan 2003 23:47:53 -0000 1.44.8.2 --- ntpath.py 13 Jan 2003 19:29:38 -0000 1.44.8.3 *************** *** 13,17 **** "getatime","islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath","splitunc", ! "realpath","supports_unicode_filenames"] # Normalize the case of a pathname and map slashes to backslashes. --- 13,17 ---- "getatime","islink","exists","isdir","isfile","ismount", "walk","expanduser","expandvars","normpath","abspath","splitunc", ! "realpath"] # Normalize the case of a pathname and map slashes to backslashes. From nnorwitz@users.sourceforge.net Mon Jan 13 20:13:26 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 12:13:26 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.612,1.613 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv7787/Misc Modified Files: NEWS Log Message: Fix SF bug #667147, Segmentation fault printing str subclass Fix infinite recursion which occurred when printing an object whose __str__() returned self. Will backport Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.612 retrieving revision 1.613 diff -C2 -d -r1.612 -r1.613 *** NEWS 10 Jan 2003 23:29:48 -0000 1.612 --- NEWS 13 Jan 2003 20:13:12 -0000 1.613 *************** *** 19,22 **** --- 19,25 ---- arguments. + - Fixed crash when printing a subclass of str and __str__ returned self. + See SF bug #667147. + Extension modules ----------------- From nnorwitz@users.sourceforge.net Mon Jan 13 20:13:44 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 12:13:44 -0800 Subject: [Python-checkins] python/dist/src/Objects object.c,2.194,2.195 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv7787/Objects Modified Files: object.c Log Message: Fix SF bug #667147, Segmentation fault printing str subclass Fix infinite recursion which occurred when printing an object whose __str__() returned self. Will backport Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.194 retrieving revision 2.195 diff -C2 -d -r2.194 -r2.195 *** object.c 17 Nov 2002 17:52:44 -0000 2.194 --- object.c 13 Jan 2003 20:13:04 -0000 2.195 *************** *** 159,166 **** } ! int ! PyObject_Print(PyObject *op, FILE *fp, int flags) { int ret = 0; if (PyErr_CheckSignals()) return -1; --- 159,171 ---- } ! /* Implementation of PyObject_Print with recursion checking */ ! static int ! internal_print(PyObject *op, FILE *fp, int flags, int nesting) { int ret = 0; + if (nesting > 10) { + PyErr_SetString(PyExc_RuntimeError, "print recursion"); + return -1; + } if (PyErr_CheckSignals()) return -1; *************** *** 188,192 **** ret = -1; else { ! ret = PyObject_Print(s, fp, Py_PRINT_RAW); } Py_XDECREF(s); --- 193,198 ---- ret = -1; else { ! ret = internal_print(s, fp, Py_PRINT_RAW, ! nesting+1); } Py_XDECREF(s); *************** *** 204,207 **** --- 210,220 ---- return ret; } + + int + PyObject_Print(PyObject *op, FILE *fp, int flags) + { + return internal_print(op, fp, flags, 0); + } + /* For debugging convenience. See Misc/gdbinit for some useful gdb hooks */ From nnorwitz@users.sourceforge.net Mon Jan 13 20:13:46 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 12:13:46 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.176,1.177 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv7787/Lib/test Modified Files: test_descr.py Log Message: Fix SF bug #667147, Segmentation fault printing str subclass Fix infinite recursion which occurred when printing an object whose __str__() returned self. Will backport Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.176 retrieving revision 1.177 diff -C2 -d -r1.176 -r1.177 *** test_descr.py 7 Jan 2003 13:41:37 -0000 1.176 --- test_descr.py 13 Jan 2003 20:13:09 -0000 1.177 *************** *** 1,5 **** # Test enhancements related to descriptors and new-style classes ! from test.test_support import verify, vereq, verbose, TestFailed, TESTFN from copy import deepcopy import warnings --- 1,5 ---- # Test enhancements related to descriptors and new-style classes ! from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout from copy import deepcopy import warnings *************** *** 1821,1824 **** --- 1821,1847 ---- unsafecmp(1, 1L) unsafecmp(1L, 1) + + class Letter(str): + def __new__(cls, letter): + if letter == 'EPS': + return str.__new__(cls) + return str.__new__(cls, letter) + def __str__(self): + if not self: + return 'EPS' + return self + + # sys.stdout needs to be the original to trigger the recursion bug + import sys + test_stdout = sys.stdout + sys.stdout = get_original_stdout() + try: + # nothing should actually be printed, this should raise an exception + print Letter('w') + except RuntimeError: + pass + else: + raise TestFailed, "expected a RuntimeError for print recursion" + sys.stdout = test_stdout def weakrefs(): From nnorwitz@users.sourceforge.net Mon Jan 13 20:17:55 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 12:17:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.113.4.29,1.113.4.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv10337/Lib/test Modified Files: Tag: release22-maint test_descr.py Log Message: Backport: Fix SF bug #667147, Segmentation fault printing str subclass Fix infinite recursion which occurred when printing an object whose __str__() returned self. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.113.4.29 retrieving revision 1.113.4.30 diff -C2 -d -r1.113.4.29 -r1.113.4.30 *** test_descr.py 13 Jan 2003 19:22:44 -0000 1.113.4.29 --- test_descr.py 13 Jan 2003 20:17:13 -0000 1.113.4.30 *************** *** 1,5 **** # Test enhancements related to descriptors and new-style classes ! from test_support import verify, vereq, verbose, TestFailed, TESTFN from copy import deepcopy import warnings --- 1,5 ---- # Test enhancements related to descriptors and new-style classes ! from test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout from copy import deepcopy import warnings *************** *** 1605,1608 **** --- 1605,1631 ---- unsafecmp(1, 1L) unsafecmp(1L, 1) + + class Letter(str): + def __new__(cls, letter): + if letter == 'EPS': + return str.__new__(cls) + return str.__new__(cls, letter) + def __str__(self): + if not self: + return 'EPS' + return self + + # sys.stdout needs to be the original to trigger the recursion bug + import sys + test_stdout = sys.stdout + sys.stdout = get_original_stdout() + try: + # nothing should actually be printed, this should raise an exception + print Letter('w') + except RuntimeError: + pass + else: + raise TestFailed, "expected a RuntimeError for print recursion" + sys.stdout = test_stdout def weakrefs(): From nnorwitz@users.sourceforge.net Mon Jan 13 20:18:18 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 12:18:18 -0800 Subject: [Python-checkins] python/dist/src/Objects object.c,2.162.6.8,2.162.6.9 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv10337/Objects Modified Files: Tag: release22-maint object.c Log Message: Backport: Fix SF bug #667147, Segmentation fault printing str subclass Fix infinite recursion which occurred when printing an object whose __str__() returned self. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.162.6.8 retrieving revision 2.162.6.9 diff -C2 -d -r2.162.6.8 -r2.162.6.9 *** object.c 16 Dec 2002 22:32:46 -0000 2.162.6.8 --- object.c 13 Jan 2003 20:17:04 -0000 2.162.6.9 *************** *** 147,154 **** } ! int ! PyObject_Print(PyObject *op, FILE *fp, int flags) { int ret = 0; if (PyErr_CheckSignals()) return -1; --- 147,159 ---- } ! /* Implementation of PyObject_Print with recursion checking */ ! static int ! internal_print(PyObject *op, FILE *fp, int flags, int nesting) { int ret = 0; + if (nesting > 10) { + PyErr_SetString(PyExc_RuntimeError, "print recursion"); + return -1; + } if (PyErr_CheckSignals()) return -1; *************** *** 176,180 **** ret = -1; else { ! ret = PyObject_Print(s, fp, Py_PRINT_RAW); } Py_XDECREF(s); --- 181,186 ---- ret = -1; else { ! ret = internal_print(s, fp, Py_PRINT_RAW, ! nesting+1); } Py_XDECREF(s); *************** *** 192,195 **** --- 198,208 ---- return ret; } + + int + PyObject_Print(PyObject *op, FILE *fp, int flags) + { + return internal_print(op, fp, flags, 0); + } + /* For debugging convenience. See Misc/gdbinit for some useful gdb hooks */ From nnorwitz@users.sourceforge.net Mon Jan 13 20:18:24 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 13 Jan 2003 12:18:24 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.55,1.337.2.4.2.56 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv10337/Misc Modified Files: Tag: release22-maint NEWS Log Message: Backport: Fix SF bug #667147, Segmentation fault printing str subclass Fix infinite recursion which occurred when printing an object whose __str__() returned self. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.55 retrieving revision 1.337.2.4.2.56 diff -C2 -d -r1.337.2.4.2.55 -r1.337.2.4.2.56 *** NEWS 11 Jan 2003 23:42:07 -0000 1.337.2.4.2.55 --- NEWS 13 Jan 2003 20:17:22 -0000 1.337.2.4.2.56 *************** *** 61,64 **** --- 61,66 ---- - SF #659228, fix realpath() not being exported from os.path + - SF #667147, fix crash when printing str subclass. + What's New in Python 2.2.2 (final) ? Release date: 14-Oct-2002 From gvanrossum@users.sourceforge.net Mon Jan 13 21:14:00 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 13 Jan 2003 13:14:00 -0800 Subject: [Python-checkins] python/dist/src/Lib pdb.py,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv31577 Modified Files: pdb.py Log Message: Duh. The do_EOF() implementation was bogus. Make it more like do_quit() -- but print a blank line first. Index: pdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pdb.py,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** pdb.py 17 Dec 2002 16:15:19 -0000 1.59 --- pdb.py 13 Jan 2003 21:13:55 -0000 1.60 *************** *** 194,200 **** do_h = cmd.Cmd.do_help - def do_EOF(self, arg): - return 0 # Don't die on EOF - def do_break(self, arg, temporary = 0): # break [ ([filename:]lineno | function) [, "condition"] ] --- 194,197 ---- *************** *** 531,534 **** --- 528,536 ---- do_q = do_quit do_exit = do_quit + + def do_EOF(self, arg): + print + self.set_quit() + return 1 def do_args(self, arg): From gvanrossum@users.sourceforge.net Mon Jan 13 21:16:44 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 13 Jan 2003 13:16:44 -0800 Subject: [Python-checkins] python/dist/src/Lib pdb.py,1.51.24.3,1.51.24.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv32387 Modified Files: Tag: release22-maint pdb.py Log Message: Backport 1.60 from trunk: Duh. The do_EOF() implementation was bogus. Make it more like do_quit() -- but print a blank line first. Index: pdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pdb.py,v retrieving revision 1.51.24.3 retrieving revision 1.51.24.4 diff -C2 -d -r1.51.24.3 -r1.51.24.4 *** pdb.py 24 Sep 2002 11:19:33 -0000 1.51.24.3 --- pdb.py 13 Jan 2003 21:16:24 -0000 1.51.24.4 *************** *** 187,193 **** do_h = cmd.Cmd.do_help - def do_EOF(self, arg): - return 0 # Don't die on EOF - def do_break(self, arg, temporary = 0): # break [ ([filename:]lineno | function) [, "condition"] ] --- 187,190 ---- *************** *** 505,508 **** --- 502,510 ---- do_q = do_quit do_exit = do_quit + + def do_EOF(self, arg): + print + self.set_quit() + return 1 def do_args(self, arg): From gvanrossum@users.sourceforge.net Mon Jan 13 21:19:02 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 13 Jan 2003 13:19:02 -0800 Subject: [Python-checkins] python/dist/src/Lib cmd.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv856 Modified Files: cmd.py Log Message: Duh. cmdqueue should be an instance variable, not a class variable. This was introduced in 1998 in rev. 1.13, where I imported extensive patches that, I am sad to say, I didn't review as carefully as I should have. Index: cmd.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cmd.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** cmd.py 2 Dec 2002 13:08:53 -0000 1.32 --- cmd.py 13 Jan 2003 21:18:54 -0000 1.33 *************** *** 69,73 **** ruler = '=' lastcmd = '' - cmdqueue = [] intro = None doc_leader = "" --- 69,72 ---- *************** *** 87,90 **** --- 86,90 ---- """ + self.cmdqueue = [] if completekey: try: From gvanrossum@users.sourceforge.net Mon Jan 13 21:21:07 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 13 Jan 2003 13:21:07 -0800 Subject: [Python-checkins] python/dist/src/Lib cmd.py,1.26.16.2,1.26.16.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv2160 Modified Files: Tag: release22-maint cmd.py Log Message: Backport 1.33 from trunk: Duh. cmdqueue should be an instance variable, not a class variable. This was introduced in 1998 in rev. 1.13, where I imported extensive patches that, I am sad to say, I didn't review as carefully as I should have. Index: cmd.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cmd.py,v retrieving revision 1.26.16.2 retrieving revision 1.26.16.3 diff -C2 -d -r1.26.16.2 -r1.26.16.3 *** cmd.py 29 May 2002 23:15:46 -0000 1.26.16.2 --- cmd.py 13 Jan 2003 21:21:00 -0000 1.26.16.3 *************** *** 69,73 **** ruler = '=' lastcmd = '' - cmdqueue = [] intro = None doc_leader = "" --- 69,72 ---- *************** *** 87,90 **** --- 86,90 ---- """ + self.cmdqueue = [] if completekey: try: From tim_one@users.sourceforge.net Mon Jan 13 21:38:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 13 Jan 2003 13:38:53 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_mmap.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv10443/python/Lib/test Modified Files: test_mmap.py Log Message: A new test here was failing on Windows, because the test before it never managed to delete the @test file it intended to delete. Also, I don't see a reason to create a 4MB file in the new test, so cut it back to 16K. Index: test_mmap.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mmap.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** test_mmap.py 10 Jan 2003 20:52:16 -0000 1.29 --- test_mmap.py 13 Jan 2003 21:38:45 -0000 1.30 *************** *** 291,300 **** vereq(m.find(slice), data.find(slice)) vereq(m.find(slice + 'x'), -1) finally: ! try: ! os.unlink(TESTFN) ! except OSError: ! pass # make sure a double close doesn't crash on Solaris (Bug# 665913) --- 291,298 ---- vereq(m.find(slice), data.find(slice)) vereq(m.find(slice + 'x'), -1) + m.close() finally: ! os.unlink(TESTFN) # make sure a double close doesn't crash on Solaris (Bug# 665913) *************** *** 302,310 **** try: # unlink TESTFN no matter what ! f.write(2**24 * 'a') # Arbitrary character f.close() f = open(TESTFN) ! mf = mmap.mmap(f.fileno(), 2**24, access=mmap.ACCESS_READ) mf.close() mf.close() --- 300,308 ---- try: # unlink TESTFN no matter what ! f.write(2**16 * 'a') # Arbitrary character f.close() f = open(TESTFN) ! mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ) mf.close() mf.close() *************** *** 312,319 **** finally: ! try: ! os.unlink(TESTFN) ! except OSError: ! pass --- 310,314 ---- finally: ! os.unlink(TESTFN) From jvr@users.sourceforge.net Mon Jan 13 23:30:13 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Mon, 13 Jan 2003 15:30:13 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bundlebuilder.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv20096 Modified Files: bundlebuilder.py Log Message: make sure Info.plist has a CFBundleIdentifier entry Index: bundlebuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bundlebuilder.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** bundlebuilder.py 2 Jan 2003 13:13:01 -0000 1.2 --- bundlebuilder.py 13 Jan 2003 23:30:04 -0000 1.3 *************** *** 128,131 **** --- 128,133 ---- self.creator = "????" plist.CFBundleSignature = self.creator + if not hasattr(plist, "CFBundleIdentifier"): + plist.CFBundleIdentifier = self.name def build(self): From rhettinger@users.sourceforge.net Tue Jan 14 02:19:38 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 13 Jan 2003 18:19:38 -0800 Subject: [Python-checkins] python/dist/src/Lib inspect.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv7580 Modified Files: inspect.py Log Message: SF bug #661184: inspect.getsource bug inspect.getsource would crash with one line definitions like: def f(x): return x or f = lambda x: x Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** inspect.py 30 Nov 2002 03:53:14 -0000 1.39 --- inspect.py 14 Jan 2003 02:19:36 -0000 1.40 *************** *** 418,422 **** raise IOError, 'could not find function definition' lnum = object.co_firstlineno - 1 ! pat = re.compile(r'^\s*def\s') while lnum > 0: if pat.match(lines[lnum]): break --- 418,422 ---- raise IOError, 'could not find function definition' lnum = object.co_firstlineno - 1 ! pat = re.compile(r'^(\s*def\s)|(.*\slambda(:|\s))') while lnum > 0: if pat.match(lines[lnum]): break *************** *** 509,512 **** --- 509,514 ---- except EndOfBlock, eob: return lines[:eob.args[0]] + # Fooling the indent/dedent logic implies a one-line definition + return lines[:1] def getsourcelines(object): From rhettinger@users.sourceforge.net Tue Jan 14 12:43:13 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 14 Jan 2003 04:43:13 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.345,2.346 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv19531 Modified Files: ceval.c Log Message: Replaced POP() with STACKADJ(-1) on lines where the result wasn't used. The two are semantically equivalent, but the first triggered a compiler warning about an unused variable. Note, the preceding steps had already accessed and decreffed the variable so the reference counts were fine. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.345 retrieving revision 2.346 diff -C2 -d -r2.345 -r2.346 *** ceval.c 10 Jan 2003 16:45:17 -0000 2.345 --- ceval.c 14 Jan 2003 12:43:10 -0000 2.346 *************** *** 921,925 **** continue; } ! POP(); break; --- 921,925 ---- continue; } ! STACKADJ(-1); break; *************** *** 1961,1965 **** continue; } ! POP(); break; --- 1961,1965 ---- continue; } ! STACKADJ(-1); break; From gvanrossum@users.sourceforge.net Tue Jan 14 16:40:59 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 14 Jan 2003 08:40:59 -0800 Subject: [Python-checkins] python/dist/src/Lib sets.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv1406 Modified Files: sets.py Log Message: Explicitly raise an exception in __cmp__ -- this clarifies that cmp() is not supported on sets. (Unfortunately, sorting a list of sets may still return random results because it uses < exclusively, but for sets that inly implements a partial ordering. Oh well.) Index: sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sets.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** sets.py 25 Nov 2002 20:43:54 -0000 1.36 --- sets.py 14 Jan 2003 16:40:06 -0000 1.37 *************** *** 103,106 **** --- 103,111 ---- return self._data.iterkeys() + # Three-way comparison is not supported + + def __cmp__(self, other): + raise TypeError, "can't compare sets using cmp()" + # Equality comparisons using the underlying dicts From gvanrossum@users.sourceforge.net Tue Jan 14 16:45:33 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 14 Jan 2003 08:45:33 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.613,1.614 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv2863 Modified Files: NEWS Log Message: Explicitly raise an exception in __cmp__ -- this clarifies that cmp() is not supported on sets. (Unfortunately, sorting a list of sets may still return random results because it uses < exclusively, but for sets that inly implements a partial ordering. Oh well.) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.613 retrieving revision 1.614 diff -C2 -d -r1.613 -r1.614 *** NEWS 13 Jan 2003 20:13:12 -0000 1.613 --- NEWS 14 Jan 2003 16:45:04 -0000 1.614 *************** *** 79,82 **** --- 79,86 ---- ------- + - The sets module now raises TypeError in __cmp__, to clarify that + sets are not intended to be three-way-compared; the comparison + operators are overloaded as subset/superset tests. + - Bastion.py and rexec.py are disabled. These modules are not safe in Python 2.2. or 2.3. From mhammond@users.sourceforge.net Tue Jan 14 23:15:24 2003 From: mhammond@users.sourceforge.net (mhammond@users.sourceforge.net) Date: Tue, 14 Jan 2003 15:15:24 -0800 Subject: [Python-checkins] python/dist/src/Parser tokenizer.c,2.70,2.71 Message-ID: Update of /cvsroot/python/python/dist/src/Parser In directory sc8-pr-cvs1:/tmp/cvs-serv29119 Modified Files: tokenizer.c Log Message: Fix [ 665014 ] files with long lines and an encoding crash. Ensure that the 'size' arg is correctly passed to the encoding reader to prevent buffer overflows. Index: tokenizer.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/tokenizer.c,v retrieving revision 2.70 retrieving revision 2.71 diff -C2 -d -r2.70 -r2.71 *** tokenizer.c 11 Dec 2002 14:04:58 -0000 2.70 --- tokenizer.c 14 Jan 2003 23:15:22 -0000 2.71 *************** *** 347,351 **** PyObject* buf = tok->decoding_buffer; if (buf == NULL) { ! PyObject *args = PyTuple_New(0); if (args == NULL) return error_ret(tok); --- 347,352 ---- PyObject* buf = tok->decoding_buffer; if (buf == NULL) { ! /* Ask for one less byte so we can terminate it */ ! PyObject *args = Py_BuildValue("(i)", size-1); if (args == NULL) return error_ret(tok); From rhettinger@users.sourceforge.net Wed Jan 15 01:55:14 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 14 Jan 2003 17:55:14 -0800 Subject: [Python-checkins] python/nondist/peps pep-0290.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv18660 Modified Files: pep-0290.txt Log Message: Good modernization advice from Terry J. Reedy: Don't use list, dict, file, and such as variable names. Index: pep-0290.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0290.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pep-0290.txt 30 Aug 2002 03:11:40 -0000 1.4 --- pep-0290.txt 15 Jan 2003 01:55:12 -0000 1.5 *************** *** 181,184 **** --- 181,199 ---- + Avoid Variable Names that Clash with the ``__builtins__`` Module + '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + + In Python 2.2, new built-in types were added for ``dict`` and ``file``. + Scripts should avoid assigning variable names that mask those types. + The same advice also applies to existing builtins like ``list``. + + Pattern:: + + file = open('myfile.txt') --> f = open('myfile.txt') + dict = obj.__dict__ --> d = obj.__dict__ + + Locating: ``grep 'file ' *.py`` + + Python 2.1 or Later ------------------- From rhettinger@users.sourceforge.net Wed Jan 15 05:32:59 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 14 Jan 2003 21:32:59 -0800 Subject: [Python-checkins] python/dist/src/Objects stringobject.c,2.203,2.204 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv3709 Modified Files: stringobject.c Log Message: SF patch #664192 bug #661913: inconsistent error messages between string and unicode Patch by Christopher Blunck. Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.203 retrieving revision 2.204 diff -C2 -d -r2.203 -r2.204 *** stringobject.c 6 Jan 2003 22:42:41 -0000 2.203 --- stringobject.c 15 Jan 2003 05:32:57 -0000 2.204 *************** *** 1621,1625 **** if (result == -1) { PyErr_SetString(PyExc_ValueError, ! "substring not found in string.index"); return NULL; } --- 1621,1625 ---- if (result == -1) { PyErr_SetString(PyExc_ValueError, ! "substring not found"); return NULL; } *************** *** 1660,1664 **** if (result == -1) { PyErr_SetString(PyExc_ValueError, ! "substring not found in string.rindex"); return NULL; } --- 1660,1664 ---- if (result == -1) { PyErr_SetString(PyExc_ValueError, ! "substring not found"); return NULL; } From loewis@users.sourceforge.net Wed Jan 15 11:37:25 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 15 Jan 2003 03:37:25 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.614,1.615 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv3409/Misc Modified Files: NEWS Log Message: Patch #473586: Implement CGIXMLRPCRequestHandler. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.614 retrieving revision 1.615 diff -C2 -d -r1.614 -r1.615 *** NEWS 14 Jan 2003 16:45:04 -0000 1.614 --- NEWS 15 Jan 2003 11:37:23 -0000 1.615 *************** *** 79,82 **** --- 79,85 ---- ------- + - SimpleXMLRPCServer now supports CGI through the CGIXMLRPCRequestHandler + class. + - The sets module now raises TypeError in __cmp__, to clarify that sets are not intended to be three-way-compared; the comparison From loewis@users.sourceforge.net Wed Jan 15 11:37:25 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 15 Jan 2003 03:37:25 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsimplexmlrpc.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv3409/Doc/lib Modified Files: libsimplexmlrpc.tex Log Message: Patch #473586: Implement CGIXMLRPCRequestHandler. Index: libsimplexmlrpc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsimplexmlrpc.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libsimplexmlrpc.tex 28 Nov 2001 07:32:53 -0000 1.3 --- libsimplexmlrpc.tex 15 Jan 2003 11:37:23 -0000 1.4 *************** *** 9,20 **** The \module{SimpleXMLRPCServer} module provides a basic server ! framework for XML-RPC servers written in Python. The server object is ! based on the \class{\refmodule{SocketServer}.TCPServer} class, ! and the request handler is based on the ! \class{\refmodule{BaseHTTPServer}.BaseHTTPRequestHandler} class. ! \begin{classdesc}{SimpleXMLRPCServer}{addr\optional{, requestHandler\optional{, logRequests}}} Create a new server instance. The \var{requestHandler} parameter should be a factory for request handler instances; it defaults to --- 9,19 ---- The \module{SimpleXMLRPCServer} module provides a basic server ! framework for XML-RPC servers written in Python. Servers can either ! be free standing, using \class{SimpleXMLRPCServer}, or embedded in a ! CGI environment, using \class{CGIXMLRPCRequestHandler}. \begin{classdesc}{SimpleXMLRPCServer}{addr\optional{, requestHandler\optional{, logRequests}}} + Create a new server instance. The \var{requestHandler} parameter should be a factory for request handler instances; it defaults to *************** *** 28,31 **** --- 27,34 ---- \end{classdesc} + \begin{classdesc}{CGIXMLRPCRequestHandler}{} + Create a new instance to handle XML-RPC requests in a CGI + environment. \versionadded{2.3} + \end{classdesc} \begin{classdesc}{SimpleXMLRPCRequestHandler}{} *************** *** 39,56 **** \subsection{SimpleXMLRPCServer Objects \label{simple-xmlrpc-servers}} ! The \class{SimpleXMLRPCServer} class provides two methods that an ! application can use to register functions that can be called via the ! XML-RPC protocol via the request handler. \begin{methoddesc}[SimpleXMLRPCServer]{register_function}{function\optional{, name}} ! Register a function that can respond to XML-RPC requests. The ! function must be callable with a single parameter which will be the ! return value of \function{\refmodule{xmlrpclib}.loads()} when called ! with the payload of the request. If \var{name} is given, it will be ! the method name associated with \var{function}, otherwise ! \code{\var{function}.__name__} will be used. \var{name} can be ! either a normal or Unicode string, and may contain characters not ! legal in Python identifiers, including the period character. \end{methoddesc} --- 42,57 ---- \subsection{SimpleXMLRPCServer Objects \label{simple-xmlrpc-servers}} ! The \class{SimpleXMLRPCServer} class is based on ! \class{SocketServer.TCPServer} and provides a means of creating ! simple, stand alone XML-RPC servers. \begin{methoddesc}[SimpleXMLRPCServer]{register_function}{function\optional{, name}} ! Register a function that can respond to XML-RPC requests. If ! \var{name} is given, it will be the method name associated with ! \var{function}, otherwise \code{\var{function}.__name__} will be ! used. \var{name} can be either a normal or Unicode string, and may ! contain characters not legal in Python identifiers, including the ! period character. \end{methoddesc} *************** *** 69,70 **** --- 70,157 ---- return value is passed back to the client. \end{methoddesc} + + \begin{methoddesc}{register_introspection_functions}{} + Registers the XML-RPC introspection functions \code{system.listMethods}, + \code{system.methodHelp} and \code{system.methodSignature}. + \versionadded{2.3} + \end{methoddesc} + + \begin{methoddesc}{register_multicall_functions}{} + Registers the XML-RPC multicall function system.multicall. + \end{methoddesc} + + Example: + + \begin{verbatim} + class MyFuncs: + def div(self, x, y) : return div(x,y) + + + server = SimpleXMLRPCServer(("localhost", 8000)) + server.register_function(pow) + server.register_function(lambda x,y: x+y, 'add') + server.register_introspection_functions() + server.register_instance(MyFuncs()) + server.serve_forever() + \end{verbatim} + + \subsection{CGIXMLRPCRequestHandler} + + The \class{CGIXMLRPCRequestHandler} class can be used to + handle XML-RPC requests sent to Python CGI scripts. + + \begin{methoddesc}{register_function}{function\optional{, name}} + Register a function that can respond to XML-RPC requests. If + \var{name] is given, it will be the method name associated with + function, otherwise \var{function.__name__} will be used. \var{name} + can be either a normal or Unicode string, and may contain + characters not legal in Python identifiers, including the period + character. + \end{methoddesc} + + \begin{methoddesc}{register_instance}{instance} + Register an object which is used to expose method names + which have not been registered using \method{register_function()}. If + 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 instance does not have a \methode{_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 method name is searched for individually, + with the effect that a simple hierarchical search is performed. + The value found from this search is then called with the + parameters from the request, and the return value is passed + back to the client. + \end{methoddesc} + + \begin{methoddesc}{register_introspection_functions}{} + Register the XML-RPC introspection functions + \code{system.listMethods}, \code{system.methodHelp} and + \code{system.methodSignature}. + \end{methoddesc} + + \begin{methoddesc}{register_multicall_functions}{} + Register the XML-RPC multicall function \code{system.multicall}. + \end{methoddesc} + + \begin{methoddesc}{handle_request}{\optional{request_text = None}} + Handle a XML-RPC request. If \var{request_text} is given, it + should be the POST data provided by the HTTP server, + otherwise the contents of stdin will be used. + \end{methoddesc} + + Example: + + \begin{verbatim} + class MyFuncs: + def div(self, x, y) : return div(x,y) + + + handler = CGIXMLRPCRequestHandler() + handler.register_function(pow) + handler.register_function(lambda x,y: x+y, 'add') + handler.register_introspection_functions() + handler.register_instance(MyFuncs()) + handler.handle_request() + \end{verbatim} \ No newline at end of file From loewis@users.sourceforge.net Wed Jan 15 11:37:25 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 15 Jan 2003 03:37:25 -0800 Subject: [Python-checkins] python/dist/src/Lib SimpleXMLRPCServer.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv3409/Lib Modified Files: SimpleXMLRPCServer.py Log Message: Patch #473586: Implement CGIXMLRPCRequestHandler. Index: SimpleXMLRPCServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SimpleXMLRPCServer.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** SimpleXMLRPCServer.py 29 Sep 2001 04:54:33 -0000 1.2 --- SimpleXMLRPCServer.py 15 Jan 2003 11:37:23 -0000 1.3 *************** *** 3,9 **** This module can be used to create simple XML-RPC servers by creating a server and either installing functions, a ! class instance, or by extending the SimpleXMLRPCRequestHandler class. A list of possible usage patterns follows: --- 3,12 ---- This module can be used to create simple XML-RPC servers by creating a server and either installing functions, a ! class instance, or by extending the SimpleXMLRPCServer class. + It can also be used to handle XML-RPC requests in a CGI + environment using CGIXMLRPCRequestHandler. + A list of possible usage patterns follows: *************** *** 23,29 **** --- 26,39 ---- import string self.string = string + def _listMethods(self): + # implement this method so that system.listMethods + # knows to advertise the strings methods + return list_public_methods(self) + \ + ['string.' + method for method in list_public_methods(self.string)] def pow(self, x, y): return pow(x, y) def add(self, x, y) : return x + y + server = SimpleXMLRPCServer(("localhost", 8000)) + server.register_introspection_functions() server.register_instance(MyFuncs()) server.serve_forever() *************** *** 32,49 **** class Math: def _dispatch(self, method, params): if method == 'pow': ! return apply(pow, params) elif method == 'add': return params[0] + params[1] else: raise 'bad method' server = SimpleXMLRPCServer(("localhost", 8000)) server.register_instance(Math()) server.serve_forever() ! 4. Subclass SimpleXMLRPCRequestHandler: ! class MathHandler(SimpleXMLRPCRequestHandler): def _dispatch(self, method, params): try: --- 42,76 ---- class Math: + def _listMethods(self): + # this method must be present for system.listMethods + # to work + return ['add', 'pow'] + def _methodHelp(self, method): + # this method must be present for system.methodHelp + # to work + if method == 'add': + return "add(2,3) => 5" + elif method == 'pow': + return "pow(x, y[, z]) => number" + else: + # By convention, return empty + # string if no help is available + return "" def _dispatch(self, method, params): if method == 'pow': ! return pow(*params) elif method == 'add': return params[0] + params[1] else: raise 'bad method' + server = SimpleXMLRPCServer(("localhost", 8000)) + server.register_introspection_functions() server.register_instance(Math()) server.serve_forever() ! 4. Subclass SimpleXMLRPCServer: ! class MathServer(SimpleXMLRPCServer): def _dispatch(self, method, params): try: *************** *** 55,68 **** raise Exception('method "%s" is not supported' % method) else: ! return apply(func, params) ! ! def log_message(self, format, *args): ! pass # maybe do something fancy like write the messages to a file def export_add(self, x, y): return x + y ! server = SimpleXMLRPCServer(("localhost", 8000), MathHandler) server.serve_forever() """ --- 82,98 ---- raise Exception('method "%s" is not supported' % method) else: ! return func(*params) def export_add(self, x, y): return x + y ! server = MathServer(("localhost", 8000)) server.serve_forever() + + 5. CGI script: + + server = CGIXMLRPCRequestHandler() + server.register_function(pow) + server.handle_request() """ *************** *** 71,130 **** import xmlrpclib import SocketServer import BaseHTTPServer import sys ! class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): ! """Simple XML-RPC request handler class. ! Handles all HTTP POST requests and attempts to decode them as ! XML-RPC requests. ! XML-RPC requests are dispatched to the _dispatch method, which ! may be overriden by subclasses. The default implementation attempts ! to dispatch XML-RPC calls to the functions or instance installed ! in the server. """ ! def do_POST(self): ! """Handles the HTTP POST request. ! Attempts to interpret all HTTP POST requests as XML-RPC calls, ! which are forwarded to the _dispatch method for handling. """ ! try: ! # get arguments ! data = self.rfile.read(int(self.headers["content-length"])) ! params, method = xmlrpclib.loads(data) ! # generate response ! try: response = self._dispatch(method, params) ! # wrap response in a singleton tuple ! response = (response,) ! except: ! # report exception back to server ! response = xmlrpclib.dumps( ! xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value)) ! ) ! else: ! response = xmlrpclib.dumps(response, methodresponse=1) except: ! # internal error, report as HTTP server error ! self.send_response(500) ! self.end_headers() else: ! # got a valid XML RPC response ! self.send_response(200) ! self.send_header("Content-type", "text/xml") ! self.send_header("Content-length", str(len(response))) ! self.end_headers() ! self.wfile.write(response) ! # shut down the connection ! self.wfile.flush() ! self.connection.shutdown(1) def _dispatch(self, method, params): """Dispatches the XML-RPC method. --- 101,342 ---- import xmlrpclib + from xmlrpclib import Fault import SocketServer import BaseHTTPServer import sys + import types + import os ! def resolve_dotted_attribute(obj, attr): ! """resolve_dotted_attribute(a, 'b.c.d') => a.b.c.d ! Resolves a dotted attribute name to an object. Raises ! an AttributeError if any attribute in the chain starts with a '_'. ! """ ! for i in attr.split('.'): ! if i.startswith('_'): ! raise AttributeError( ! 'attempt to access private attribute "%s"' % i ! ) ! else: ! obj = getattr(obj,i) ! return obj ! ! def list_public_methods(obj): ! """Returns a list of attribute strings, found in the specified ! object, which represent callable attributes""" ! ! return [member for member in dir(obj) ! if not member.startswith('_') and ! callable(getattr(obj, member))] ! ! def remove_duplicates(lst): ! """remove_duplicates([2,2,2,1,3,3]) => [3,1,2] ! ! Returns a copy of a list without duplicates. Every list ! item must be hashable and the order of the items in the ! resulting list is not defined. ! """ ! u = {} ! for x in lst: ! u[x] = 1 ! ! return u.keys() ! ! class SimpleXMLRPCDispatcher: ! """Mix-in class that dispatches XML-RPC requests. ! ! This class is used to register XML-RPC method handlers ! and then to dispatch them. There should never be any ! reason to instantiate this class directly. """ + + def __init__(self): + self.funcs = {} + self.instance = None ! def register_instance(self, instance): ! """Registers an instance to respond to XML-RPC requests. ! Only one instance can be installed at a time. ! ! If the registered instance has a _dispatch method then that ! method will be called with the name of the XML-RPC method and ! it's parameters as a tuple ! e.g. instance._dispatch('add',(2,3)) ! ! If the registered instance does not have a _dispatch method ! then the instance will be searched to find a matching method ! and, if found, will be called. Methods beginning with an '_' ! are considered private and will not be called by ! SimpleXMLRPCServer. ! ! If a registered function matches a XML-RPC request, then it ! will be called instead of the registered instance. """ ! self.instance = instance ! def register_function(self, function, name = None): ! """Registers a function to respond to XML-RPC requests. ! ! The optional name argument can be used to set a Unicode name ! for the function. ! """ ! ! if name is None: ! name = function.__name__ ! self.funcs[name] = function ! ! def register_introspection_functions(self): ! """Registers the XML-RPC introspection methods in the system ! namespace. ! ! see http://xmlrpc.usefulinc.com/doc/reserved.html ! """ ! ! self.funcs.update({'system.listMethods' : self.system_listMethods, ! 'system.methodSignature' : self.system_methodSignature, ! 'system.methodHelp' : self.system_methodHelp}) ! ! def register_multicall_functions(self): ! """Registers the XML-RPC multicall method in the system ! namespace. ! ! see http://www.xmlrpc.com/discuss/msgReader$1208""" ! ! self.funcs.update({'system.multicall' : self.system_multicall}) ! ! def _marshaled_dispatch(self, data, dispatch_method = None): ! """Dispatches an XML-RPC method from marshalled (XML) data. ! ! XML-RPC methods are dispatched from the marshalled (XML) data ! using the _dispatch method and the result is returned as ! marshalled data. For backwards compatibility, a dispatch ! function can be provided as an argument (see comment in ! SimpleXMLRPCRequestHandler.do_POST) but overriding the ! existing method through subclassing is the prefered means ! of changing method dispatch behavior. ! """ ! ! params, method = xmlrpclib.loads(data) ! ! # generate response ! try: ! if dispatch_method is not None: ! response = dispatch_method(method, params) ! else: response = self._dispatch(method, params) ! # wrap response in a singleton tuple ! response = (response,) ! response = xmlrpclib.dumps(response, methodresponse=1) ! except Fault, fault: ! response = xmlrpclib.dumps(fault) except: ! # report exception back to server ! response = xmlrpclib.dumps( ! xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value)) ! ) ! ! return response ! ! def system_listMethods(self): ! """system.listMethods() => ['add', 'subtract', 'multiple'] ! ! Returns a list of the methods supported by the server.""" ! ! methods = self.funcs.keys() ! if self.instance is not None: ! # Instance can implement _listMethod to return a list of ! # methods ! if hasattr(self.instance, '_listMethods'): ! methods = remove_duplicates( ! methods + self.instance._listMethods() ! ) ! # if the instance has a _dispatch method then we ! # don't have enough information to provide a list ! # of methods ! elif not hasattr(self.instance, '_dispatch'): ! methods = remove_duplicates( ! methods + list_public_methods(self.instance) ! ) ! methods.sort() ! return methods ! ! def system_methodSignature(self, method_name): ! """system.methodSignature('add') => [double, int, int] ! ! Returns a list describing the signiture of the method. In the ! above example, the add method takes two integers as arguments ! and returns a double result. ! ! This server does NOT support system.methodSignature.""" ! ! # See http://xmlrpc.usefulinc.com/doc/sysmethodsig.html ! ! return 'signatures not supported' ! ! def system_methodHelp(self, method_name): ! """system.methodHelp('add') => "Adds two integers together" ! ! Returns a string containing documentation for the specified method.""" ! ! method = None ! if self.funcs.has_key(method_name): ! method = self.funcs[method_name] ! elif self.instance is not None: ! # Instance can implement _methodHelp to return help for a method ! if hasattr(self.instance, '_methodHelp'): ! return self.instance._methodHelp(method_name) ! # if the instance has a _dispatch method then we ! # don't have enough information to provide help ! elif not hasattr(self.instance, '_dispatch'): ! try: ! method = resolve_dotted_attribute( ! self.instance, ! method_name ! ) ! except AttributeError: ! pass ! ! # Note that we aren't checking that the method actually ! # be a callable object of some kind ! if method is None: ! return "" else: ! return pydoc.getdoc(method) ! def system_multicall(self, call_list): ! """system.multicall([{'methodName': 'add', 'params': [2, 2]}, ...]) => \ ! [[4], ...] ! ! Allows the caller to package multiple XML-RPC calls into a single ! request. + See http://www.xmlrpc.com/discuss/msgReader$1208 + """ + + results = [] + for call in call_list: + method_name = call['methodName'] + params = call['params'] + + try: + # XXX A marshalling error in any response will fail the entire + # multicall. If someone cares they should fix this. + results.append([self._dispatch(method_name, params)]) + except Fault, fault: + results.append( + {'faultCode' : fault.faultCode, + 'faultString' : fault.faultString} + ) + except: + results.append( + {'faultCode' : 1, + 'faultString' : "%s:%s" % (sys.exc_type, sys.exc_value)} + ) + return results + def _dispatch(self, method, params): """Dispatches the XML-RPC method. *************** *** 145,149 **** Methods beginning with an '_' are considered private and will ! not be called by SimpleXMLRPCServer. """ --- 357,361 ---- Methods beginning with an '_' are considered private and will ! not be called. """ *************** *** 151,165 **** try: # check to see if a matching function has been registered ! func = self.server.funcs[method] except KeyError: ! if self.server.instance is not None: # check for a _dispatch method ! if hasattr(self.server.instance, '_dispatch'): ! return self.server.instance._dispatch(method, params) else: # call instance method directly try: ! func = _resolve_dotted_attribute( ! self.server.instance, method ) --- 363,377 ---- try: # check to see if a matching function has been registered ! func = self.funcs[method] except KeyError: ! if self.instance is not None: # check for a _dispatch method ! if hasattr(self.instance, '_dispatch'): ! return self.instance._dispatch(method, params) else: # call instance method directly try: ! func = resolve_dotted_attribute( ! self.instance, method ) *************** *** 168,247 **** if func is not None: ! return apply(func, params) else: raise Exception('method "%s" is not supported' % method) ! def log_request(self, code='-', size='-'): ! """Selectively log an accepted request.""" ! ! if self.server.logRequests: ! BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size) ! def _resolve_dotted_attribute(obj, attr): ! """Resolves a dotted attribute name to an object. Raises ! an AttributeError if any attribute in the chain starts with a '_'. ! """ ! for i in attr.split('.'): ! if i.startswith('_'): ! raise AttributeError( ! 'attempt to access private attribute "%s"' % i ) else: ! obj = getattr(obj,i) ! return obj ! class SimpleXMLRPCServer(SocketServer.TCPServer): """Simple XML-RPC server. Simple XML-RPC server that allows functions and a single instance ! to be installed to handle requests. """ def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler, logRequests=1): - self.funcs = {} self.logRequests = logRequests ! self.instance = None SocketServer.TCPServer.__init__(self, addr, requestHandler) ! def register_instance(self, instance): ! """Registers an instance to respond to XML-RPC requests. ! ! Only one instance can be installed at a time. ! ! If the registered instance has a _dispatch method then that ! method will be called with the name of the XML-RPC method and ! it's parameters as a tuple ! e.g. instance._dispatch('add',(2,3)) ! ! If the registered instance does not have a _dispatch method ! then the instance will be searched to find a matching method ! and, if found, will be called. ! Methods beginning with an '_' are considered private and will ! not be called by SimpleXMLRPCServer. ! If a registered function matches a XML-RPC request, then it ! will be called instead of the registered instance. """ ! self.instance = instance ! ! def register_function(self, function, name = None): ! """Registers a function to respond to XML-RPC requests. ! ! The optional name argument can be used to set a Unicode name ! for the function. ! ! If an instance is also registered then it will only be called ! if a matching function is not found. """ ! if name is None: ! name = function.__name__ ! self.funcs[name] = function ! if __name__ == '__main__': server = SimpleXMLRPCServer(("localhost", 8000)) --- 380,509 ---- if func is not None: ! return func(*params) else: raise Exception('method "%s" is not supported' % method) + + class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + """Simple XML-RPC request handler class. ! Handles all HTTP POST requests and attempts to decode them as ! XML-RPC requests. ! """ + def do_POST(self): + """Handles the HTTP POST request. ! Attempts to interpret all HTTP POST requests as XML-RPC calls, ! which are forwarded to the server's _dispatch method for handling. ! """ ! ! try: ! # get arguments ! data = self.rfile.read(int(self.headers["content-length"])) ! # In previous versions of SimpleXMLRPCServer, _dispatch ! # could be overridden in this class, instead of in ! # SimpleXMLRPCDispatcher. To maintain backwards compatibility, ! # check to see if a subclass implements _dispatch and dispatch ! # using that method if present. ! response = self.server._marshaled_dispatch( ! data, getattr(self, '_dispatch', None) ) + except: # This should only happen if the module is buggy + # internal error, report as HTTP server error + self.send_response(500) + self.end_headers() else: ! # got a valid XML RPC response ! self.send_response(200) ! self.send_header("Content-type", "text/xml") ! self.send_header("Content-length", str(len(response))) ! self.end_headers() ! self.wfile.write(response) + # shut down the connection + self.wfile.flush() + self.connection.shutdown(1) + + def log_request(self, code='-', size='-'): + """Selectively log an accepted request.""" ! if self.server.logRequests: ! BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size) ! ! class SimpleXMLRPCServer(SocketServer.TCPServer, ! SimpleXMLRPCDispatcher): """Simple XML-RPC server. Simple XML-RPC server that allows functions and a single instance ! to be installed to handle requests. The default implementation ! attempts to dispatch XML-RPC calls to the functions or instance ! installed in the server. Override the _dispatch method inhereted ! from SimpleXMLRPCDispatcher to change this behavior. """ def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler, logRequests=1): self.logRequests = logRequests ! ! SimpleXMLRPCDispatcher.__init__(self) SocketServer.TCPServer.__init__(self, addr, requestHandler) + + class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): + """Simple handler for XML-RPC data passed through CGI.""" + + def __init__(self): + SimpleXMLRPCDispatcher.__init__(self) ! def handle_xmlrpc(self, request_text): ! """Handle a single XML-RPC request""" ! ! response = self._marshaled_dispatch(request_text) ! ! print 'Content-Type: text/xml' ! print 'Content-Length: %d' % len(response) ! print ! print response ! def handle_get(self): ! """Handle a single HTTP GET request. ! Default implementation indicates an error because ! XML-RPC uses the POST method. """ ! code = 400 ! message, explain = \ ! BaseHTTPServer.BaseHTTPRequestHandler.responses[code] ! ! response = BaseHTTPServer.DEFAULT_ERROR_MESSAGE % \ ! { ! 'code' : code, ! 'message' : message, ! 'explain' : explain ! } ! print 'Status: %d %s' % (code, message) ! print 'Content-Type: text/html' ! print 'Content-Length: %d' % len(response) ! print ! print response ! ! def handle_request(self, request_text = None): ! """Handle a single XML-RPC request passed through a CGI post method. ! ! If no XML data is given then it is read from stdin. The resulting ! XML-RPC response is printed to stdout along with the correct HTTP ! headers. """ + + if request_text is None and \ + os.environ.get('REQUEST_METHOD', None) == 'GET': + self.handle_get() + else: + # POST data is normally available through stdin + if request_text is None: + request_text = sys.stdin.read() ! self.handle_xmlrpc(request_text) ! if __name__ == '__main__': server = SimpleXMLRPCServer(("localhost", 8000)) From loewis@users.sourceforge.net Wed Jan 15 11:51:08 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 15 Jan 2003 03:51:08 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libpycompile.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv4597/Doc/lib Modified Files: libpycompile.tex Log Message: Patch #661719: Expose compilation errors as exceptions on request. Index: libpycompile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpycompile.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libpycompile.tex 21 Aug 2002 20:56:21 -0000 1.3 --- libpycompile.tex 15 Jan 2003 11:51:06 -0000 1.4 *************** *** 20,25 **** containing the source code. ! \begin{funcdesc}{compile}{file\optional{, cfile\optional{, dfile}}} Compile a source file to byte-code and write out the byte-code cache file. The source code is loaded from the file name \var{file}. The --- 20,28 ---- containing the source code. + \begin{excdesc}{PyCompileError} + Exception raised when an error occurs while attempting to compile the file. + \end{excdesc} ! \begin{funcdesc}{compile}{file\optional{, cfile\optional{, dfile\optional{, doraise}}}} Compile a source file to byte-code and write out the byte-code cache file. The source code is loaded from the file name \var{file}. The *************** *** 28,33 **** current interpreter). If \var{dfile} is specified, it is used as the name of the source file in error messages instead of \var{file}. \end{funcdesc} - \begin{funcdesc}{main}{\optional{args}} --- 31,38 ---- current interpreter). If \var{dfile} is specified, it is used as the name of the source file in error messages instead of \var{file}. + If \var{doraise} = True, a PyCompileError is raised when an error is + encountered while compiling \var{file}. If \var{doraise} = False (the default), + an error string is written to sys.stderr, but no exception is raised. \end{funcdesc} \begin{funcdesc}{main}{\optional{args}} From loewis@users.sourceforge.net Wed Jan 15 11:51:09 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 15 Jan 2003 03:51:09 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.615,1.616 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv4597/Misc Modified Files: NEWS Log Message: Patch #661719: Expose compilation errors as exceptions on request. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.615 retrieving revision 1.616 diff -C2 -d -r1.615 -r1.616 *** NEWS 15 Jan 2003 11:37:23 -0000 1.615 --- NEWS 15 Jan 2003 11:51:06 -0000 1.616 *************** *** 79,82 **** --- 79,85 ---- ------- + - py_compile has a new 'doraise' flag and a new PyCompileError + exception. + - SimpleXMLRPCServer now supports CGI through the CGIXMLRPCRequestHandler class. From loewis@users.sourceforge.net Wed Jan 15 11:51:08 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 15 Jan 2003 03:51:08 -0800 Subject: [Python-checkins] python/dist/src/Lib compileall.py,1.12,1.13 py_compile.py,1.23,1.24 zipfile.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv4597/Lib Modified Files: compileall.py py_compile.py zipfile.py Log Message: Patch #661719: Expose compilation errors as exceptions on request. Index: compileall.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compileall.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** compileall.py 1 Jun 2002 19:51:15 -0000 1.12 --- compileall.py 15 Jan 2003 11:51:06 -0000 1.13 *************** *** 63,76 **** print 'Compiling', fullname, '...' try: ! ok = py_compile.compile(fullname, None, dfile) except KeyboardInterrupt: raise KeyboardInterrupt ! except: ! # XXX py_compile catches SyntaxErrors ! if type(sys.exc_type) == type(''): ! exc_type_name = sys.exc_type ! else: exc_type_name = sys.exc_type.__name__ ! print 'Sorry:', exc_type_name + ':', ! print sys.exc_value success = 0 else: --- 63,71 ---- print 'Compiling', fullname, '...' try: ! ok = py_compile.compile(fullname, None, dfile, True) except KeyboardInterrupt: raise KeyboardInterrupt ! except py_compile.PyCompileError,err: ! print err.msg success = 0 else: Index: py_compile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/py_compile.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** py_compile.py 21 Aug 2002 20:56:21 -0000 1.23 --- py_compile.py 15 Jan 2003 11:51:06 -0000 1.24 *************** *** 13,17 **** MAGIC = imp.get_magic() ! __all__ = ["compile", "main"] # Define an internal helper according to the platform --- 13,64 ---- MAGIC = imp.get_magic() ! __all__ = ["compile", "main", "PyCompileError"] ! ! ! class PyCompileError(Exception): ! """Exception raised when an error occurs while attempting to ! compile the file. ! ! To raise this exception, use ! ! raise PyCompileError(exc_type,exc_value,file[,msg]) ! ! where ! ! exc_type: exception type to be used in error message ! type name can be accesses as class variable ! 'exc_type_name' ! ! exc_value: exception value to be used in error message ! can be accesses as class variable 'exc_value' ! ! file: name of file being compiled to be used in error message ! can be accesses as class variable 'file' ! ! msg: string message to be written as error message ! If no value is given, a default exception message will be given, ! consistent with 'standard' py_compile output. ! message (or default) can be accesses as class variable 'msg' ! ! """ ! ! def __init__(self, exc_type, exc_value, file, msg=''): ! exc_type_name = exc_type.__name__ ! if exc_type is SyntaxError: ! tbtext = ''.join(traceback.format_exception_only(exc_type, exc_value)) ! errmsg = tbtext.replace('File ""', 'File "%s"' % file) ! else: ! errmsg = "Sorry: %s: %s" % (exc_type_name,exc_value) ! ! Exception.__init__(self,msg or errmsg,exc_type_name,exc_value,file) ! ! self.exc_type_name = exc_type_name ! self.exc_value = exc_value ! self.file = file ! self.msg = msg or errmsg ! ! def __str__(self): ! return self.msg ! # Define an internal helper according to the platform *************** *** 31,45 **** f.write(chr((x >> 24) & 0xff)) ! def compile(file, cfile=None, dfile=None): """Byte-compile one Python source file to Python bytecode. Arguments: ! file: source filename ! cfile: target filename; defaults to source with 'c' or 'o' appended ! ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo) ! dfile: purported filename; defaults to source (this is the filename ! that will show up in error messages) ! Note that it isn't necessary to byte-compile Python modules for execution efficiency -- Python itself byte-compiles a module when --- 78,99 ---- f.write(chr((x >> 24) & 0xff)) ! def compile(file, cfile=None, dfile=None, doraise=False): """Byte-compile one Python source file to Python bytecode. Arguments: ! file: source filename ! cfile: target filename; defaults to source with 'c' or 'o' appended ! ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo) ! dfile: purported filename; defaults to source (this is the filename ! that will show up in error messages) ! doraise: flag indicating whether or not an exception should be ! raised when a compile error is found. If an exception ! occurs and this flag is set to False, a string ! indicating the nature of the exception will be printed, ! and the function will return to the caller. If an ! exception occurs and this flag is set to True, a ! PyCompileError exception will be raised. ! Note that it isn't necessary to byte-compile Python modules for execution efficiency -- Python itself byte-compiles a module when *************** *** 69,79 **** codestring = codestring + '\n' try: ! codeobject = __builtin__.compile(codestring, dfile or file, 'exec') ! except SyntaxError, detail: ! lines = traceback.format_exception_only(SyntaxError, detail) ! for line in lines: ! sys.stderr.write(line.replace('File ""', ! 'File "%s"' % (dfile or file))) ! return if cfile is None: cfile = file + (__debug__ and 'c' or 'o') --- 123,134 ---- codestring = codestring + '\n' try: ! codeobject = __builtin__.compile(codestring, dfile or file,'exec') ! except Exception,err: ! py_exc = PyCompileError(err.__class__,err.args,dfile or file) ! if doraise: ! raise py_exc ! else: ! sys.stderr.write(py_exc.msg) ! return if cfile is None: cfile = file + (__debug__ and 'c' or 'o') *************** *** 101,106 **** args = sys.argv[1:] for filename in args: ! compile(filename) ! if __name__ == "__main__": main() --- 156,164 ---- args = sys.argv[1:] for filename in args: ! try: ! compile(filename, doraise=True) ! except PyCompileError,err: ! sys.stderr.write(err.msg) ! if __name__ == "__main__": main() Index: zipfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/zipfile.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** zipfile.py 12 Dec 2002 12:23:32 -0000 1.27 --- zipfile.py 15 Jan 2003 11:51:06 -0000 1.28 *************** *** 605,609 **** if self.debug: print "Compiling", file_py ! py_compile.compile(file_py, file_pyc) fname = file_pyc else: --- 605,612 ---- if self.debug: print "Compiling", file_py ! try: ! py_compile.compile(file_py, file_pyc, None, True) ! except py_compile.PyCompileError,err: ! print err.msg fname = file_pyc else: From loewis@users.sourceforge.net Wed Jan 15 11:53:15 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 15 Jan 2003 03:53:15 -0800 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.223,1.224 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv4800/Misc Modified Files: ACKS Log Message: Gyro Func for patch #661719. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.223 retrieving revision 1.224 diff -C2 -d -r1.223 -r1.224 *** ACKS 7 Jan 2003 20:34:19 -0000 1.223 --- ACKS 15 Jan 2003 11:53:13 -0000 1.224 *************** *** 174,180 **** Ivan Frohne Jim Fulton - Geoff Furnish Tadayoshi Funaba Peter Funk Lele Gaifax Raymund Galvin --- 174,181 ---- Ivan Frohne Jim Fulton Tadayoshi Funaba + Gyro Funch Peter Funk + Geoff Furnish Lele Gaifax Raymund Galvin From webmaster@pferdemarkt.ws Wed Jan 15 12:32:58 2003 From: webmaster@pferdemarkt.ws (webmaster@pferdemarkt.ws) Date: Wed, 15 Jan 2003 04:32:58 -0800 Subject: [Python-checkins] Pferdemarkt.ws informiert! Newsletter 01/2003 Message-ID: <200301151232.EAA07130@eagle.he.net> http://www.pferdemarkt.ws Wir sind in 2003 erfolgreich in des neue \"Pferdejahr 2003 gestartet. Für den schnellen Erfolg unseres Marktes möchten wir uns bei Ihnen bedanken. Heute am 15. Januar 2003 sind wir genau 14 Tage Online! Täglich wächst unsere Datenbank um ca. 30 neue Angebote. Stellen auch Sie als Privatperson Ihre zu verkaufenden Pferde direkt und vollkommen Kostenlos ins Internet. Zur besseren Sichtbarmachung Ihrer Angebote können SIe bis zu ein Bild zu Ihrer Pferdeanzeige kostenlos einstellen! Klicken Sie hier um sich direkt einzuloggen http://www.Pferdemarkt.ws Kostenlos Anbieten, Kostenlos Suchen! Direkt von Privat zu Privat! Haben Sie noch Fragen mailto: webmaster@pferdemarkt.ws From rhettinger@users.sourceforge.net Wed Jan 15 15:46:07 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 15 Jan 2003 07:46:07 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsets.tex,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv30036 Modified Files: libsets.tex Log Message: Document that __cmp__() is not defined for sets. Note, that list.sort() is undefined for lists of sets. Add the ... prompt to the example so it runs in doctest. Index: libsets.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsets.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** libsets.tex 6 Jan 2003 15:50:32 -0000 1.8 --- libsets.tex 15 Jan 2003 15:46:05 -0000 1.9 *************** *** 111,114 **** --- 111,123 ---- superset of the second set (is a superset, but is not equal). + The subset and equality comparisons do not generalize to a complete + ordering function. For example, any two disjoint sets are not equal and + are not subsets of each other, so \emph{none} of the following are true: + \code{\var{a}<\var{b}}, \code{\var{a}==\var{b}}, or \code{\var{a}>\var{b}}. + Accordingly, sets do not implement the \method{__cmp__} method. + + Since sets only define partial ordering (subset relationships), the output + of the \method{list.sort()} method is undefined for lists of sets. + The following table lists operations available in \class{ImmutableSet} but not found in \class{Set}: *************** *** 176,182 **** True >>> for group in [engineers, programmers, management, employees]: ! group.discard('Susan') # unconditionally remove element ! print group ! Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) Set(['Janice', 'Jack', 'Sam']) --- 185,191 ---- True >>> for group in [engineers, programmers, management, employees]: ! ... group.discard('Susan') # unconditionally remove element ! ... print group ! ... Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) Set(['Janice', 'Jack', 'Sam']) From nascheme@users.sourceforge.net Wed Jan 15 16:04:46 2003 From: nascheme@users.sourceforge.net (nascheme@users.sourceforge.net) Date: Wed, 15 Jan 2003 08:04:46 -0800 Subject: [Python-checkins] python/dist/src README,1.166,1.167 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv613 Modified Files: README Log Message: Remove misleading advice. VERSION was not intended to be used that way. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.166 retrieving revision 1.167 diff -C2 -d -r1.166 -r1.167 *** README 6 Jan 2003 17:23:37 -0000 1.166 --- README 15 Jan 2003 16:04:43 -0000 1.167 *************** *** 882,891 **** it doesn't install the manual page at all. - Alpha/beta revision levels are stripped from the executable and - library filenames during installation. For example, Python2.1a2 will - install as python2.1, overwriting the previous python2.1. To avoid - this, you could set the Makefile VERSION variable manually - (e.g. VERSION=2.1a2) before running "make install" or "make altinstall". - The only thing you may have to install manually is the Python mode for Emacs found in Misc/python-mode.el. (But then again, more recent --- 882,885 ---- From rhettinger@users.sourceforge.net Wed Jan 15 16:15:41 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 15 Jan 2003 08:15:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sets.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv2409 Modified Files: test_sets.py Log Message: * Add test for __cmp__() * Add doctest for example in the library reference manual Index: test_sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sets.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** test_sets.py 25 Nov 2002 20:43:55 -0000 1.18 --- test_sets.py 15 Jan 2003 16:15:38 -0000 1.19 *************** *** 231,234 **** --- 231,238 ---- self.assertEqual(result, Set([2, 4, 6, 8])) + def test_cmp(self): + a, b = Set('a'), Set('b') + self.assertRaises(TypeError, cmp, (a,b)) + #============================================================================== *************** *** 635,638 **** --- 639,672 ---- #============================================================================== + libreftest = """ + Example from the Library Reference: Doc/lib/libsets.tex + + >>> from sets import Set + >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice']) + >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice']) + >>> management = Set(['Jane', 'Jack', 'Susan', 'Zack']) + >>> employees = engineers | programmers | management # union + >>> engineering_management = engineers & programmers # intersection + >>> fulltime_management = management - engineers - programmers # difference + >>> engineers.add('Marvin') + >>> print engineers + Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) + >>> employees.issuperset(engineers) # superset test + False + >>> employees.update(engineers) # update from another set + >>> employees.issuperset(engineers) + True + >>> for group in [engineers, programmers, management, employees]: + ... group.discard('Susan') # unconditionally remove element + ... print group + ... + Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) + Set(['Janice', 'Jack', 'Sam']) + Set(['Jane', 'Zack', 'Jack']) + Set(['Zack', 'Sam', 'Marvin', 'Jack', 'Jane', 'Janice', 'John']) + """ + + #============================================================================== + def makeAllTests(): suite = unittest.TestSuite() *************** *** 665,672 **** #------------------------------------------------------------------------------ ! def test_main(): suite = makeAllTests() test_support.run_suite(suite) if __name__ == "__main__": ! test_main() --- 699,710 ---- #------------------------------------------------------------------------------ ! __test__ = {'libreftest' : libreftest} ! ! def test_main(verbose=None): ! from test import test_sets suite = makeAllTests() test_support.run_suite(suite) + test_support.run_doctest(test_sets, verbose) if __name__ == "__main__": ! test_main(verbose=True) From montanaro@users.sourceforge.net Wed Jan 15 21:08:21 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 15 Jan 2003 13:08:21 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libfcntl.tex,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv11979 Modified Files: libfcntl.tex Log Message: reference the os module and the lock flags in the os.open() function. (Someone please review what I wrote for accuracy.) Index: libfcntl.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfcntl.tex,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** libfcntl.tex 14 Jun 2002 01:58:19 -0000 1.29 --- libfcntl.tex 15 Jan 2003 21:08:19 -0000 1.30 *************** *** 119,120 **** --- 119,128 ---- system dependent --- therefore using the \function{flock()} call may be better. + + \begin{seealso} + \seemodule{os}{The \function{os.open} function supports locking flags + and is available on a wider variety of platforms than + the \function{fcntl.lockf} and \function{fcntl.flock} + functions, providing a more platform-independent file + locking facility.} + \end{seealso} From jackjansen@users.sourceforge.net Wed Jan 15 22:36:18 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 15 Jan 2003 14:36:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macfs.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv26831/Lib/plat-mac Modified Files: macfs.py Log Message: Implemented FSCatalogInfo structure support, and used this to implement FSSpec.SetDates() and GetDates(). Closes #662836. Index: macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macfs.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** macfs.py 8 Jan 2003 16:32:29 -0000 1.2 --- macfs.py 15 Jan 2003 22:36:16 -0000 1.3 *************** *** 22,25 **** --- 22,42 ---- smAllScripts = -3 + # + # Find the epoch conversion for file dates in a way that works on OS9 and OSX + import time + if time.gmtime(0)[0] == 1970: + _EPOCHCONVERT = -((1970-1904)*365 + 17) * (24*60*60) + 0x100000000L + def _utc2time(utc): + t = utc[1] + _EPOCHCONVERT + return int(t) + def _time2utc(t): + t = t - _EPOCHCONVERT + if t < -0x7fffffff: + t = t + 0x10000000L + return (0, int(t), 0) + else: + def _utc2time(utc): return utc[1] + def _time2utc(t): return (0, t, 0) + # The old name of the error object: error = Carbon.File.Error *************** *** 53,62 **** def GetDates(self): ! import os ! statb = os.stat(self.as_pathname()) ! return statb.st_ctime, statb.st_mtime, 0 ! def SetDates(self, *dates): ! pass # print "FSSpec.SetDates not yet implemented" class FSRef(Carbon.File.FSRef): --- 70,87 ---- def GetDates(self): ! catInfoFlags = kFSCatInfoCreateDate|kFSCatInfoContentMod|kFSCatInfoBackupDate ! catinfo, d1, d2, d3 = FSRef(self).FSGetCatalogInfo(catInfoFlags) ! cdate = catinfo.createDate ! mdate = catinfo.contentModDate ! bdate = catinfo.backupDate ! return _utc2time(cdate), _utc2time(mdate), _utc2time(bdate) ! def SetDates(self, cdate, mdate, bdate): ! catInfoFlags = kFSCatInfoCreateDate|kFSCatInfoContentMod|kFSCatInfoBackupDate ! catinfo = Carbon.File.FSCatalogInfo( ! createDate = _time2utc(cdate), ! contentModDate = _time2utc(mdate), ! backupDate = _time2utc(bdate)) ! FSRef(self).FSSetCatalogInfo(catInfoFlags, catinfo) class FSRef(Carbon.File.FSRef): From jackjansen@users.sourceforge.net Wed Jan 15 22:36:18 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 15 Jan 2003 14:36:18 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/file _Filemodule.c,1.12,1.13 filesupport.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/file In directory sc8-pr-cvs1:/tmp/cvs-serv26831/Mac/Modules/file Modified Files: _Filemodule.c filesupport.py Log Message: Implemented FSCatalogInfo structure support, and used this to implement FSSpec.SetDates() and GetDates(). Closes #662836. Index: _Filemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/_Filemodule.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** _Filemodule.c 12 Jan 2003 23:01:44 -0000 1.12 --- _Filemodule.c 15 Jan 2003 22:36:16 -0000 1.13 *************** *** 371,375 **** "accessDate", "backupDate", - "permissions", "valence", "dataLogicalSize", --- 371,374 ---- *************** *** 381,385 **** , 0}; ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "|HhllO&O&O&O&O&(llll)llllllb", kw, &((FSCatalogInfoObject *)self)->ob_itself.nodeFlags, &((FSCatalogInfoObject *)self)->ob_itself.volume, &((FSCatalogInfoObject *)self)->ob_itself.parentDirID, --- 380,384 ---- , 0}; ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "|HhllO&O&O&O&O&llllllb", kw, &((FSCatalogInfoObject *)self)->ob_itself.nodeFlags, &((FSCatalogInfoObject *)self)->ob_itself.volume, &((FSCatalogInfoObject *)self)->ob_itself.parentDirID, *************** *** 390,397 **** UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.accessDate, UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.backupDate, - &((FSCatalogInfoObject *)self)->ob_itself.permissions[0], - &((FSCatalogInfoObject *)self)->ob_itself.permissions[1], - &((FSCatalogInfoObject *)self)->ob_itself.permissions[2], - &((FSCatalogInfoObject *)self)->ob_itself.permissions[3], &((FSCatalogInfoObject *)self)->ob_itself.valence, &((FSCatalogInfoObject *)self)->ob_itself.dataLogicalSize, --- 389,392 ---- Index: filesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filesupport.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** filesupport.py 12 Jan 2003 23:01:46 -0000 1.11 --- filesupport.py 15 Jan 2003 22:36:16 -0000 1.12 *************** *** 414,418 **** ] # The same info, but in a different form ! INITFORMAT = "HhllO&O&O&O&O&(llll)llllllb" INITARGS = """&((FSCatalogInfoObject *)self)->ob_itself.nodeFlags, &((FSCatalogInfoObject *)self)->ob_itself.volume, --- 414,418 ---- ] # The same info, but in a different form ! INITFORMAT = "HhllO&O&O&O&O&llllllb" INITARGS = """&((FSCatalogInfoObject *)self)->ob_itself.nodeFlags, &((FSCatalogInfoObject *)self)->ob_itself.volume, *************** *** 424,431 **** UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.accessDate, UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.backupDate, - &((FSCatalogInfoObject *)self)->ob_itself.permissions[0], - &((FSCatalogInfoObject *)self)->ob_itself.permissions[1], - &((FSCatalogInfoObject *)self)->ob_itself.permissions[2], - &((FSCatalogInfoObject *)self)->ob_itself.permissions[3], &((FSCatalogInfoObject *)self)->ob_itself.valence, &((FSCatalogInfoObject *)self)->ob_itself.dataLogicalSize, --- 424,427 ---- *************** *** 445,449 **** "accessDate", "backupDate", - "permissions", "valence", "dataLogicalSize", --- 441,444 ---- From jackjansen@users.sourceforge.net Wed Jan 15 22:45:50 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 15 Jan 2003 14:45:50 -0800 Subject: [Python-checkins] python/dist/src/Lib macpath.py,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28460/Lib Modified Files: macpath.py Log Message: Added ismount(). Fixes #661762, bugfix candidate. Index: macpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/macpath.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** macpath.py 3 Jan 2003 18:01:55 -0000 1.43 --- macpath.py 15 Jan 2003 22:45:48 -0000 1.44 *************** *** 85,88 **** --- 85,93 ---- def basename(s): return split(s)[1] + def ismount(s): + if not isabs(s): + return False + components = split(s) + return len(components) == 2 and components[1] == '' def isdir(s): From jackjansen@users.sourceforge.net Wed Jan 15 22:59:41 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 15 Jan 2003 14:59:41 -0800 Subject: [Python-checkins] python/dist/src/Lib _strptime.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv29981 Modified Files: _strptime.py Log Message: Checking in Brett Cannon's patch #662053, which fixes bug #661354. _strptime can now handle getting two empty strings as the timezone information. Index: _strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/_strptime.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** _strptime.py 30 Dec 2002 22:23:12 -0000 1.8 --- _strptime.py 15 Jan 2003 22:59:39 -0000 1.9 *************** *** 259,269 **** # '3' needed for when no leading zero. ('2', '%w'), ('10', '%I')): ! try: ! # Done this way to deal with possible lack of locale info ! # manifesting itself as the empty string (i.e., Swedish's ! # lack of AM/PM info). current_format = current_format.replace(old, new) - except ValueError: - pass time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0)) if time.strftime(directive, time_tuple).find('00'): --- 259,268 ---- # '3' needed for when no leading zero. ('2', '%w'), ('10', '%I')): ! # Must deal with possible lack of locale info ! # manifesting itself as the empty string (e.g., Swedish's ! # lack of AM/PM info) or a platform returning a tuple of empty ! # strings (e.g., MacOS 9 having timezone as ('','')). ! if old: current_format = current_format.replace(old, new) time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0)) if time.strftime(directive, time_tuple).find('00'): *************** *** 352,356 **** def __seqToRE(self, to_convert, directive): ! """Convert a list to a regex string for matching directive.""" def sorter(a, b): """Sort based on length. --- 351,355 ---- def __seqToRE(self, to_convert, directive): ! """Convert a list to a regex string for matching a directive.""" def sorter(a, b): """Sort based on length. *************** *** 371,374 **** --- 370,378 ---- to_convert = to_convert[:] # Don't want to change value in-place. + for value in to_convert: + if value != '': + break + else: + return '' to_convert.sort(sorter) regex = '|'.join(to_convert) *************** *** 474,478 **** if locale_time.timezone[0] == locale_time.timezone[1]: pass #Deals with bad locale setup where timezone info is ! # the same; first found on FreeBSD 4.4 -current elif locale_time.timezone[0].lower() == found_zone: tz = 0 --- 478,482 ---- if locale_time.timezone[0] == locale_time.timezone[1]: pass #Deals with bad locale setup where timezone info is ! # the same; first found on FreeBSD 4.4. elif locale_time.timezone[0].lower() == found_zone: tz = 0 From mhammond@users.sourceforge.net Wed Jan 15 23:38:17 2003 From: mhammond@users.sourceforge.net (mhammond@users.sourceforge.net) Date: Wed, 15 Jan 2003 15:38:17 -0800 Subject: [Python-checkins] python/dist/src/PC _winreg.c,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1:/tmp/cvs-serv2785 Modified Files: _winreg.c Log Message: Correct docstring for SetValueEx() Index: _winreg.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/_winreg.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** _winreg.c 20 Dec 2002 20:13:35 -0000 1.13 --- _winreg.c 15 Jan 2003 23:38:15 -0000 1.14 *************** *** 259,263 **** "\n" "key is an already open key, or any one of the predefined HKEY_* constants.\n" ! "sub_key is a string that names the subkey with which the value is associated.\n" "type is an integer that specifies the type of the data. This should be one of:\n" " REG_BINARY -- Binary data in any form.\n" --- 259,263 ---- "\n" "key is an already open key, or any one of the predefined HKEY_* constants.\n" ! "value_name is a string containing the name of the value to set, or None\n" "type is an integer that specifies the type of the data. This should be one of:\n" " REG_BINARY -- Binary data in any form.\n" From jackjansen@users.sourceforge.net Wed Jan 15 23:43:04 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 15 Jan 2003 15:43:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_logging.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv3348 Modified Files: test_logging.py Log Message: On Mac OS X calling setlocale will raise locale.Error. This isn't fatal, so just continue testing. Fixes #668787. Index: test_logging.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_logging.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_logging.py 5 Jan 2003 18:15:23 -0000 1.2 --- test_logging.py 15 Jan 2003 23:43:02 -0000 1.3 *************** *** 32,37 **** try: locale.setlocale(locale.LC_ALL, '') ! except ValueError: # this happens on a Solaris box which only supports "C" locale pass --- 32,38 ---- try: locale.setlocale(locale.LC_ALL, '') ! except (ValueError, locale.Error): # this happens on a Solaris box which only supports "C" locale + # or a Mac OS X box which supports very little locale stuff at all pass From mhammond@users.sourceforge.net Thu Jan 16 04:56:55 2003 From: mhammond@users.sourceforge.net (mhammond@users.sourceforge.net) Date: Wed, 15 Jan 2003 20:56:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_repr.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv31281 Modified Files: test_repr.py Log Message: This test previously failed when run from the 'test' directory. In that case, the test module created is actually a sub-package of 'test', thus the module is named 'test.areallylongpackage...' - this caused failure. Replace the hard-coded module names with __name__ attributes, which correctly reflects any hierarchy. Index: test_repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_repr.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** test_repr.py 23 Jul 2002 19:04:00 -0000 1.14 --- test_repr.py 16 Jan 2003 04:56:52 -0000 1.15 *************** *** 195,199 **** from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation eq(repr(areallylongpackageandmodulenametotestreprtruncation), ! "" % areallylongpackageandmodulenametotestreprtruncation.__file__) eq(repr(sys), "") --- 195,199 ---- from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation eq(repr(areallylongpackageandmodulenametotestreprtruncation), ! "" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__)) eq(repr(sys), "") *************** *** 206,210 **** from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo eq(repr(foo.foo), ! "") def test_object(self): --- 206,210 ---- from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo eq(repr(foo.foo), ! "" % foo.__name__) def test_object(self): *************** *** 219,224 **** ''') from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar self.failUnless(repr(bar.bar).startswith( ! " Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28418/Lib Modified Files: copy.py Log Message: Support copying booleans. Fixes #668925. Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** copy.py 12 Aug 2002 20:20:08 -0000 1.29 --- copy.py 16 Jan 2003 10:40:00 -0000 1.30 *************** *** 97,100 **** --- 97,101 ---- d[types.LongType] = _copy_atomic d[types.FloatType] = _copy_atomic + d[types.BooleanType] = _copy_atomic try: d[types.ComplexType] = _copy_atomic *************** *** 197,200 **** --- 198,202 ---- d[types.LongType] = _deepcopy_atomic d[types.FloatType] = _deepcopy_atomic + d[types.BooleanType] = _deepcopy_atomic try: d[types.ComplexType] = _deepcopy_atomic From loewis@users.sourceforge.net Thu Jan 16 11:02:46 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Thu, 16 Jan 2003 03:02:46 -0800 Subject: [Python-checkins] python/dist/src/Lib compileall.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv30087/Lib Modified Files: compileall.py Log Message: Catch IOErrors. Index: compileall.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compileall.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** compileall.py 15 Jan 2003 11:51:06 -0000 1.13 --- compileall.py 16 Jan 2003 11:02:43 -0000 1.14 *************** *** 69,72 **** --- 69,75 ---- print err.msg success = 0 + except IOError, e: + print "Sorry", e + success = 0 else: if ok == 0: From loewis@users.sourceforge.net Thu Jan 16 11:03:35 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Thu, 16 Jan 2003 03:03:35 -0800 Subject: [Python-checkins] python/dist/src/Tools/idle setup.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory sc8-pr-cvs1:/tmp/cvs-serv30193/Tools/idle Modified Files: setup.py Log Message: Properly find and install icons even if calling setup.py from the build dir. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/setup.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** setup.py 6 Nov 2002 21:59:33 -0000 1.4 --- setup.py 16 Jan 2003 11:03:33 -0000 1.5 *************** *** 27,31 **** # the normal build_py would not incorporate the .txt files txt_files = ['config-unix.txt','config-win.txt','config.txt', 'help.txt'] ! Icons = glob.glob1("Icons","*.gif") class idle_build_py(build_py): def get_plain_outfile(self, build_dir, package, file): --- 27,31 ---- # the normal build_py would not incorporate the .txt files txt_files = ['config-unix.txt','config-win.txt','config.txt', 'help.txt'] ! Icons = glob.glob1(os.path.join(package_dir,"Icons"),"*.gif") class idle_build_py(build_py): def get_plain_outfile(self, build_dir, package, file): *************** *** 49,53 **** dir = os.path.dirname(outfile) self.mkpath(dir) ! self.copy_file(os.path.join("Icons",name), outfile, preserve_mode = 0) --- 49,53 ---- dir = os.path.dirname(outfile) self.mkpath(dir) ! self.copy_file(os.path.join(package_dir, "Icons", name), outfile, preserve_mode = 0) From loewis@users.sourceforge.net Thu Jan 16 11:30:11 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Thu, 16 Jan 2003 03:30:11 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv32269 Modified Files: ref6.tex Log Message: Patch #662454: import a.b as c is ok, fixes #660811. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** ref6.tex 6 Jan 2003 12:54:54 -0000 1.59 --- ref6.tex 16 Jan 2003 11:30:08 -0000 1.60 *************** *** 679,687 **** the next identifier, if any. If the module name is followed by \keyword{as}, the name following \keyword{as} is used as the local ! name for the module. To avoid confusion, you cannot import modules ! with dotted names \keyword{as} a different local name. So \code{import ! module as m} is legal, but \code{import module.submod as s} is not. ! The latter should be written as \code{from module import submod as s}; ! see below. The \keyword{from} form does not bind the module name: it goes through the --- 679,683 ---- the next identifier, if any. If the module name is followed by \keyword{as}, the name following \keyword{as} is used as the local ! name for the module. The \keyword{from} form does not bind the module name: it goes through the From rhettinger@users.sourceforge.net Thu Jan 16 12:02:37 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 16 Jan 2003 04:02:37 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_bisect.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv2304 Modified Files: test_bisect.py Log Message: Convert to unittest format so that more tests can be added cleanly. Index: test_bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bisect.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_bisect.py 30 Jul 2002 23:26:01 -0000 1.2 --- test_bisect.py 16 Jan 2003 12:02:35 -0000 1.3 *************** *** 1,127 **** ! from test.test_support import TestFailed ! import bisect ! import sys - nerrors = 0 ! def check_bisect(func, list, elt, expected): ! global nerrors ! got = func(list, elt) ! if got != expected: ! print >> sys.stderr, \ ! "expected %s(%s, %s) -> %s, but got %s" % (func.__name__, ! list, ! elt, ! expected, ! got) ! nerrors += 1 ! # XXX optional slice arguments need tests. ! check_bisect(bisect.bisect_right, [], 1, 0) ! check_bisect(bisect.bisect_right, [1], 0, 0) ! check_bisect(bisect.bisect_right, [1], 1, 1) ! check_bisect(bisect.bisect_right, [1], 2, 1) ! check_bisect(bisect.bisect_right, [1, 1], 0, 0) ! check_bisect(bisect.bisect_right, [1, 1], 1, 2) ! check_bisect(bisect.bisect_right, [1, 1], 2, 2) ! check_bisect(bisect.bisect_right, [1, 1, 1], 0, 0) ! check_bisect(bisect.bisect_right, [1, 1, 1], 1, 3) ! check_bisect(bisect.bisect_right, [1, 1, 1], 2, 3) ! check_bisect(bisect.bisect_right, [1, 1, 1, 1], 0, 0) ! check_bisect(bisect.bisect_right, [1, 1, 1, 1], 1, 4) ! check_bisect(bisect.bisect_right, [1, 1, 1, 1], 2, 4) ! check_bisect(bisect.bisect_right, [1, 2], 0, 0) ! check_bisect(bisect.bisect_right, [1, 2], 1, 1) ! check_bisect(bisect.bisect_right, [1, 2], 1.5, 1) ! check_bisect(bisect.bisect_right, [1, 2], 2, 2) ! check_bisect(bisect.bisect_right, [1, 2], 3, 2) ! check_bisect(bisect.bisect_right, [1, 1, 2, 2], 0, 0) ! check_bisect(bisect.bisect_right, [1, 1, 2, 2], 1, 2) ! check_bisect(bisect.bisect_right, [1, 1, 2, 2], 1.5, 2) ! check_bisect(bisect.bisect_right, [1, 1, 2, 2], 2, 4) ! check_bisect(bisect.bisect_right, [1, 1, 2, 2], 3, 4) ! check_bisect(bisect.bisect_right, [1, 2, 3], 0, 0) ! check_bisect(bisect.bisect_right, [1, 2, 3], 1, 1) ! check_bisect(bisect.bisect_right, [1, 2, 3], 1.5, 1) ! check_bisect(bisect.bisect_right, [1, 2, 3], 2, 2) ! check_bisect(bisect.bisect_right, [1, 2, 3], 2.5, 2) ! check_bisect(bisect.bisect_right, [1, 2, 3], 3, 3) ! check_bisect(bisect.bisect_right, [1, 2, 3], 4, 3) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10) ! check_bisect(bisect.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10) ! check_bisect(bisect.bisect_left, [], 1, 0) ! check_bisect(bisect.bisect_left, [1], 0, 0) ! check_bisect(bisect.bisect_left, [1], 1, 0) ! check_bisect(bisect.bisect_left, [1], 2, 1) ! check_bisect(bisect.bisect_left, [1, 1], 0, 0) ! check_bisect(bisect.bisect_left, [1, 1], 1, 0) ! check_bisect(bisect.bisect_left, [1, 1], 2, 2) ! check_bisect(bisect.bisect_left, [1, 1, 1], 0, 0) ! check_bisect(bisect.bisect_left, [1, 1, 1], 1, 0) ! check_bisect(bisect.bisect_left, [1, 1, 1], 2, 3) ! check_bisect(bisect.bisect_left, [1, 1, 1, 1], 0, 0) ! check_bisect(bisect.bisect_left, [1, 1, 1, 1], 1, 0) ! check_bisect(bisect.bisect_left, [1, 1, 1, 1], 2, 4) ! check_bisect(bisect.bisect_left, [1, 2], 0, 0) ! check_bisect(bisect.bisect_left, [1, 2], 1, 0) ! check_bisect(bisect.bisect_left, [1, 2], 1.5, 1) ! check_bisect(bisect.bisect_left, [1, 2], 2, 1) ! check_bisect(bisect.bisect_left, [1, 2], 3, 2) ! check_bisect(bisect.bisect_left, [1, 1, 2, 2], 0, 0) ! check_bisect(bisect.bisect_left, [1, 1, 2, 2], 1, 0) ! check_bisect(bisect.bisect_left, [1, 1, 2, 2], 1.5, 2) ! check_bisect(bisect.bisect_left, [1, 1, 2, 2], 2, 2) ! check_bisect(bisect.bisect_left, [1, 1, 2, 2], 3, 4) ! check_bisect(bisect.bisect_left, [1, 2, 3], 0, 0) ! check_bisect(bisect.bisect_left, [1, 2, 3], 1, 0) ! check_bisect(bisect.bisect_left, [1, 2, 3], 1.5, 1) ! check_bisect(bisect.bisect_left, [1, 2, 3], 2, 1) ! check_bisect(bisect.bisect_left, [1, 2, 3], 2.5, 2) ! check_bisect(bisect.bisect_left, [1, 2, 3], 3, 2) ! check_bisect(bisect.bisect_left, [1, 2, 3], 4, 3) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6) ! check_bisect(bisect.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10) ! def check_insort(n): ! global nerrors ! from random import choice ! import sys ! digits = "0123456789" ! raw = [] ! insorted = [] ! for i in range(n): ! digit = choice(digits) ! raw.append(digit) ! if digit in "02468": ! f = bisect.insort_left ! else: ! f = bisect.insort_right ! f(insorted, digit) ! sorted = raw[:] ! sorted.sort() ! if sorted == insorted: ! return ! print >> sys.stderr, "insort test failed: raw %s got %s" % (raw, insorted) ! nerrors += 1 ! check_insort(500) - if nerrors: - raise TestFailed("%d errors in test_bisect" % nerrors) --- 1,136 ---- ! import unittest ! from test import test_support ! from bisect import bisect_right, bisect_left, insort_left, insort_right ! # XXX optional slice arguments need tests. ! class TestBisect(unittest.TestCase): ! precomputedCases = [ ! (bisect_right, [], 1, 0), ! (bisect_right, [1], 0, 0), ! (bisect_right, [1], 1, 1), ! (bisect_right, [1], 2, 1), ! (bisect_right, [1, 1], 0, 0), ! (bisect_right, [1, 1], 1, 2), ! (bisect_right, [1, 1], 2, 2), ! (bisect_right, [1, 1, 1], 0, 0), ! (bisect_right, [1, 1, 1], 1, 3), ! (bisect_right, [1, 1, 1], 2, 3), ! (bisect_right, [1, 1, 1, 1], 0, 0), ! (bisect_right, [1, 1, 1, 1], 1, 4), ! (bisect_right, [1, 1, 1, 1], 2, 4), ! (bisect_right, [1, 2], 0, 0), ! (bisect_right, [1, 2], 1, 1), ! (bisect_right, [1, 2], 1.5, 1), ! (bisect_right, [1, 2], 2, 2), ! (bisect_right, [1, 2], 3, 2), ! (bisect_right, [1, 1, 2, 2], 0, 0), ! (bisect_right, [1, 1, 2, 2], 1, 2), ! (bisect_right, [1, 1, 2, 2], 1.5, 2), ! (bisect_right, [1, 1, 2, 2], 2, 4), ! (bisect_right, [1, 1, 2, 2], 3, 4), ! (bisect_right, [1, 2, 3], 0, 0), ! (bisect_right, [1, 2, 3], 1, 1), ! (bisect_right, [1, 2, 3], 1.5, 1), ! (bisect_right, [1, 2, 3], 2, 2), ! (bisect_right, [1, 2, 3], 2.5, 2), ! (bisect_right, [1, 2, 3], 3, 3), ! (bisect_right, [1, 2, 3], 4, 3), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10), ! (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10), ! (bisect_left, [], 1, 0), ! (bisect_left, [1], 0, 0), ! (bisect_left, [1], 1, 0), ! (bisect_left, [1], 2, 1), ! (bisect_left, [1, 1], 0, 0), ! (bisect_left, [1, 1], 1, 0), ! (bisect_left, [1, 1], 2, 2), ! (bisect_left, [1, 1, 1], 0, 0), ! (bisect_left, [1, 1, 1], 1, 0), ! (bisect_left, [1, 1, 1], 2, 3), ! (bisect_left, [1, 1, 1, 1], 0, 0), ! (bisect_left, [1, 1, 1, 1], 1, 0), ! (bisect_left, [1, 1, 1, 1], 2, 4), ! (bisect_left, [1, 2], 0, 0), ! (bisect_left, [1, 2], 1, 0), ! (bisect_left, [1, 2], 1.5, 1), ! (bisect_left, [1, 2], 2, 1), ! (bisect_left, [1, 2], 3, 2), ! (bisect_left, [1, 1, 2, 2], 0, 0), ! (bisect_left, [1, 1, 2, 2], 1, 0), ! (bisect_left, [1, 1, 2, 2], 1.5, 2), ! (bisect_left, [1, 1, 2, 2], 2, 2), ! (bisect_left, [1, 1, 2, 2], 3, 4), ! (bisect_left, [1, 2, 3], 0, 0), ! (bisect_left, [1, 2, 3], 1, 0), ! (bisect_left, [1, 2, 3], 1.5, 1), ! (bisect_left, [1, 2, 3], 2, 1), ! (bisect_left, [1, 2, 3], 2.5, 2), ! (bisect_left, [1, 2, 3], 3, 2), ! (bisect_left, [1, 2, 3], 4, 3), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6), ! (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10) ! ] ! def test_precomputed(self): ! for func, list, elt, expected in self.precomputedCases: ! self.assertEqual(func(list, elt), expected) ! #============================================================================== ! class TestInsort(unittest.TestCase): ! ! def test_vsListSort(self, n=500): ! from random import choice ! digits = "0123456789" ! raw = [] ! insorted = [] ! for i in range(n): ! digit = choice(digits) ! raw.append(digit) ! if digit in "02468": ! f = insort_left ! else: ! f = insort_right ! f(insorted, digit) ! sorted = raw[:] ! sorted.sort() ! self.assertEqual(sorted, insorted) ! ! #============================================================================== ! ! def makeAllTests(): ! suite = unittest.TestSuite() ! for klass in (TestBisect, ! TestInsort ! ): ! suite.addTest(unittest.makeSuite(klass)) ! return suite ! ! #------------------------------------------------------------------------------ ! ! def test_main(verbose=None): ! from test import test_bisect ! suite = makeAllTests() ! test_support.run_suite(suite) ! ! if __name__ == "__main__": ! test_main(verbose=True) From rhettinger@users.sourceforge.net Thu Jan 16 12:31:38 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 16 Jan 2003 04:31:38 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_bisect.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv4539 Modified Files: test_bisect.py Log Message: Added doctest for examples in the library reference. Added random test from bisect to augment the finite precomputed checks. Index: test_bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bisect.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_bisect.py 16 Jan 2003 12:02:35 -0000 1.3 --- test_bisect.py 16 Jan 2003 12:31:36 -0000 1.4 *************** *** 94,97 **** --- 94,114 ---- self.assertEqual(func(list, elt), expected) + def test_random(self, n=20): + from random import randrange + for i in xrange(n): + data = [randrange(0, n, 2) for j in xrange(i)] + data.sort() + elem = randrange(n) + ip = bisect_left(data, elem) + if ip < len(data): + self.failUnless(elem <= data[ip]) + if ip > 0: + self.failUnless(data[ip-1] < elem) + ip = bisect_right(data, elem) + if ip < len(data): + self.failUnless(elem < data[ip]) + if ip > 0: + self.failUnless(data[ip-1] <= elem) + #============================================================================== *************** *** 117,120 **** --- 134,177 ---- #============================================================================== + libreftest = """ + Example from the Library Reference: Doc/lib/libbisect.tex + + The bisect() function is generally useful for categorizing numeric data. + This example uses bisect() to look up a letter grade for an exam total + (say) based on a set of ordered numeric breakpoints: 85 and up is an `A', + 75..84 is a `B', etc. + + >>> grades = "FEDCBA" + >>> breakpoints = [30, 44, 66, 75, 85] + >>> from bisect import bisect + >>> def grade(total): + ... return grades[bisect(breakpoints, total)] + ... + >>> grade(66) + 'C' + >>> map(grade, [33, 99, 77, 44, 12, 88]) + ['E', 'A', 'B', 'D', 'F', 'A'] + + The bisect module can be used with the Queue module to implement + a priority queue (example courtesy of Fredrik Lundh): + + >>> import Queue, bisect + >>> class PriorityQueue(Queue.Queue): + ... def _put(self, item): + ... bisect.insort(self.queue, item) + ... + >>> queue = PriorityQueue(0) + >>> queue.put((2, "second")) + >>> queue.put((1, "first")) + >>> queue.put((3, "third")) + >>> queue.get() + (1, 'first') + >>> queue.get() + (2, 'second') + + """ + + #============================================================================== + def makeAllTests(): suite = unittest.TestSuite() *************** *** 127,134 **** --- 184,194 ---- #------------------------------------------------------------------------------ + __test__ = {'libreftest' : libreftest} + def test_main(verbose=None): from test import test_bisect suite = makeAllTests() test_support.run_suite(suite) + test_support.run_doctest(test_bisect, verbose) if __name__ == "__main__": From rhettinger@users.sourceforge.net Thu Jan 16 13:02:27 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 16 Jan 2003 05:02:27 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_bisect.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv8100 Modified Files: test_bisect.py Log Message: Test optional slice arguments. Add backwards compatibility test. Index: test_bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bisect.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_bisect.py 16 Jan 2003 12:31:36 -0000 1.4 --- test_bisect.py 16 Jan 2003 13:02:25 -0000 1.5 *************** *** 1,8 **** import unittest from test import test_support ! from bisect import bisect_right, bisect_left, insort_left, insort_right ! ! # XXX optional slice arguments need tests. ! class TestBisect(unittest.TestCase): --- 1,5 ---- import unittest from test import test_support ! from bisect import bisect_right, bisect_left, insort_left, insort_right, insort, bisect class TestBisect(unittest.TestCase): *************** *** 111,114 **** --- 108,121 ---- self.failUnless(data[ip-1] <= elem) + def test_optionalSlicing(self): + for func, list, elt, expected in self.precomputedCases: + lo = min(len(list), 1) + self.failUnless(func(list, elt, lo=lo) >= lo) + hi = min(len(list), 2) + self.failUnless(func(list, elt, hi=hi) <= hi) + + def test_backcompatibility(self): + self.assertEqual(bisect, bisect_right) + #============================================================================== *************** *** 131,134 **** --- 138,144 ---- sorted.sort() self.assertEqual(sorted, insorted) + + def test_backcompatibility(self): + self.assertEqual(insort, insort_right) #============================================================================== From rhettinger@users.sourceforge.net Thu Jan 16 14:00:17 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 16 Jan 2003 06:00:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_bisect.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14733 Modified Files: test_bisect.py Log Message: Let test_random cover the endpoints. Strengthen slicing tests. Improved variable names. Index: test_bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bisect.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_bisect.py 16 Jan 2003 13:02:25 -0000 1.5 --- test_bisect.py 16 Jan 2003 14:00:15 -0000 1.6 *************** *** 88,100 **** def test_precomputed(self): ! for func, list, elt, expected in self.precomputedCases: ! self.assertEqual(func(list, elt), expected) ! def test_random(self, n=20): from random import randrange for i in xrange(n): data = [randrange(0, n, 2) for j in xrange(i)] data.sort() ! elem = randrange(n) ip = bisect_left(data, elem) if ip < len(data): --- 88,100 ---- def test_precomputed(self): ! for func, data, elem, expected in self.precomputedCases: ! self.assertEqual(func(data, elem), expected) ! def test_random(self, n=25): from random import randrange for i in xrange(n): data = [randrange(0, n, 2) for j in xrange(i)] data.sort() ! elem = randrange(-1, n+1) ip = bisect_left(data, elem) if ip < len(data): *************** *** 109,117 **** def test_optionalSlicing(self): ! for func, list, elt, expected in self.precomputedCases: ! lo = min(len(list), 1) ! self.failUnless(func(list, elt, lo=lo) >= lo) ! hi = min(len(list), 2) ! self.failUnless(func(list, elt, hi=hi) <= hi) def test_backcompatibility(self): --- 109,128 ---- def test_optionalSlicing(self): ! for func, data, elem, expected in self.precomputedCases: ! for lo in xrange(4): ! lo = min(len(data), lo) ! for hi in xrange(3,8): ! hi = min(len(data), hi) ! ip = func(data, elem, lo, hi) ! self.failUnless(lo <= ip <= hi) ! if func is bisect_left and ip < hi: ! self.failUnless(elem <= data[ip]) ! if func is bisect_left and ip > lo: ! self.failUnless(data[ip-1] < elem) ! if func is bisect_right and ip < hi: ! self.failUnless(elem < data[ip]) ! if func is bisect_right and ip > lo: ! self.failUnless(data[ip-1] <= elem) ! self.assertEqual(ip, max(lo, min(hi, expected))) def test_backcompatibility(self): From mwh@users.sourceforge.net Thu Jan 16 15:39:09 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 16 Jan 2003 07:39:09 -0800 Subject: [Python-checkins] python/dist/src/Python compile.c,2.271,2.272 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv26729 Modified Files: compile.c Log Message: A. Lloyd Flanagan pointed out a spelling error on c.l.py. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.271 retrieving revision 2.272 diff -C2 -d -r2.271 -r2.272 *** compile.c 31 Dec 2002 18:17:44 -0000 2.271 --- compile.c 16 Jan 2003 15:39:07 -0000 2.272 *************** *** 996,1000 **** char *msg; if (assigning) ! msg = "assigment to None"; else msg = "deleting None"; --- 996,1000 ---- char *msg; if (assigning) ! msg = "assignment to None"; else msg = "deleting None"; From tim_one@users.sourceforge.net Fri Jan 17 01:08:49 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 16 Jan 2003 17:08:49 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime PSF.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv8147 Modified Files: PSF.py Log Message: Work with datetimes instead of datetimetzs. Index: PSF.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/PSF.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PSF.py 2 Jan 2003 22:20:52 -0000 1.2 --- PSF.py 17 Jan 2003 01:08:47 -0000 1.3 *************** *** 7,11 **** """ ! from datetime import datetimetz from dateutil import TUESDAY, weekday_of_month --- 7,11 ---- """ ! from datetime import datetime from dateutil import TUESDAY, weekday_of_month *************** *** 22,29 **** } ! # A vector of 12 datetimetzs, all in Eastern. def psf_times_for_a_year(year): # 1pm Eastern on the second Tuesday of the month. ! base = datetimetz(year, 1, 1, 13, tzinfo=Eastern) return [weekday_of_month(TUESDAY, base.replace(month=i), 1) for i in range(1, 13)] --- 22,29 ---- } ! # A vector of 12 datetimes, all in Eastern. def psf_times_for_a_year(year): # 1pm Eastern on the second Tuesday of the month. ! base = datetime(year, 1, 1, 13, tzinfo=Eastern) return [weekday_of_month(TUESDAY, base.replace(month=i), 1) for i in range(1, 13)] From greg@users.sourceforge.net Fri Jan 17 07:53:01 2003 From: greg@users.sourceforge.net (greg@users.sourceforge.net) Date: Thu, 16 Jan 2003 23:53:01 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb/test test_basics.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb/test In directory sc8-pr-cvs1:/tmp/cvs-serv5715/bsddb/test Modified Files: test_basics.py Log Message: bugfix: disallow use of DB_TXN after commit() or abort(), prevents a coredump or segmentation violation. Sourceforge patch ID 664896: http://sourceforge.net/tracker/index.php?func=detail&aid=664896&group_id=13900&atid=313900 The bug was reported on the pybsddb-users mailing list. Index: test_basics.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_basics.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_basics.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_basics.py 17 Jan 2003 07:52:59 -0000 1.4 *************** *** 605,608 **** --- 605,628 ---- txn.commit() + #---------------------------------------- + + def test08_TxnLateUse(self): + txn = self.env.txn_begin() + txn.abort() + try: + txn.abort() + except db.DBError, e: + pass + else: + raise RuntimeError, "DBTxn.abort() called after DB_TXN no longer valid w/o an exception" + + txn = self.env.txn_begin() + txn.commit() + try: + txn.commit() + except db.DBError, e: + pass + else: + raise RuntimeError, "DBTxn.commit() called after DB_TXN no longer valid w/o an exception" From greg@users.sourceforge.net Fri Jan 17 07:53:01 2003 From: greg@users.sourceforge.net (greg@users.sourceforge.net) Date: Thu, 16 Jan 2003 23:53:01 -0800 Subject: [Python-checkins] python/dist/src/Modules _bsddb.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv5715/extsrc Modified Files: _bsddb.c Log Message: bugfix: disallow use of DB_TXN after commit() or abort(), prevents a coredump or segmentation violation. Sourceforge patch ID 664896: http://sourceforge.net/tracker/index.php?func=detail&aid=664896&group_id=13900&atid=313900 The bug was reported on the pybsddb-users mailing list. Index: _bsddb.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _bsddb.c 30 Dec 2002 20:53:52 -0000 1.3 --- _bsddb.c 17 Jan 2003 07:52:59 -0000 1.4 *************** *** 86,90 **** #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) ! #define PY_BSDDB_VERSION "4.1.1" static char *rcs_id = "$Id$"; --- 86,90 ---- #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) ! #define PY_BSDDB_VERSION "4.1.2" static char *rcs_id = "$Id$"; *************** *** 466,469 **** --- 466,470 ---- if (errObj != NULL) { + /* FIXME this needs proper bounds checking on errTxt */ strcpy(errTxt, db_strerror(err)); if (_db_errmsg[0]) { *************** *** 3723,3735 **** { int flags=0, err; if (!PyArg_ParseTuple(args, "|i:commit", &flags)) return NULL; MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 40) ! err = self->txn->commit(self->txn, flags); #else ! err = txn_commit(self->txn, flags); #endif MYDB_END_ALLOW_THREADS; --- 3724,3744 ---- { int flags=0, err; + DB_TXN *txn; if (!PyArg_ParseTuple(args, "|i:commit", &flags)) return NULL; + if (!self->txn) { + PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, + "DBTxn must not be used after txn_commit or txn_abort")); + return NULL; + } + txn = self->txn; + self->txn = NULL; /* this DB_TXN is no longer valid after this call */ MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 40) ! err = txn->commit(txn, flags); #else ! err = txn_commit(txn, flags); #endif MYDB_END_ALLOW_THREADS; *************** *** 3755,3758 **** --- 3764,3772 ---- } + if (!self->txn) { + PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, + "DBTxn must not be used after txn_commit or txn_abort")); + return NULL; + } MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 40) *************** *** 3770,3773 **** --- 3784,3792 ---- return NULL; + if (!self->txn) { + PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, + "DBTxn must not be used after txn_commit or txn_abort")); + return NULL; + } MYDB_BEGIN_ALLOW_THREADS; err = txn_prepare(self->txn); *************** *** 3783,3795 **** { int err; if (!PyArg_ParseTuple(args, ":abort")) return NULL; MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 40) ! err = self->txn->abort(self->txn); #else ! err = txn_abort(self->txn); #endif MYDB_END_ALLOW_THREADS; --- 3802,3822 ---- { int err; + DB_TXN *txn; if (!PyArg_ParseTuple(args, ":abort")) return NULL; + if (!self->txn) { + PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, + "DBTxn must not be used after txn_commit or txn_abort")); + return NULL; + } + txn = self->txn; + self->txn = NULL; /* this DB_TXN is no longer valid after this call */ MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 40) ! err = txn->abort(txn); #else ! err = txn_abort(txn); #endif MYDB_END_ALLOW_THREADS; *************** *** 3807,3810 **** --- 3834,3842 ---- return NULL; + if (!self->txn) { + PyErr_SetObject(DBError, Py_BuildValue("(is)", 0, + "DBTxn must not be used after txn_commit or txn_abort")); + return NULL; + } MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 40) From greg@users.sourceforge.net Fri Jan 17 07:56:18 2003 From: greg@users.sourceforge.net (greg@users.sourceforge.net) Date: Thu, 16 Jan 2003 23:56:18 -0800 Subject: [Python-checkins] python/dist/src/Modules _bsddb.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6003 Modified Files: _bsddb.c Log Message: bugfix: allow the module to work with python compiled without thread support. closes sourceforge pybsddb bug id 669533. Index: _bsddb.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** _bsddb.c 17 Jan 2003 07:52:59 -0000 1.4 --- _bsddb.c 17 Jan 2003 07:56:16 -0000 1.5 *************** *** 1073,1077 **** --- 1073,1079 ---- * (see pybsddb-users mailing list post on 2002-08-07) */ + #ifdef WITH_THREAD PyEval_InitThreads(); + #endif MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 41) From greg@users.sourceforge.net Fri Jan 17 08:42:52 2003 From: greg@users.sourceforge.net (greg@users.sourceforge.net) Date: Fri, 17 Jan 2003 00:42:52 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb/test test_basics.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb/test In directory sc8-pr-cvs1:/tmp/cvs-serv9401/bsddb/test Modified Files: test_basics.py Log Message: bugfix: do not double-close DB cursor during deallocation when the underlying DB has already been closed (and thus all of its cursors). This fixes a potential segfault. SF pybsddb bug id 667343 bugfix: close the DB object when raising an exception due to an error during DB.open. This prevents an exception when closing the environment about not all databases being closed. SF pybsddb bug id 667340 Index: test_basics.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_basics.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_basics.py 17 Jan 2003 07:52:59 -0000 1.4 --- test_basics.py 17 Jan 2003 08:42:50 -0000 1.5 *************** *** 399,402 **** --- 399,414 ---- "%s method" % method) + # + # free cursor referencing a closed database, it should not barf: + # + oldcursor = self.d.cursor(txn=txn) + self.d.close() + + # this would originally cause a segfault when the cursor for a + # closed database was cleaned up. it should not anymore. + # SF pybsddb bug id 667343 + del oldcursor + + #---------------------------------------- From greg@users.sourceforge.net Fri Jan 17 08:42:52 2003 From: greg@users.sourceforge.net (greg@users.sourceforge.net) Date: Fri, 17 Jan 2003 00:42:52 -0800 Subject: [Python-checkins] python/dist/src/Modules _bsddb.c,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv9401/extsrc Modified Files: _bsddb.c Log Message: bugfix: do not double-close DB cursor during deallocation when the underlying DB has already been closed (and thus all of its cursors). This fixes a potential segfault. SF pybsddb bug id 667343 bugfix: close the DB object when raising an exception due to an error during DB.open. This prevents an exception when closing the environment about not all databases being closed. SF pybsddb bug id 667340 Index: _bsddb.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** _bsddb.c 17 Jan 2003 07:56:16 -0000 1.5 --- _bsddb.c 17 Jan 2003 08:42:50 -0000 1.6 *************** *** 747,751 **** if (self->dbc != NULL) { MYDB_BEGIN_ALLOW_THREADS; ! err = self->dbc->c_close(self->dbc); self->dbc = NULL; MYDB_END_ALLOW_THREADS; --- 747,752 ---- if (self->dbc != NULL) { MYDB_BEGIN_ALLOW_THREADS; ! if (self->mydb->db != NULL) ! err = self->dbc->c_close(self->dbc); self->dbc = NULL; MYDB_END_ALLOW_THREADS; *************** *** 1624,1627 **** --- 1625,1629 ---- MYDB_END_ALLOW_THREADS; if (makeDBError(err)) { + self->db->close(self->db, 0); self->db = NULL; return NULL; From jackjansen@users.sourceforge.net Fri Jan 17 16:04:43 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 17 Jan 2003 08:04:43 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac EasyDialogs.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv16867 Modified Files: EasyDialogs.py Log Message: Added methods AskFileForOpen(), AskFileForSave() and AskFolder(). These are going to replace StandardGetFile() and friends. Main differences are that these allow you to ask for specific datatypes to be returned (FSSpec, FSRef, string, unicode or subtypes thereof) and that they provide access to underlying features of Navigation Services through keyword arguments. Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/EasyDialogs.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** EasyDialogs.py 30 Dec 2002 22:04:20 -0000 1.1 --- EasyDialogs.py 17 Jan 2003 16:04:39 -0000 1.2 *************** *** 24,30 **** --- 24,32 ---- from Carbon import Controls from Carbon import Menu + import Nav import MacOS import string from Carbon.ControlAccessor import * # Also import Controls constants + import Carbon.File import macfs import macresource *************** *** 547,551 **** --- 549,696 ---- apply(MacOS.SchedParams, appsw) del d + + def _mktypelist(typelist): + # Workaround for OSX typeless files: + if 'TEXT' in typelist and not '\0\0\0\0' in typelist: + typelist = typelist + ('\0\0\0\0',) + if not typelist: + return None + data = 'Pyth' + struct.pack("hh", 0, len(typelist)) + for type in typelist: + data = data+type + return Carbon.Res.Handle(data) + + _ALLOWED_KEYS = { + 'version':1, + 'defaultLocation':1, + 'dialogOptionFlags':1, + 'location':1, + 'clientName':1, + 'windowTitle':1, + 'actionButtonLabel':1, + 'cancelButtonLabel':1, + 'savedFileName':1, + 'message':1, + 'preferenceKey':1, + 'popupExtension':1, + 'eventProc':1, + 'previewProc':1, + 'filterProc':1, + 'typeList':1, + 'fileType':1, + 'fileCreator':1, + # Our extension: + 'wanted':1, + 'multiple':1, + } + + def _process_Nav_args(argsargs, allowed, dftflags): + import aepack + import Carbon.AE + import Carbon.File + args = argsargs.copy() + for k in args.keys(): + if not allowed.has_key(k): + raise TypeError, "Unknown keyword argument: %s" % repr(k) + # Set some defaults, and modify some arguments + if not args.has_key('dialogOptionFlags'): + args['dialogOptionFlags'] = dftflags + if args.has_key('defaultLocation') and \ + not isinstance(args['defaultLocation'], Carbon.AE.AEDesc): + defaultLocation = args['defaultLocation'] + if isinstance(defaultLocation, (Carbon.File.FSSpec, Carbon.File.FSRef)): + args['defaultLocation'] = aepack.pack(defaultLocation) + else: + defaultLocation = Carbon.File.FSRef(defaultLocation) + args['defaultLocation'] = aepack.pack(defaultLocation) + if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType): + typeList = args['typeList'].copy() + # Workaround for OSX typeless files: + if 'TEXT' in typeList and not '\0\0\0\0' in typeList: + typeList = typeList + ('\0\0\0\0',) + data = 'Pyth' + struct.pack("hh", 0, len(typeList)) + for type in typeList: + data = data+type + args['typeList'] = Carbon.Res.Handle(data) + tpwanted = str + if args.has_key('wanted'): + tpwanted = args['wanted'] + del args['wanted'] + return args, tpwanted + + def AskFileForOpen(**args): + default_flags = 0x56 # Or 0xe4? + args, tpwanted = _process_Nav_args(args, _ALLOWED_KEYS, default_flags) + try: + rr = Nav.NavChooseFile(args) + good = 1 + except Nav.error, arg: + if arg[0] != -128: # userCancelledErr + raise Nav.error, arg + return None + if not rr.validRecord or not rr.selection: + return None + if issubclass(tpwanted, Carbon.File.FSRef): + return tpwanted(rr.selection_fsr[0]) + if issubclass(tpwanted, Carbon.File.FSSpec): + return tpwanted(rr.selection[0]) + if issubclass(tpwanted, str): + return tpwanted(rr.selection_fsr[0].FSRefMakePath()) + if issubclass(tpwanted, unicode): + return tpwanted(rr.selection_fsr[0].FSRefMakePath(), 'utf8') + raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) + + def AskFileForSave(**args): + default_flags = 0x07 + args, tpwanted = _process_Nav_args(args, _ALLOWED_KEYS, default_flags) + try: + rr = Nav.NavPutFile(args) + good = 1 + except Nav.error, arg: + if arg[0] != -128: # userCancelledErr + raise Nav.error, arg + return None + if not rr.validRecord or not rr.selection: + return None + if issubclass(tpwanted, Carbon.File.FSRef): + raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave" + if issubclass(tpwanted, Carbon.File.FSSpec): + return tpwanted(rr.selection[0]) + if issubclass(tpwanted, (str, unicode)): + # This is gross, and probably incorrect too + vrefnum, dirid, name = rr.selection[0].as_tuple() + pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, '')) + pardir_fsr = Carbon.File.FSRef(fss) + pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8 + name_utf8 = unicode(name, 'macroman').encode('utf8') + fullpath = os.path.join(pardir_path, name_utf8) + if issubclass(tpwanted, unicode): + return unicode(fullpath, 'utf8') + return tpwanted(fullpath) + raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) + + def AskFolder(**args): + default_flags = 0x17 + args, tpwanted = _process_Nav_args(args, _ALLOWED_KEYS, default_flags) + try: + rr = Nav.NavChooseFolder(args) + good = 1 + except Nav.error, arg: + if arg[0] != -128: # userCancelledErr + raise Nav.error, arg + return None + if not rr.validRecord or not rr.selection: + return None + if issubclass(tpwanted, Carbon.File.FSRef): + return tpwanted(rr.selection_fsr[0]) + if issubclass(tpwanted, Carbon.File.FSSpec): + return tpwanted(rr.selection[0]) + if issubclass(tpwanted, str): + return tpwanted(rr.selection_fsr[0].FSRefMakePath()) + if issubclass(tpwanted, unicode): + return tpwanted(rr.selection_fsr[0].FSRefMakePath(), 'utf8') + raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) + def test(): import time, sys *************** *** 556,563 **** commandlist = (('start', 'Start something'), ('stop', 'Stop something')) argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0) for i in range(len(argv)): print 'arg[%d] = %s'%(i, `argv[i]`) - print 'Type return to continue - ', - sys.stdin.readline() ok = AskYesNoCancel("Do you want to proceed?") ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No") --- 701,707 ---- commandlist = (('start', 'Start something'), ('stop', 'Stop something')) argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0) + Message("Command line: %s"%' '.join(argv)) for i in range(len(argv)): print 'arg[%d] = %s'%(i, `argv[i]`) ok = AskYesNoCancel("Do you want to proceed?") ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No") *************** *** 569,572 **** --- 713,724 ---- else: Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2)) + else: + s = 'Anonymous' + rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=macfs.FSSpec) + Message("rv: %s"%rv) + rv = AskFileForSave(wanted=macfs.FSSpec, savedFileName="%s.txt"%s) + Message("rv.as_pathname: %s"%rv.as_pathname()) + rv = AskFolder() + Message("Folder name: %s"%rv) text = ( "Working Hard...", "Hardly Working..." , "So far, so good!", "Keep on truckin'" ) From jackjansen@users.sourceforge.net Fri Jan 17 16:14:37 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 17 Jan 2003 08:14:37 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules Nav.c,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv18740 Modified Files: Nav.c Log Message: For reasons unknown previewProc and filterProc were disabled. Enabled them. Index: Nav.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/Nav.c,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** Nav.c 23 Dec 2002 23:16:20 -0000 1.21 --- Nav.c 17 Jan 2003 16:14:31 -0000 1.22 *************** *** 203,211 **** *eventProcP = my_eventProcUPP; } else if( previewProcP && strcmp(keystr, "previewProc") == 0 ) { ! PyErr_SetString(ErrorObject, "No callbacks implemented yet"); ! return 0; } else if( filterProcP && strcmp(keystr, "filterProc") == 0 ) { ! PyErr_SetString(ErrorObject, "No callbacks implemented yet"); ! return 0; } else if( typeListP && strcmp(keystr, "typeList") == 0 ) { if ( !PyArg_Parse(value, "O&", ResObj_Convert, typeListP) ) --- 203,209 ---- *eventProcP = my_eventProcUPP; } else if( previewProcP && strcmp(keystr, "previewProc") == 0 ) { ! *previewProcP = my_previewProcUPP; } else if( filterProcP && strcmp(keystr, "filterProc") == 0 ) { ! *filterProcP = my_filterProcUPP; } else if( typeListP && strcmp(keystr, "typeList") == 0 ) { if ( !PyArg_Parse(value, "O&", ResObj_Convert, typeListP) ) From rhettinger@users.sourceforge.net Fri Jan 17 16:20:30 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 17 Jan 2003 08:20:30 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.108,1.109 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv19627 Modified Files: whatsnew23.tex Log Message: Correct typos in example code. Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.108 retrieving revision 1.109 diff -C2 -d -r1.108 -r1.109 *** whatsnew23.tex 13 Jan 2003 19:09:03 -0000 1.108 --- whatsnew23.tex 17 Jan 2003 16:20:23 -0000 1.109 *************** *** 895,899 **** Traceback (most recent call last): File "", line 1, in ? ! ValueError: attempt to assign list of size 3 to extended slice of size 2 \end{verbatim} --- 895,899 ---- Traceback (most recent call last): File "", line 1, in ? ! ValueError: attempt to assign sequence of size 3 to extended slice of size 2 \end{verbatim} *************** *** 1001,1005 **** Traceback (most recent call last): File "stdin", line 1, in ? ! KeyError: pop(): dictionary is empty >>> d {} --- 1001,1005 ---- Traceback (most recent call last): File "stdin", line 1, in ? ! KeyError: 'pop(): dictionary is empty' >>> d {} *************** *** 1683,1687 **** >>> now.ctime() # Only available on date, datetime 'Mon Dec 30 21:27:03 2002' ! >>> now.strftime('%Y %d %h') '2002 30 Dec' \end{verbatim} --- 1683,1687 ---- >>> now.ctime() # Only available on date, datetime 'Mon Dec 30 21:27:03 2002' ! >>> now.strftime('%Y %d %b') '2002 30 Dec' \end{verbatim} From rhettinger@users.sourceforge.net Fri Jan 17 17:23:25 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 17 Jan 2003 09:23:25 -0800 Subject: [Python-checkins] python/dist/src/Lib random.py,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5751 Modified Files: random.py Log Message: * Migrate sample distribution test from random.py to test_random.py. * Use Sets module to more clearly articulate a couple of tests. Index: random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** random.py 7 Jan 2003 10:25:55 -0000 1.45 --- random.py 17 Jan 2003 17:23:22 -0000 1.46 *************** *** 744,750 **** (avg, stddev, smallest, largest) - def _sample_generator(n, k): - # Return a fixed element from the sample. Validates random ordering. - return sample(xrange(n), k)[k//2] def _test(N=2000): --- 744,747 ---- *************** *** 765,770 **** _test_generator(N, 'gauss(0.0, 1.0)') _test_generator(N, 'betavariate(3.0, 3.0)') - _test_generator(N, '_sample_generator(50, 5)') # expected s.d.: 14.4 - _test_generator(N, '_sample_generator(50, 45)') # expected s.d.: 14.4 # Create one instance, seeded from current time, and export its methods --- 762,765 ---- From rhettinger@users.sourceforge.net Fri Jan 17 17:23:26 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 17 Jan 2003 09:23:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_random.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv5751/test Modified Files: test_random.py Log Message: * Migrate sample distribution test from random.py to test_random.py. * Use Sets module to more clearly articulate a couple of tests. Index: test_random.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_random.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_random.py 5 Jan 2003 09:20:06 -0000 1.6 --- test_random.py 17 Jan 2003 17:23:23 -0000 1.7 *************** *** 5,8 **** --- 5,9 ---- import time from math import log, exp, sqrt, pi + from sets import Set from test import test_support *************** *** 62,70 **** s = self.gen.sample(population, k) self.assertEqual(len(s), k) ! uniq = dict.fromkeys(s) self.assertEqual(len(uniq), k) ! self.failIf(None in uniq) self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0 def test_gauss(self): # Ensure that the seed() method initializes all the hidden state. In --- 63,89 ---- s = self.gen.sample(population, k) self.assertEqual(len(s), k) ! uniq = Set(s) self.assertEqual(len(uniq), k) ! self.failUnless(uniq <= Set(population)) self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0 + def test_sample_distribution(self): + # For the entire allowable range of 0 <= k <= N, validate that + # sample generates all possible permutations + n = 5 + pop = range(n) + trials = 10000 # large num prevents false negatives without slowing normal case + def factorial(n): + return n==0 and 1 or n * factorial(n-1) + for k in xrange(n): + expected = factorial(n) / factorial(n-k) + perms = {} + for i in xrange(trials): + perms[tuple(self.gen.sample(pop, k))] = None + if len(perms) == expected: + break + else: + self.fail() + def test_gauss(self): # Ensure that the seed() method initializes all the hidden state. In *************** *** 251,257 **** def test__all__(self): # tests validity but not completeness of the __all__ list ! defined = dict.fromkeys(dir(random)) ! for entry in random.__all__: ! self.failUnless(entry in defined) def test_main(): --- 270,274 ---- def test__all__(self): # tests validity but not completeness of the __all__ list ! self.failUnless(Set(random.__all__) <= Set(dir(random))) def test_main(): From jvr@users.sourceforge.net Fri Jan 17 20:02:10 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Fri, 17 Jan 2003 12:02:10 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bundlebuilder.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv21411 Modified Files: bundlebuilder.py Log Message: make sure src exists before creating a symlink Index: bundlebuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bundlebuilder.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** bundlebuilder.py 13 Jan 2003 23:30:04 -0000 1.3 --- bundlebuilder.py 17 Jan 2003 20:02:06 -0000 1.4 *************** *** 579,582 **** --- 579,584 ---- def symlink(src, dst, mkdirs=0): """Copy a file or a directory.""" + if not os.path.exists(src): + raise IOError, "No such file or directory: '%s'" % src if mkdirs: makedirs(os.path.dirname(dst)) From tim_one@users.sourceforge.net Fri Jan 17 20:08:59 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 17 Jan 2003 12:08:59 -0800 Subject: [Python-checkins] python/dist/src/Modules timemodule.c,2.132,2.133 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv24013/python/Modules Modified Files: timemodule.c Log Message: When time.localtime() is passed a tick count the platform C localtime() function can't handle, don't raise IOError -- that doesn't make sense. Raise ValueError instead. Bugfix candidate. Index: timemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v retrieving revision 2.132 retrieving revision 2.133 diff -C2 -d -r2.132 -r2.133 *** timemodule.c 16 Oct 2002 20:28:25 -0000 2.132 --- timemodule.c 17 Jan 2003 20:08:54 -0000 2.133 *************** *** 274,278 **** errno = EINVAL; #endif ! return PyErr_SetFromErrno(PyExc_IOError); } return tmtotuple(p); --- 274,278 ---- errno = EINVAL; #endif ! return PyErr_SetFromErrno(PyExc_ValueError); } return tmtotuple(p); From fdrake@users.sourceforge.net Fri Jan 17 21:25:08 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 17 Jan 2003 13:25:08 -0800 Subject: [Python-checkins] python/dist/src/Doc/tools mkhowto,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory sc8-pr-cvs1:/tmp/cvs-serv24186 Modified Files: mkhowto Log Message: Clean up some files that LaTeX2HTML drops in the HTML output directory sometimes. Index: mkhowto =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkhowto,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** mkhowto 30 Oct 2002 17:02:21 -0000 1.37 --- mkhowto 17 Jan 2003 21:25:04 -0000 1.38 *************** *** 444,447 **** --- 444,452 ---- finally: os.chdir(pwd) + # These files need to be cleaned up here since builddir there + # can be more than one, so we clean each of them. + if self.options.discard_temps: + for fn in ("images.tex", "images.log", "images.aux"): + safe_unlink(os.path.join(builddir, fn)) def build_text(self, tempdir=None): From tim_one@users.sourceforge.net Fri Jan 17 21:50:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 17 Jan 2003 13:50:41 -0800 Subject: [Python-checkins] python/dist/src/PCbuild python20.wse,1.115,1.116 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv2736/python/PCbuild Modified Files: python20.wse Log Message: CVS patch 669645: wininst.exe missing in Windows installer. Not anymore it ain't. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.115 retrieving revision 1.116 diff -C2 -d -r1.115 -r1.116 *** python20.wse 2 Jan 2003 17:09:19 -0000 1.115 --- python20.wse 17 Jan 2003 21:50:32 -0000 1.116 *************** *** 1944,1947 **** --- 1944,1952 ---- end item: Install File + Source=..\lib\distutils\command\wininst.exe + Destination=%MAINDIR%\Lib\distutils\command\wininst.exe + Flags=0000000000000010 + end + item: Install File Source=..\lib\distutils\command\command_template Destination=%MAINDIR%\Lib\distutils\command\command_template From fdrake@users.sourceforge.net Fri Jan 17 22:50:20 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 17 Jan 2003 14:50:20 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv27442 Modified Files: whatsnew23.tex Log Message: Various markup changes. Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.109 retrieving revision 1.110 diff -C2 -d -r1.109 -r1.110 *** whatsnew23.tex 17 Jan 2003 16:20:23 -0000 1.109 --- whatsnew23.tex 17 Jan 2003 22:50:10 -0000 1.110 *************** *** 4,8 **** \title{What's New in Python 2.3} \release{0.08} ! \author{A.M. Kuchling} \authoraddress{\email{amk@amk.ca}} --- 4,8 ---- \title{What's New in Python 2.3} \release{0.08} ! \author{A.M.\ Kuchling} \authoraddress{\email{amk@amk.ca}} *************** *** 174,182 **** \keyword{yield} statement. (For complicated reasons, the \keyword{yield} statement isn't allowed inside the \keyword{try} block ! of a \code{try...finally} statement; read \pep{255} for a full explanation of the interaction between \keyword{yield} and exceptions.) ! Here's a sample usage of the \function{generate_ints} generator: \begin{verbatim} --- 174,182 ---- \keyword{yield} statement. (For complicated reasons, the \keyword{yield} statement isn't allowed inside the \keyword{try} block ! of a \keyword{try}...\keyword{finally} statement; read \pep{255} for a full explanation of the interaction between \keyword{yield} and exceptions.) ! Here's a sample usage of the \function{generate_ints()} generator: \begin{verbatim} *************** *** 473,477 **** recent traceback. Any of the other functions will also record the traceback if you specify a true value for the keyword argument ! \code{exc_info}. \begin{verbatim} --- 473,477 ---- recent traceback. Any of the other functions will also record the traceback if you specify a true value for the keyword argument ! \var{exc_info}. \begin{verbatim} *************** *** 511,515 **** logged to \samp{server.auth} is also seen by \samp{server} and \samp{root}, but a handler can prevent this by setting its ! \member{propagate} attribute to \code{False}. There are more classes provided by the \module{logging} package that --- 511,515 ---- logged to \samp{server.auth} is also seen by \samp{server} and \samp{root}, but a handler can prevent this by setting its ! \member{propagate} attribute to \constant{False}. There are more classes provided by the \module{logging} package that *************** *** 684,691 **** An entry in \code{sys.path} can now be the filename of a ZIP archive. The ZIP archive can contain any kind of files, but only files named ! \code{*.py}, \code{*.pyc}, or \code{*.pyo} can be imported. If an ! archive only contains \code{*.py} files, Python will not attempt to ! modify the archive by adding the corresponding \code{*.pyc} file, meaning ! that if a ZIP archive doesn't contain \code{*.pyc} files, importing may be rather slow. --- 684,691 ---- An entry in \code{sys.path} can now be the filename of a ZIP archive. The ZIP archive can contain any kind of files, but only files named ! \file{*.py}, \file{*.pyc}, or \file{*.pyo} can be imported. If an ! archive only contains \file{*.py} files, Python will not attempt to ! modify the archive by adding the corresponding \file{*.pyc} file, meaning ! that if a ZIP archive doesn't contain \file{*.pyc} files, importing may be rather slow. *************** *** 768,779 **** \begin{itemize} \item \code{sys.path_hooks} is a list of callable objects; most ! often they'll be classes. Each callable takes a string containing ! a path and either returns an importer object that will handle imports ! from this path or raises an \exception{ImportError} exception if it ! can't handle this path. \item \code{sys.path_importer_cache} caches importer objects for ! each path, so \code{sys.path_hooks} will only need to be traversed ! once for each path. \item \code{sys.meta_path} is a list of importer objects that will --- 768,779 ---- \begin{itemize} \item \code{sys.path_hooks} is a list of callable objects; most ! often they'll be classes. Each callable takes a string containing a ! path and either returns an importer object that will handle imports ! from this path or raises an \exception{ImportError} exception if it ! can't handle this path. \item \code{sys.path_importer_cache} caches importer objects for ! each path, so \code{sys.path_hooks} will only need to be traversed ! once for each path. \item \code{sys.meta_path} is a list of importer objects that will *************** *** 928,933 **** To simplify implementing sequences that support extended slicing, slice objects now have a method \method{indices(\var{length})} which, ! given the length of a sequence, returns a \code{(start, stop, step)} ! tuple that can be passed directly to \function{range()}. \method{indices()} handles omitted and out-of-bounds indices in a manner consistent with regular slices (and this innocuous phrase hides --- 928,934 ---- To simplify implementing sequences that support extended slicing, slice objects now have a method \method{indices(\var{length})} which, ! given the length of a sequence, returns a \code{(\var{start}, ! \var{stop}, \var{step})} tuple that can be passed directly to ! \function{range()}. \method{indices()} handles omitted and out-of-bounds indices in a manner consistent with regular slices (and this innocuous phrase hides *************** *** 1119,1123 **** \begin{itemize} ! \item The \code{in} operator now works differently for strings. Previously, when evaluating \code{\var{X} in \var{Y}} where \var{X} and \var{Y} are strings, \var{X} could only be a single character. --- 1120,1124 ---- \begin{itemize} ! \item The \keyword{in} operator now works differently for strings. Previously, when evaluating \code{\var{X} in \var{Y}} where \var{X} and \var{Y} are strings, \var{X} could only be a single character. *************** *** 1406,1410 **** \item The \function{sample(\var{population}, \var{k})} function was added to the \module{random} module. \var{population} is a sequence ! or \code{xrange} object containing the elements of a population, and \function{sample()} chooses \var{k} elements from the population without replacing chosen elements. \var{k} can be any value up to \code{len(\var{population})}. --- 1407,1412 ---- \item The \function{sample(\var{population}, \var{k})} function was added to the \module{random} module. \var{population} is a sequence ! or \class{xrange} object containing the elements of a population, and ! \function{sample()} chooses \var{k} elements from the population without replacing chosen elements. \var{k} can be any value up to \code{len(\var{population})}. *************** *** 1934,1938 **** the argument checking can then be removed. If compatibility with pre-2.2 versions of Python is important, the code could use ! \code{PyArg_ParseTuple(args, "")} instead, but this will be slower than using \constant{METH_NOARGS}. --- 1936,1940 ---- the argument checking can then be removed. If compatibility with pre-2.2 versions of Python is important, the code could use ! \code{PyArg_ParseTuple(\var{args}, "")} instead, but this will be slower than using \constant{METH_NOARGS}. From fdrake@users.sourceforge.net Fri Jan 17 22:47:35 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 17 Jan 2003 14:47:35 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsimplexmlrpc.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv26415 Modified Files: libsimplexmlrpc.tex Log Message: Fix a couple of markup errors. Index: libsimplexmlrpc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsimplexmlrpc.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** libsimplexmlrpc.tex 15 Jan 2003 11:37:23 -0000 1.4 --- libsimplexmlrpc.tex 17 Jan 2003 22:47:33 -0000 1.5 *************** *** 103,107 **** \begin{methoddesc}{register_function}{function\optional{, name}} Register a function that can respond to XML-RPC requests. If ! \var{name] is given, it will be the method name associated with function, otherwise \var{function.__name__} will be used. \var{name} can be either a normal or Unicode string, and may contain --- 103,107 ---- \begin{methoddesc}{register_function}{function\optional{, name}} Register a function that can respond to XML-RPC requests. If ! \var{name} is given, it will be the method name associated with function, otherwise \var{function.__name__} will be used. \var{name} can be either a normal or Unicode string, and may contain *************** *** 116,120 **** requested method name and the parameters from the request; the return value is returned to the client as the result. ! If instance does not have a \methode{_dispatch()} method, it is searched for an attribute matching the name of the requested method; if the requested method name contains periods, each --- 116,120 ---- requested method name and the parameters from the request; the return value is returned to the client as the result. ! If 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 *************** *** 155,157 **** handler.register_instance(MyFuncs()) handler.handle_request() ! \end{verbatim} \ No newline at end of file --- 155,157 ---- handler.register_instance(MyFuncs()) handler.handle_request() ! \end{verbatim} From jackjansen@users.sourceforge.net Fri Jan 17 23:11:20 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 17 Jan 2003 15:11:20 -0800 Subject: [Python-checkins] python/dist/src/Python mactoolboxglue.c,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv2704/Python Modified Files: mactoolboxglue.c Log Message: It turns out that some calls return AEDesc records that are "borrowed", the AEDesc data shouldn't be disposed when the Python object is. Added a C call AEDesc_NewBorrowed() to create these objects and a Python method old=AEDesc.AutoDispose(onoff) to change auto-dispose state. Index: mactoolboxglue.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/mactoolboxglue.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** mactoolboxglue.c 23 Dec 2002 21:03:36 -0000 1.15 --- mactoolboxglue.c 17 Jan 2003 23:11:17 -0000 1.16 *************** *** 535,538 **** --- 535,539 ---- GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */ + GLUE_NEW(AppleEvent *, AEDesc_NewBorrowed, "Carbon.AE") GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE") From jackjansen@users.sourceforge.net Fri Jan 17 23:11:20 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 17 Jan 2003 15:11:20 -0800 Subject: [Python-checkins] python/dist/src/Include pymactoolbox.h,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv2704/Include Modified Files: pymactoolbox.h Log Message: It turns out that some calls return AEDesc records that are "borrowed", the AEDesc data shouldn't be disposed when the Python object is. Added a C call AEDesc_NewBorrowed() to create these objects and a Python method old=AEDesc.AutoDispose(onoff) to change auto-dispose state. Index: pymactoolbox.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pymactoolbox.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pymactoolbox.h 10 Sep 2002 12:32:46 -0000 1.6 --- pymactoolbox.h 17 Jan 2003 23:11:15 -0000 1.7 *************** *** 107,110 **** --- 107,111 ---- /* AE exports */ extern PyObject *AEDesc_New(AppleEvent *); /* XXXX Why passed by address?? */ + extern PyObject *AEDesc_NewBorrowed(AppleEvent *); extern int AEDesc_Convert(PyObject *, AppleEvent *); From jackjansen@users.sourceforge.net Fri Jan 17 23:11:22 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 17 Jan 2003 15:11:22 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/ae _AEmodule.c,1.18,1.19 aesupport.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ae In directory sc8-pr-cvs1:/tmp/cvs-serv2704/Mac/Modules/ae Modified Files: _AEmodule.c aesupport.py Log Message: It turns out that some calls return AEDesc records that are "borrowed", the AEDesc data shouldn't be disposed when the Python object is. Added a C call AEDesc_NewBorrowed() to create these objects and a Python method old=AEDesc.AutoDispose(onoff) to change auto-dispose state. Index: _AEmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/_AEmodule.c,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** _AEmodule.c 23 Dec 2002 23:16:20 -0000 1.18 --- _AEmodule.c 17 Jan 2003 23:11:17 -0000 1.19 *************** *** 36,39 **** --- 36,40 ---- #define AEDesc_New _AEDesc_New + #define AEDesc_NewBorrowed _AEDesc_NewBorrowed #define AEDesc_Convert _AEDesc_Convert #endif *************** *** 71,74 **** --- 72,76 ---- PyObject_HEAD AEDesc ob_itself; + int ob_owned; } AEDescObject; *************** *** 79,82 **** --- 81,85 ---- if (it == NULL) return NULL; it->ob_itself = *itself; + it->ob_owned = 1; return (PyObject *)it; } *************** *** 94,98 **** static void AEDesc_dealloc(AEDescObject *self) { ! AEDisposeDesc(&self->ob_itself); self->ob_type->tp_free((PyObject *)self); } --- 97,101 ---- static void AEDesc_dealloc(AEDescObject *self) { ! if (self->ob_owned) AEDisposeDesc(&self->ob_itself); self->ob_type->tp_free((PyObject *)self); } *************** *** 760,763 **** --- 763,780 ---- } + static PyObject *AEDesc_AutoDispose(AEDescObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + + int onoff, old; + if (!PyArg_ParseTuple(_args, "i", &onoff)) + return NULL; + old = _self->ob_owned; + _self->ob_owned = onoff; + _res = Py_BuildValue("i", old); + return _res; + + } + static PyMethodDef AEDesc_methods[] = { {"AECoerceDesc", (PyCFunction)AEDesc_AECoerceDesc, 1, *************** *** 817,820 **** --- 834,839 ---- {"AEResolve", (PyCFunction)AEDesc_AEResolve, 1, PyDoc_STR("(short callbackFlags) -> (AEDesc theToken)")}, + {"AutoDispose", (PyCFunction)AEDesc_AutoDispose, 1, + PyDoc_STR("(int)->int. Automatically AEDisposeDesc the object on Python object cleanup")}, {NULL, NULL, 0} }; *************** *** 1414,1417 **** --- 1433,1447 ---- } + PyObject *AEDesc_NewBorrowed(AEDesc *itself) + { + PyObject *it; + + it = AEDesc_New(itself); + if (it) + ((AEDescObject *)it)->ob_owned = 0; + return (PyObject *)it; + } + + void init_AE(void) *************** *** 1425,1428 **** --- 1455,1459 ---- upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler); PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New); + PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert); Index: aesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/aesupport.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** aesupport.py 13 Dec 2002 15:01:32 -0000 1.29 --- aesupport.py 17 Jan 2003 23:11:17 -0000 1.30 *************** *** 98,101 **** --- 98,102 ---- #define AEDesc_New _AEDesc_New + #define AEDesc_NewBorrowed _AEDesc_NewBorrowed #define AEDesc_Convert _AEDesc_Convert #endif *************** *** 156,159 **** --- 157,171 ---- return noErr; } + + PyObject *AEDesc_NewBorrowed(AEDesc *itself) + { + PyObject *it; + + it = AEDesc_New(itself); + if (it) + ((AEDescObject *)it)->ob_owned = 0; + return (PyObject *)it; + } + """ *************** *** 162,165 **** --- 174,178 ---- upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler); PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New); + PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert); """ *************** *** 198,203 **** self.argref = "*" ! def outputFreeIt(self, name): ! Output("AEDisposeDesc(&%s);", name) aedescobject = AEDescDefinition('AEDesc') --- 211,224 ---- self.argref = "*" ! def outputStructMembers(self): ! GlobalObjectDefinition.outputStructMembers(self) ! Output("int ob_owned;") ! ! def outputInitStructMembers(self): ! GlobalObjectDefinition.outputInitStructMembers(self) ! Output("it->ob_owned = 1;") ! ! def outputCleanupStructMembers(self): ! Output("if (self->ob_owned) AEDisposeDesc(&self->ob_itself);") aedescobject = AEDescDefinition('AEDesc') *************** *** 209,212 **** --- 230,247 ---- execfile('aegen.py') ##execfile('aedatamodelgen.py') + + # Manual generator + AutoDispose_body = """ + int onoff, old; + if (!PyArg_ParseTuple(_args, "i", &onoff)) + return NULL; + old = _self->ob_owned; + _self->ob_owned = onoff; + _res = Py_BuildValue("i", old); + return _res; + """ + f = ManualGenerator("AutoDispose", AutoDispose_body) + f.docstring = lambda: "(int)->int. Automatically AEDisposeDesc the object on Python object cleanup" + aedescmethods.append(f) for f in functions: module.add(f) From jackjansen@users.sourceforge.net Fri Jan 17 23:13:05 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 17 Jan 2003 15:13:05 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac EasyDialogs.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv4402/Lib/plat-mac Modified Files: EasyDialogs.py Log Message: Fixed the first two bugs in the new file dialogs (found by Just): - AskFileForSave didn't work for string return values - filterProc didn't work. Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/EasyDialogs.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** EasyDialogs.py 17 Jan 2003 16:04:39 -0000 1.2 --- EasyDialogs.py 17 Jan 2003 23:13:02 -0000 1.3 *************** *** 31,34 **** --- 31,35 ---- import macfs import macresource + import os _initialized = 0 *************** *** 661,665 **** vrefnum, dirid, name = rr.selection[0].as_tuple() pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, '')) ! pardir_fsr = Carbon.File.FSRef(fss) pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8 name_utf8 = unicode(name, 'macroman').encode('utf8') --- 662,666 ---- vrefnum, dirid, name = rr.selection[0].as_tuple() pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, '')) ! pardir_fsr = Carbon.File.FSRef(pardir_fss) pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8 name_utf8 = unicode(name, 'macroman').encode('utf8') From jackjansen@users.sourceforge.net Fri Jan 17 23:13:06 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 17 Jan 2003 15:13:06 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules Nav.c,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv4402/Mac/Modules Modified Files: Nav.c Log Message: Fixed the first two bugs in the new file dialogs (found by Just): - AskFileForSave didn't work for string return values - filterProc didn't work. Index: Nav.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/Nav.c,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** Nav.c 17 Jan 2003 16:14:31 -0000 1.22 --- Nav.c 17 Jan 2003 23:13:03 -0000 1.23 *************** *** 57,61 **** if (!dict) return; if ( (pyfunc = PyDict_GetItemString(dict, "eventProc")) == NULL ) { ! PyErr_Clear(); return; } --- 57,61 ---- if (!dict) return; if ( (pyfunc = PyDict_GetItemString(dict, "eventProc")) == NULL ) { ! PyErr_Print(); return; } *************** *** 75,80 **** Py_DECREF(rv); else { ! fprintf(stderr, "Nav: exception in eventProc callback\n"); ! PyErr_Clear(); } } --- 75,80 ---- Py_DECREF(rv); else { ! PySys_WriteStderr("Nav: exception in eventProc callback\n"); ! PyErr_Print(); } } *************** *** 91,95 **** if (!dict) return false; if ( (pyfunc = PyDict_GetItemString(dict, "previewProc")) == NULL ) { ! PyErr_Clear(); return false; } --- 91,95 ---- if (!dict) return false; if ( (pyfunc = PyDict_GetItemString(dict, "previewProc")) == NULL ) { ! PyErr_Print(); return false; } *************** *** 99,104 **** Py_DECREF(rv); } else { ! fprintf(stderr, "Nav: exception in previewProc callback\n"); ! PyErr_Clear(); } return c_rv; --- 99,104 ---- Py_DECREF(rv); } else { ! PySys_WriteStderr("Nav: exception in previewProc callback\n"); ! PyErr_Print(); } return c_rv; *************** *** 114,131 **** PyObject *rv; Boolean c_rv = false; if (!dict) return false; if ( (pyfunc = PyDict_GetItemString(dict, "filterProc")) == NULL ) { ! PyErr_Clear(); return false; } rv = PyObject_CallFunction(pyfunc, "O&s#h", ! AEDesc_New, theItem, info, sizeof(NavFileOrFolderInfo), (short)filterMode); if ( rv ) { c_rv = PyObject_IsTrue(rv); Py_DECREF(rv); } else { ! fprintf(stderr, "Nav: exception in filterProc callback\n"); ! PyErr_Clear(); } return c_rv; --- 114,132 ---- PyObject *rv; Boolean c_rv = false; + PyObject theItemCopy; if (!dict) return false; if ( (pyfunc = PyDict_GetItemString(dict, "filterProc")) == NULL ) { ! PyErr_Print(); return false; } rv = PyObject_CallFunction(pyfunc, "O&s#h", ! AEDesc_NewBorrowed, theItem, info, sizeof(NavFileOrFolderInfo), (short)filterMode); if ( rv ) { c_rv = PyObject_IsTrue(rv); Py_DECREF(rv); } else { ! PySys_WriteStderr("Nav: exception in filterProc callback\n"); ! PyErr_Print(); } return c_rv; From goodger@users.sourceforge.net Sat Jan 18 00:59:08 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Fri, 17 Jan 2003 16:59:08 -0800 Subject: [Python-checkins] python/nondist/peps pep-0240.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv11194/python/nondist/peps Modified Files: pep-0240.txt Log Message: Updates from Christopher Craig. Index: pep-0240.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0240.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0240.txt 20 Sep 2002 14:10:52 -0000 1.6 --- pep-0240.txt 18 Jan 2003 00:59:04 -0000 1.7 *************** *** 42,49 **** mentioned above. The following migration is suggested: ! 1. "from __future__ import rational_literals" will cause all such ! literals to be treated as rational numbers. ! 2. Python 2.2 will have a warning, turned off by default, about such literals in the absence of a __future__ statement. The warning message will contain information about the __future__ --- 42,50 ---- mentioned above. The following migration is suggested: ! 1. The next Python after approval will allow ! "from __future__ import rational_literals" ! to cause all such literals to be treated as rational numbers. ! 2. Python 3.0 will have a warning, turned on by default, about such literals in the absence of a __future__ statement. The warning message will contain information about the __future__ *************** *** 51,55 **** they should be suffixed with "e0". ! 3. Python 2.3 will have the warning turned on by default. This warning will stay in place for 24 months, at which time the literals will be rationals and the warning will be removed. --- 52,56 ---- they should be suffixed with "e0". ! 3. Python 3.1 will have the warning turned off by default. This warning will stay in place for 24 months, at which time the literals will be rationals and the warning will be removed. *************** *** 61,64 **** --- 62,71 ---- (Relax, I'm not taking floats away, I'm just adding two more characters. 1e0 will still be a float) + + Rationals must present themselves as a decimal float or they will be + horrible for users expecting decimals (i.e. str(.5) should return '.5' and + not '1/2'). This means that many rationals must be truncated at some + point, which gives us a new loss of precision. + From tim_one@users.sourceforge.net Sat Jan 18 03:53:51 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 17 Jan 2003 19:53:51 -0800 Subject: [Python-checkins] python/dist/src/Lib _strptime.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14518/python/Lib Modified Files: _strptime.py Log Message: SF patch 670012: Compatibility changes for _strptime.py. Patch from Brett Cannon: First, the 'y' directive now handles [00, 68] as a suffix for the 21st century while [69, 99] is treated as the suffix for the 20th century (this is for Open Group compatibility). strptime now returns default values that make it a valid date ... the ability to pass in a regex object to use instead of a format string (and the inverse ability to have strptime return a regex object) has been removed. This is in preparation for a future patch that will add some caching internally to get a speed boost. Index: _strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/_strptime.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** _strptime.py 15 Jan 2003 22:59:39 -0000 1.9 --- _strptime.py 18 Jan 2003 03:53:49 -0000 1.10 *************** *** 400,498 **** def strptime(data_string, format="%a %b %d %H:%M:%S %Y"): ! """Return a time struct based on the input data and the format string. ! ! The format argument may either be a regular expression object compiled by ! strptime(), or a format string. If False is passed in for data_string ! then the re object calculated for format will be returned. The re object ! must be used with the same locale as was used to compile the re object. ! """ locale_time = LocaleTime() ! if isinstance(format, RegexpType): ! if format.pattern.find(locale_time.lang) == -1: ! raise TypeError("re object not created with same language as " ! "LocaleTime instance") ! else: ! compiled_re = format ! else: ! compiled_re = TimeRE(locale_time).compile(format) ! if data_string is False: ! return compiled_re ! else: ! found = compiled_re.match(data_string) ! if not found: ! raise ValueError("time data did not match format") ! year = month = day = hour = minute = second = weekday = julian = tz =-1 ! found_dict = found.groupdict() ! for group_key in found_dict.iterkeys(): ! if group_key == 'y': ! year = int("%s%s" % ! (time.strftime("%Y")[:-2], found_dict['y'])) ! elif group_key == 'Y': ! year = int(found_dict['Y']) ! elif group_key == 'm': ! month = int(found_dict['m']) ! elif group_key == 'B': ! month = _insensitiveindex(locale_time.f_month, found_dict['B']) ! elif group_key == 'b': ! month = _insensitiveindex(locale_time.a_month, found_dict['b']) ! elif group_key == 'd': ! day = int(found_dict['d']) ! elif group_key is 'H': ! hour = int(found_dict['H']) ! elif group_key == 'I': ! hour = int(found_dict['I']) ! ampm = found_dict.get('p', '').lower() ! # If there was no AM/PM indicator, we'll treat this like AM ! if ampm in ('', locale_time.am_pm[0].lower()): ! # We're in AM so the hour is correct unless we're ! # looking at 12 midnight. ! # 12 midnight == 12 AM == hour 0 ! if hour == 12: ! hour = 0 ! elif ampm == locale_time.am_pm[1].lower(): ! # We're in PM so we need to add 12 to the hour unless ! # we're looking at 12 noon. ! # 12 noon == 12 PM == hour 12 ! if hour != 12: ! hour += 12 ! elif group_key == 'M': ! minute = int(found_dict['M']) ! elif group_key == 'S': ! second = int(found_dict['S']) ! elif group_key == 'A': ! weekday = _insensitiveindex(locale_time.f_weekday, ! found_dict['A']) ! elif group_key == 'a': ! weekday = _insensitiveindex(locale_time.a_weekday, ! found_dict['a']) ! elif group_key == 'w': ! weekday = int(found_dict['w']) ! if weekday == 0: ! weekday = 6 ! else: ! weekday -= 1 ! elif group_key == 'j': ! julian = int(found_dict['j']) ! elif group_key == 'Z': ! found_zone = found_dict['Z'].lower() ! if locale_time.timezone[0] == locale_time.timezone[1]: ! pass #Deals with bad locale setup where timezone info is ! # the same; first found on FreeBSD 4.4. ! elif locale_time.timezone[0].lower() == found_zone: ! tz = 0 ! elif locale_time.timezone[1].lower() == found_zone: ! tz = 1 ! elif locale_time.timezone[2].lower() == found_zone: ! tz = 0 ! #XXX : If calculating fxns are never exposed to the general ! # populous then just inline calculations. ! if julian == -1 and year != -1 and month != -1 and day != -1: julian = julianday(year, month, day) ! if (month == -1 or day == -1) and julian != -1 and year != -1: year, month, day = gregorian(julian, year) ! if weekday == -1 and year != -1 and month != -1 and day != -1: weekday = dayofweek(year, month, day) ! return time.struct_time( ! (year,month,day,hour,minute,second,weekday, julian,tz)) def _insensitiveindex(lst, findme): --- 400,496 ---- def strptime(data_string, format="%a %b %d %H:%M:%S %Y"): ! """Return a time struct based on the input data and the format string.""" locale_time = LocaleTime() ! compiled_re = TimeRE(locale_time).compile(format) ! found = compiled_re.match(data_string) ! if not found: ! raise ValueError("time data did not match format") ! year = 1900 ! month = day = 1 ! hour = minute = second = 0 ! tz = -1 ! # Defaulted to -1 so as to signal using functions to calc values ! weekday = julian = -1 ! found_dict = found.groupdict() ! for group_key in found_dict.iterkeys(): ! if group_key == 'y': ! year = int(found_dict['y']) ! # Open Group specification for strptime() states that a %y ! #value in the range of [00, 68] is in the century 2000, while ! #[69,99] is in the century 1900 ! if year <= 68: ! year += 2000 ! else: ! year += 1900 ! elif group_key == 'Y': ! year = int(found_dict['Y']) ! elif group_key == 'm': ! month = int(found_dict['m']) ! elif group_key == 'B': ! month = _insensitiveindex(locale_time.f_month, found_dict['B']) ! elif group_key == 'b': ! month = _insensitiveindex(locale_time.a_month, found_dict['b']) ! elif group_key == 'd': ! day = int(found_dict['d']) ! elif group_key is 'H': ! hour = int(found_dict['H']) ! elif group_key == 'I': ! hour = int(found_dict['I']) ! ampm = found_dict.get('p', '').lower() ! # If there was no AM/PM indicator, we'll treat this like AM ! if ampm in ('', locale_time.am_pm[0].lower()): ! # We're in AM so the hour is correct unless we're ! # looking at 12 midnight. ! # 12 midnight == 12 AM == hour 0 ! if hour == 12: ! hour = 0 ! elif ampm == locale_time.am_pm[1].lower(): ! # We're in PM so we need to add 12 to the hour unless ! # we're looking at 12 noon. ! # 12 noon == 12 PM == hour 12 ! if hour != 12: ! hour += 12 ! elif group_key == 'M': ! minute = int(found_dict['M']) ! elif group_key == 'S': ! second = int(found_dict['S']) ! elif group_key == 'A': ! weekday = _insensitiveindex(locale_time.f_weekday, ! found_dict['A']) ! elif group_key == 'a': ! weekday = _insensitiveindex(locale_time.a_weekday, ! found_dict['a']) ! elif group_key == 'w': ! weekday = int(found_dict['w']) ! if weekday == 0: ! weekday = 6 ! else: ! weekday -= 1 ! elif group_key == 'j': ! julian = int(found_dict['j']) ! elif group_key == 'Z': ! found_zone = found_dict['Z'].lower() ! if locale_time.timezone[0] == locale_time.timezone[1]: ! pass #Deals with bad locale setup where timezone info is ! # the same; first found on FreeBSD 4.4. ! elif locale_time.timezone[0].lower() == found_zone: ! tz = 0 ! elif locale_time.timezone[1].lower() == found_zone: ! tz = 1 ! elif locale_time.timezone[2].lower() == found_zone: ! tz = -1 ! #XXX : If calculating fxns are never exposed to the general ! #populous then just inline calculations. Also might be able to use ! #``datetime`` and the methods it provides. ! if julian == -1: julian = julianday(year, month, day) ! else: # Assuming that if they bothered to include Julian day it will ! #be accurate year, month, day = gregorian(julian, year) ! if weekday == -1: weekday = dayofweek(year, month, day) ! return time.struct_time((year, month, day, ! hour, minute, second, ! weekday, julian, tz)) def _insensitiveindex(lst, findme): From tim_one@users.sourceforge.net Sat Jan 18 03:53:51 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 17 Jan 2003 19:53:51 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_strptime.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14518/python/Lib/test Modified Files: test_strptime.py Log Message: SF patch 670012: Compatibility changes for _strptime.py. Patch from Brett Cannon: First, the 'y' directive now handles [00, 68] as a suffix for the 21st century while [69, 99] is treated as the suffix for the 20th century (this is for Open Group compatibility). strptime now returns default values that make it a valid date ... the ability to pass in a regex object to use instead of a format string (and the inverse ability to have strptime return a regex object) has been removed. This is in preparation for a future patch that will add some caching internally to get a speed boost. Index: test_strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_strptime.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_strptime.py 26 Dec 2002 16:19:52 -0000 1.8 --- test_strptime.py 18 Jan 2003 03:53:49 -0000 1.9 *************** *** 125,128 **** --- 125,136 ---- self.assertRaises(TypeError, _strptime.LocaleTime, timezone=range(3)) + def test_unknowntimezone(self): + # Handle timezone set to ('','') properly. + # Fixes bug #661354 + locale_time = _strptime.LocaleTime(timezone=('','')) + self.failUnless("%Z" not in locale_time.LC_date, + "when timezone == ('',''), string.replace('','%Z') is " + "occuring") + class TimeRETests(unittest.TestCase): """Tests for TimeRE.""" *************** *** 181,190 **** for directive in ('a','A','b','B','c','d','H','I','j','m','M','p','S', 'U','w','W','x','X','y','Y','Z','%'): ! compiled = self.time_re.compile("%%%s"% directive) ! found = compiled.match(time.strftime("%%%s" % directive)) self.failUnless(found, "Matching failed on '%s' using '%s' regex" % ! (time.strftime("%%%s" % directive), compiled.pattern)) class StrptimeTests(unittest.TestCase): """Tests for _strptime.strptime.""" --- 189,205 ---- for directive in ('a','A','b','B','c','d','H','I','j','m','M','p','S', 'U','w','W','x','X','y','Y','Z','%'): ! compiled = self.time_re.compile("%" + directive) ! found = compiled.match(time.strftime("%" + directive)) self.failUnless(found, "Matching failed on '%s' using '%s' regex" % ! (time.strftime("%" + directive), compiled.pattern)) + def test_blankpattern(self): + # Make sure when tuple or something has no values no regex is generated. + # Fixes bug #661354 + test_locale = _strptime.LocaleTime(timezone=('','')) + self.failUnless(_strptime.TimeRE(test_locale).pattern("%Z") == '', + "with timezone == ('',''), TimeRE().pattern('%Z') != ''") + class StrptimeTests(unittest.TestCase): """Tests for _strptime.strptime.""" *************** *** 199,217 **** format="%A") - def test_returning_RE(self): - # Make sure that an re can be returned - strp_output = _strptime.strptime(False, "%Y") - self.failUnless(isinstance(strp_output, type(re.compile(''))), - "re object not returned correctly") - self.failUnless(_strptime.strptime("1999", strp_output), - "Use of re object failed") - bad_locale_time = _strptime.LocaleTime(lang="gibberish") - self.assertRaises(TypeError, _strptime.strptime, data_string='1999', - format=strp_output, locale_time=bad_locale_time) - def helper(self, directive, position): """Helper fxn in testing.""" ! strf_output = time.strftime("%%%s" % directive, self.time_tuple) ! strp_output = _strptime.strptime(strf_output, "%%%s" % directive) self.failUnless(strp_output[position] == self.time_tuple[position], "testing of '%s' directive failed; '%s' -> %s != %s" % --- 214,221 ---- format="%A") def helper(self, directive, position): """Helper fxn in testing.""" ! strf_output = time.strftime("%" + directive, self.time_tuple) ! strp_output = _strptime.strptime(strf_output, "%" + directive) self.failUnless(strp_output[position] == self.time_tuple[position], "testing of '%s' directive failed; '%s' -> %s != %s" % *************** *** 223,226 **** --- 227,238 ---- for directive in ('y', 'Y'): self.helper(directive, 0) + # Must also make sure %y values are correct for bounds set by Open Group + for century, bounds in ((1900, ('69', '99')), (2000, ('00', '68'))): + for bound in bounds: + strp_output = _strptime.strptime(bound, '%y') + expected_result = century + int(bound) + self.failUnless(strp_output[0] == expected_result, + "'y' test failed; passed in '%s' " + "and returned '%s'" % (bound, strp_output[0])) def test_month(self): *************** *** 263,267 **** # When gmtime() is used with %Z, entire result of strftime() is empty. # Check for equal timezone names deals with bad locale info when this ! # occurs; first found in FreeBSD 4.4 -current time_tuple = time.localtime() strf_output = time.strftime("%Z") #UTC does not have a timezone --- 275,279 ---- # When gmtime() is used with %Z, entire result of strftime() is empty. # Check for equal timezone names deals with bad locale info when this ! # occurs; first found in FreeBSD 4.4. time_tuple = time.localtime() strf_output = time.strftime("%Z") #UTC does not have a timezone *************** *** 275,279 **** self.failUnless(strp_output[8] == -1, "LocaleTime().timezone has duplicate values but " ! "timzone value not set to -1") def test_date_time(self): --- 287,291 ---- self.failUnless(strp_output[8] == -1, "LocaleTime().timezone has duplicate values but " ! "timzone value not set to 0") def test_date_time(self): *************** *** 310,313 **** --- 322,333 ---- "strptime does not handle capword names properly") + def test_defaults(self): + # Default return value should be (1900, 1, 1, 0, 0, 0, 0, 1, 0) + defaults = (1900, 1, 1, 0, 0, 0, 0, 1, -1) + strp_output = _strptime.strptime('1', '%m') + self.failUnless(strp_output == defaults, + "Default values for strptime() are incorrect;" + " %s != %s" % (strp_output, defaults)) + class FxnTests(unittest.TestCase): """Test functions that fill in info by validating result and are triggered *************** *** 326,337 **** (result, self.time_tuple[7])) - def test_julianday_trigger(self): - # Make sure julianday is called - strf_output = time.strftime("%Y-%m-%d", self.time_tuple) - strp_output = _strptime.strptime(strf_output, "%Y-%m-%d") - self.failUnless(strp_output[7] == self.time_tuple[7], - "strptime did not trigger julianday(); %s != %s" % - (strp_output[7], self.time_tuple[7])) - def test_gregorian_result(self): # Test gregorian --- 346,349 ---- *************** *** 341,355 **** "gregorian() failed; %s != %s" % (result, comparison)) - def test_gregorian_trigger(self): - # Test that gregorian() is triggered - strf_output = time.strftime("%j %Y", self.time_tuple) - strp_output = _strptime.strptime(strf_output, "%j %Y") - self.failUnless(strp_output[1] == self.time_tuple[1] and - strp_output[2] == self.time_tuple[2], - "gregorian() not triggered; month -- %s != %s, " - "day -- %s != %s" % - (strp_output[1], self.time_tuple[1], strp_output[2], - self.time_tuple[2])) - def test_dayofweek_result(self): # Test dayofweek --- 353,356 ---- *************** *** 360,372 **** "dayofweek() failed; %s != %s" % (result, comparison)) - def test_dayofweek_trigger(self): - # Make sure dayofweek() gets triggered - strf_output = time.strftime("%Y-%m-%d", self.time_tuple) - strp_output = _strptime.strptime(strf_output, "%Y-%m-%d") - self.failUnless(strp_output[6] == self.time_tuple[6], - "triggering of dayofweek() failed; %s != %s" % - (strp_output[6], self.time_tuple[6])) - - class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" --- 361,364 ---- *************** *** 385,389 **** def test_all_julian_days(self): eq = self.assertEqual - # XXX: should 0 be accepted? for i in range(1, 367): # use 2004, since it is a leap year, we have 366 days --- 377,380 ---- From rhettinger@users.sourceforge.net Sat Jan 18 22:53:38 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 18 Jan 2003 14:53:38 -0800 Subject: [Python-checkins] python/dist/src/Tools/idle ClassBrowser.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory sc8-pr-cvs1:/tmp/cvs-serv29747 Modified Files: ClassBrowser.py Log Message: SF bug #668906: class browser raises AttributeError The Py2.3 updates to the pyclbr module return both Class and Function objects. The IDLE ClassBrowser module only knew about Class and could not handle objects which did not define "super". Fixed by adding a guard. Index: ClassBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/ClassBrowser.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** ClassBrowser.py 3 Dec 2002 09:28:36 -0000 1.14 --- ClassBrowser.py 18 Jan 2003 22:53:36 -0000 1.15 *************** *** 99,103 **** if cl.module == name: s = key ! if cl.super: supers = [] for sup in cl.super: --- 99,103 ---- if cl.module == name: s = key ! if hasattr(cl, "super") and cl.super: supers = [] for sup in cl.super: From rhettinger@users.sourceforge.net Sat Jan 18 23:22:22 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 18 Jan 2003 15:22:22 -0800 Subject: [Python-checkins] python/dist/src/Modules operator.c,2.26,2.27 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv12504/Modules Modified Files: operator.c Log Message: SF patch #670423: Add missing identity tests to operator.c Index: operator.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/operator.c,v retrieving revision 2.26 retrieving revision 2.27 diff -C2 -d -r2.26 -r2.27 *** operator.c 3 Jan 2003 08:24:58 -0000 2.26 --- operator.c 18 Jan 2003 23:22:20 -0000 2.27 *************** *** 109,112 **** --- 109,134 ---- static PyObject* + is_(PyObject *s, PyObject *a) + { + PyObject *a1, *a2, *result = NULL; + if (PyArg_UnpackTuple(a,"is_", 2, 2, &a1, &a2)) { + result = (a1 == a2) ? Py_True : Py_False; + Py_INCREF(result); + } + return result; + } + + static PyObject* + is_not(PyObject *s, PyObject *a) + { + PyObject *a1, *a2, *result = NULL; + if (PyArg_UnpackTuple(a,"is_not", 2, 2, &a1, &a2)) { + result = (a1 != a2) ? Py_True : Py_False; + Py_INCREF(result); + } + return result; + } + + static PyObject* op_getslice(PyObject *s, PyObject *a) { *************** *** 183,186 **** --- 205,210 ---- "isMappingType(a) -- Return True if a has a mapping type, False otherwise.") + spam1(is_, "is_(a, b) -- Same as a is b.") + spam1(is_not, "is_not(a, b) -- Same as a is not b.") spam2(add,__add__, "add(a, b) -- Same as a + b.") spam2(sub,__sub__, "sub(a, b) -- Same as a - b.") From rhettinger@users.sourceforge.net Sat Jan 18 23:22:22 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 18 Jan 2003 15:22:22 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.616,1.617 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv12504/Misc Modified Files: NEWS Log Message: SF patch #670423: Add missing identity tests to operator.c Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.616 retrieving revision 1.617 diff -C2 -d -r1.616 -r1.617 *** NEWS 15 Jan 2003 11:51:06 -0000 1.616 --- NEWS 18 Jan 2003 23:22:19 -0000 1.617 *************** *** 518,521 **** --- 518,526 ---- ----------------- + - Added three operators to the operator module: + operator.pow(a,b) which is equivalent to: a**b. + operator.is_(a,b) which is equivalent to: a is b. + operator.is_not(a,b) which is equivalent to: a is not b. + - posix.openpty now works on all systems that have /dev/ptmx. *************** *** 733,738 **** or when you need to use sets as dict keys, and a class BaseSet which is the base class of the two. - - - Added operator.pow(a,b) which is equivalent to a**b. - Added random.sample(population,k) for random sampling without replacement. --- 738,741 ---- From rhettinger@users.sourceforge.net Sat Jan 18 23:22:22 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 18 Jan 2003 15:22:22 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib liboperator.tex,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv12504/Doc/lib Modified Files: liboperator.tex Log Message: SF patch #670423: Add missing identity tests to operator.c Index: liboperator.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liboperator.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** liboperator.tex 12 Jan 2003 15:04:54 -0000 1.25 --- liboperator.tex 18 Jan 2003 23:22:20 -0000 1.26 *************** *** 49,53 **** The logical operations are also generally applicable to all objects, ! and support truth tests and Boolean operations: \begin{funcdesc}{not_}{o} --- 49,53 ---- The logical operations are also generally applicable to all objects, ! and support truth tests, identity tests, and Boolean operations: \begin{funcdesc}{not_}{o} *************** *** 63,66 **** --- 63,74 ---- otherwise. This is equivalent to using the \class{bool} constructor. + \end{funcdesc} + + \begin{funcdesc}{is_}{a, b} + Return \code{\var{a} is \var{b}}. Tests object identity. + \end{funcdesc} + + \begin{funcdesc}{is_not}{a, b} + Return \code{\var{a} is not \var{b}}. Tests object identity. \end{funcdesc} From rhettinger@users.sourceforge.net Sat Jan 18 23:22:23 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 18 Jan 2003 15:22:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_operator.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv12504/Lib/test Modified Files: test_operator.py Log Message: SF patch #670423: Add missing identity tests to operator.c Index: test_operator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_operator.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_operator.py 19 Aug 2002 03:19:09 -0000 1.10 --- test_operator.py 18 Jan 2003 23:22:20 -0000 1.11 *************** *** 216,219 **** --- 216,230 ---- self.failUnless(operator.xor(0xb, 0xc) == 0x7) + def test_is(self): + a = b = 'xyzpdq' + c = a[:3] + b[3:] + self.failUnless(operator.is_(a, b)) + self.failIf(operator.is_(a,c)) + + def test_is_not(self): + a = b = 'xyzpdq' + c = a[:3] + b[3:] + self.failIf(operator.is_not(a, b)) + self.failUnless(operator.is_not(a,c)) def test_main(): From rhettinger@users.sourceforge.net Sun Jan 19 00:45:04 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 18 Jan 2003 16:45:04 -0800 Subject: [Python-checkins] python/dist/src/Include cStringIO.h,2.19,2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv16131 Modified Files: cStringIO.h Log Message: SF bug #670229: doc improvement for cStringIO.h Gernot Hillier added more detail to the internal API documentation. Index: cStringIO.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/cStringIO.h,v retrieving revision 2.19 retrieving revision 2.20 diff -C2 -d -r2.19 -r2.20 *** cStringIO.h 4 Oct 2002 12:43:02 -0000 2.19 --- cStringIO.h 19 Jan 2003 00:45:01 -0000 2.20 *************** *** 27,40 **** static struct PycStringIO_CAPI { ! /* Read a string. If the last argument is -1, the remainder will be read. */ int(*cread)(PyObject *, char **, int); ! /* Read a line */ int(*creadline)(PyObject *, char **); ! /* Write a string */ int(*cwrite)(PyObject *, char *, int); ! /* Get the cStringIO object as a Python string */ PyObject *(*cgetvalue)(PyObject *); --- 27,45 ---- static struct PycStringIO_CAPI { ! /* Read a string from an input object. If the last argument ! is -1, the remainder will be read. ! */ int(*cread)(PyObject *, char **, int); ! /* Read a line from an input object. Returns the length of the read ! line as an int and a pointer inside the object buffer as char** (so ! the caller doesn't have to provide its own buffer as destination). ! */ int(*creadline)(PyObject *, char **); ! /* Write a string to an output object*/ int(*cwrite)(PyObject *, char *, int); ! /* Get the output object as a Python string (returns new reference). */ PyObject *(*cgetvalue)(PyObject *); *************** *** 42,46 **** PyObject *(*NewOutput)(int); ! /* Create an input object from a Python string */ PyObject *(*NewInput)(PyObject *); --- 47,53 ---- PyObject *(*NewOutput)(int); ! /* Create an input object from a Python string ! (copies the Python string reference). ! */ PyObject *(*NewInput)(PyObject *); From tim_one@users.sourceforge.net Sun Jan 19 04:40:46 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 18 Jan 2003 20:40:46 -0800 Subject: [Python-checkins] python/dist/src/Lib _strptime.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv15164/python/Lib Modified Files: _strptime.py Log Message: SF patch 670194: Performance enhancement for _strptime.py. >From Brett Cannon. Mostly speedups via caching format string -> compiled regexp. Index: _strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/_strptime.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** _strptime.py 18 Jan 2003 03:53:49 -0000 1.10 --- _strptime.py 19 Jan 2003 04:40:44 -0000 1.11 *************** *** 25,29 **** from re import compile as re_compile from re import IGNORECASE - from string import whitespace as whitespace_string __author__ = "Brett Cannon" --- 25,28 ---- *************** *** 34,37 **** --- 33,47 ---- RegexpType = type(re_compile('')) + def _getlang(): + # Figure out what the current language is set to. + current_lang = locale.getlocale(locale.LC_TIME)[0] + if current_lang: + return current_lang + else: + current_lang = locale.getdefaultlocale()[0] + if current_lang: + return current_lang + else: + return '' class LocaleTime(object): *************** *** 286,302 **** def __calc_lang(self): ! # Set self.__lang by using locale.getlocale() or ! # locale.getdefaultlocale(). If both turn up empty, set the attribute ! # to ''. This is to stop calls to this method and to make sure ! # strptime() can produce an re object correctly. ! current_lang = locale.getlocale(locale.LC_TIME)[0] ! if current_lang: ! self.__lang = current_lang ! else: ! current_lang = locale.getdefaultlocale()[0] ! if current_lang: ! self.__lang = current_lang ! else: ! self.__lang = '' --- 296,302 ---- def __calc_lang(self): ! # Set self.__lang by using __getlang(). ! self.__lang = _getlang() ! *************** *** 383,388 **** """Return re pattern for the format string.""" processed_format = '' ! for whitespace in whitespace_string: ! format = format.replace(whitespace, r'\s*') while format.find('%') != -1: directive_index = format.index('%')+1 --- 383,388 ---- """Return re pattern for the format string.""" processed_format = '' ! whitespace_replacement = re_compile('\s+') ! format = whitespace_replacement.sub('\s*', format) while format.find('%') != -1: directive_index = format.index('%')+1 *************** *** 395,407 **** def compile(self, format): """Return a compiled re object for the format string.""" - format = "(?#%s)%s" % (self.locale_time.lang,format) return re_compile(self.pattern(format), IGNORECASE) def strptime(data_string, format="%a %b %d %H:%M:%S %Y"): """Return a time struct based on the input data and the format string.""" ! locale_time = LocaleTime() ! compiled_re = TimeRE(locale_time).compile(format) ! found = compiled_re.match(data_string) if not found: raise ValueError("time data did not match format") --- 395,423 ---- def compile(self, format): """Return a compiled re object for the format string.""" return re_compile(self.pattern(format), IGNORECASE) + # Cached TimeRE; probably only need one instance ever so cache it for performance + _locale_cache = TimeRE() + # Cached regex objects; same reason as for TimeRE cache + _regex_cache = dict() def strptime(data_string, format="%a %b %d %H:%M:%S %Y"): """Return a time struct based on the input data and the format string.""" ! global _locale_cache ! global _regex_cache ! locale_time = _locale_cache.locale_time ! # If the language changes, caches are invalidated, so clear them ! if locale_time.lang != _getlang(): ! _locale_cache = TimeRE() ! _regex_cache.clear() ! format_regex = _regex_cache.get(format) ! if not format_regex: ! # Limit regex cache size to prevent major bloating of the module; ! # The value 5 is arbitrary ! if len(_regex_cache) > 5: ! _regex_cache.clear() ! format_regex = _locale_cache.compile(format) ! _regex_cache[format] = format_regex ! found = format_regex.match(data_string) if not found: raise ValueError("time data did not match format") From tim_one@users.sourceforge.net Sun Jan 19 04:55:01 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 18 Jan 2003 20:55:01 -0800 Subject: [Python-checkins] python/dist/src/Modules timemodule.c,2.133,2.134 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv18113/python/Modules Modified Files: timemodule.c Log Message: Windows flavor of floatsleep(): folded long lines, introduced a temp var for clarity. Index: timemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v retrieving revision 2.133 retrieving revision 2.134 diff -C2 -d -r2.133 -r2.134 *** timemodule.c 17 Jan 2003 20:08:54 -0000 2.133 --- timemodule.c 19 Jan 2003 04:54:58 -0000 2.134 *************** *** 456,460 **** PyObject *strptime_module = PyImport_ImportModule("_strptime"); ! if (!strptime_module) return NULL; return PyObject_CallMethod(strptime_module, "strptime", "O", args); --- 456,460 ---- PyObject *strptime_module = PyImport_ImportModule("_strptime"); ! if (!strptime_module) return NULL; return PyObject_CallMethod(strptime_module, "strptime", "O", args); *************** *** 812,835 **** { double millisecs = secs * 1000.0; if (millisecs > (double)ULONG_MAX) { ! PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); return -1; } Py_BEGIN_ALLOW_THREADS ! /* allow sleep(0) to maintain win32 semantics, and as decreed by ! Guido, only the main thread can be interrupted. */ ! if ((unsigned long)millisecs==0 || main_thread != PyThread_get_thread_ident()) ! Sleep((unsigned long)millisecs); else { DWORD rc; ResetEvent(hInterruptEvent); ! rc = WaitForSingleObject(hInterruptEvent, (unsigned long)millisecs); ! if (rc==WAIT_OBJECT_0) { ! /* yield to make sure real Python signal handler called */ Sleep(1); Py_BLOCK_THREADS - /* PyErr_SetFromErrno() does the "right thing" wrt signals - if errno=EINTR - */ errno = EINTR; PyErr_SetFromErrno(PyExc_IOError); --- 812,840 ---- { double millisecs = secs * 1000.0; + unsigned long ul_millis; + if (millisecs > (double)ULONG_MAX) { ! PyErr_SetString(PyExc_OverflowError, ! "sleep length is too large"); return -1; } Py_BEGIN_ALLOW_THREADS ! /* Allow sleep(0) to maintain win32 semantics, and as decreed ! * by Guido, only the main thread can be interrupted. ! */ ! ul_millis = (unsigned long)millisecs; ! if (ul_millis == 0 || ! main_thread != PyThread_get_thread_ident()) ! Sleep(ul_millis); else { DWORD rc; ResetEvent(hInterruptEvent); ! rc = WaitForSingleObject(hInterruptEvent, ul_millis); ! if (rc == WAIT_OBJECT_0) { ! /* Yield to make sure real Python signal ! * handler called. ! */ Sleep(1); Py_BLOCK_THREADS errno = EINTR; PyErr_SetFromErrno(PyExc_IOError); From rhettinger@users.sourceforge.net Sun Jan 19 05:08:16 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 18 Jan 2003 21:08:16 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.346,2.347 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv20475 Modified Files: ceval.c Log Message: SF patch #670367: Micro-optimizations for ceval.c Make the code slightly shorter, faster, and easier to read. * Eliminate unused DUP_TOPX code for x==1. compile.c always generates DUP_TOP instead. * Since only two cases remain for DUP_TOPX, replace the switch-case with if-elseif. * The in-lined integer compare does a CheckExact on both arguments. Since the second is a little more likely to fail, test it first. * The switch-case for IS/IS_NOT and IN/NOT_IN can separate the regular and inverted cases with no additional work. For all four paths, saves a test and jump. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.346 retrieving revision 2.347 diff -C2 -d -r2.346 -r2.347 *** ceval.c 14 Jan 2003 12:43:10 -0000 2.346 --- ceval.c 19 Jan 2003 05:08:13 -0000 2.347 *************** *** 856,867 **** case DUP_TOPX: ! switch (oparg) { ! case 1: ! x = TOP(); ! Py_INCREF(x); ! STACKADJ(1); ! SET_TOP(x); ! continue; ! case 2: x = TOP(); Py_INCREF(x); --- 856,860 ---- case DUP_TOPX: ! if (oparg == 2) { x = TOP(); Py_INCREF(x); *************** *** 872,876 **** SET_SECOND(w); continue; ! case 3: x = TOP(); Py_INCREF(x); --- 865,869 ---- SET_SECOND(w); continue; ! } else if (oparg == 3) { x = TOP(); Py_INCREF(x); *************** *** 884,891 **** SET_THIRD(v); continue; - default: - Py_FatalError("invalid argument to DUP_TOPX" - " (bytecode corruption?)"); } break; --- 877,883 ---- SET_THIRD(v); continue; } + Py_FatalError("invalid argument to DUP_TOPX" + " (bytecode corruption?)"); break; *************** *** 1843,1847 **** w = POP(); v = TOP(); ! if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { /* INLINE: cmp(int, int) */ register long a, b; --- 1835,1839 ---- w = POP(); v = TOP(); ! if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) { /* INLINE: cmp(int, int) */ register long a, b; *************** *** 3582,3597 **** switch (op) { case PyCmp_IS: - case PyCmp_IS_NOT: res = (v == w); ! if (op == (int) PyCmp_IS_NOT) ! res = !res; break; case PyCmp_IN: case PyCmp_NOT_IN: res = PySequence_Contains(w, v); if (res < 0) return NULL; ! if (op == (int) PyCmp_NOT_IN) ! res = !res; break; case PyCmp_EXC_MATCH: --- 3574,3592 ---- switch (op) { case PyCmp_IS: res = (v == w); ! break; ! case PyCmp_IS_NOT: ! res = (v != w); break; case PyCmp_IN: + res = PySequence_Contains(w, v); + if (res < 0) + return NULL; + break; case PyCmp_NOT_IN: res = PySequence_Contains(w, v); if (res < 0) return NULL; ! res = !res; break; case PyCmp_EXC_MATCH: From rhettinger@users.sourceforge.net Sun Jan 19 13:08:21 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 19 Jan 2003 05:08:21 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref2.tex,1.46,1.47 ref3.tex,1.96,1.97 ref6.tex,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv31488 Modified Files: ref2.tex ref3.tex ref6.tex Log Message: SF patch #634866: Alex Martelli's corrections to the ref manual. Backport candidate. All but one or two of these changes are applicable to 2.2.2. Index: ref2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref2.tex,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** ref2.tex 24 Oct 2002 19:57:37 -0000 1.46 --- ref2.tex 19 Jan 2003 13:08:18 -0000 1.47 *************** *** 327,331 **** \end{tableiii} ! (XXX need section references here.) Note: --- 327,333 ---- \end{tableiii} ! See sections: \ref{import}, ``The \keyword{import} statement''; ! \ref{specialnames}, ``Special method names''; ! \ref{atom-identifiers}, ``Identifiers (Names)''. Note: *************** *** 563,578 **** digit \character{1}. ! Plain integer decimal literals must be at most 2147483647 (i.e., the ! largest positive integer, using 32-bit arithmetic). Plain octal and ! hexadecimal literals may be as large as 4294967295, but values larger ! than 2147483647 are converted to a negative value by subtracting ! 4294967296. There is no limit for long integer literals apart from ! what can be stored in available memory. ! Some examples of plain and long integer literals: \begin{verbatim} 7 2147483647 0177 0x80000000 3L 79228162514264337593543950336L 0377L 0x100000000L \end{verbatim} --- 565,587 ---- digit \character{1}. ! Plain integer decimal literals that are above the largest representable ! plain integer (e.g., 2147483647 when using 32-bit arithmetic) are accepted ! as if they were long integers instead. Octal and hexadecimal literals ! behave similarly, but when in the range just above the largest representable ! plain integer but below the largest unsigned 32-bit number (on a machine ! using 32-bit arithmetic), 4294967296, they are taken as the negative plain ! integer obtained by subtracting 4294967296 from their unsigned value. There ! is no limit for long integer literals apart from what can be stored in ! available memory. For example, 0xdeadbeef is taken, on a 32-bit machine, ! as the value -559038737, while 0xdeadbeeffeed is taken as the value ! 244837814107885L. ! Some examples of plain integer literals (first row) and long integer ! literals (second and third rows): \begin{verbatim} 7 2147483647 0177 0x80000000 3L 79228162514264337593543950336L 0377L 0x100000000L + 79228162514264337593543950336 0xdeadbeeffeed \end{verbatim} Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -d -r1.96 -r1.97 *** ref3.tex 17 Dec 2002 16:15:12 -0000 1.96 --- ref3.tex 19 Jan 2003 13:08:18 -0000 1.97 *************** *** 18,22 **** representing its identity (currently implemented as its address). An object's \dfn{type} is ! also unchangeable. It determines the operations that an object supports (e.g., ``does it have a length?'') and also defines the possible values for objects of that type. The --- 18,30 ---- representing its identity (currently implemented as its address). An object's \dfn{type} is ! also unchangeable.\footnote{Since Python 2.2, a gradual merging of ! types and classes has been started that makes this and a few other ! assertions made in this manual not 100\% accurate and complete: ! for example, it \emph{is} now possible in some cases to change an ! object's type, under certain controlled conditions. Until this manual ! undergoes extensive revision, it must now be taken as authoritative ! only regarding ``classic classes'', that are still the default, for ! compatibility purposes, in Python 2.2 and 2.3.} ! An object's type determines the operations that the object supports (e.g., ``does it have a length?'') and also defines the possible values for objects of that type. The *************** *** 48,52 **** reachable. (Implementation note: the current implementation uses a reference-counting scheme with (optional) delayed detection of ! cyclicly linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the --- 56,60 ---- reachable. (Implementation note: the current implementation uses a reference-counting scheme with (optional) delayed detection of ! cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the *************** *** 101,105 **** Below is a list of the types that are built into Python. Extension ! modules written in \C{} can define additional types. Future versions of Python may add types to the type hierarchy (e.g., rational numbers, efficiently stored arrays of integers, etc.). --- 109,114 ---- Below is a list of the types that are built into Python. Extension ! modules (written in C, Java, or other languages, depending on ! the implementation) can define additional types. Future versions of Python may add types to the type hierarchy (e.g., rational numbers, efficiently stored arrays of integers, etc.). *************** *** 171,175 **** size, but not smaller.) When the result of an operation would fall outside this range, the ! exception \exception{OverflowError} is raised. For the purpose of shift and mask operations, integers are assumed to have a binary, 2's complement notation using 32 or more bits, and --- 180,185 ---- size, but not smaller.) When the result of an operation would fall outside this range, the ! result is normally returned as a long integer (in some cases, the ! exception \exception{OverflowError} is raised instead). For the purpose of shift and mask operations, integers are assumed to have a binary, 2's complement notation using 32 or more bits, and *************** *** 203,209 **** meaningful interpretation of shift and mask operations involving negative integers and the least surprises when switching between the ! plain and long integer domains. For any operation except left shift, if it yields a result in the plain integer domain without causing ! overflow, it will yield the same result in the long integer domain or when using mixed operands. \indexii{integer}{representation} --- 213,219 ---- meaningful interpretation of shift and mask operations involving negative integers and the least surprises when switching between the ! plain and long integer domains. Any operation except left shift, if it yields a result in the plain integer domain without causing ! overflow, will yield the same result in the long integer domain or when using mixed operands. \indexii{integer}{representation} *************** *** 211,216 **** \item[Floating point numbers] These represent machine-level double precision floating point numbers. ! You are at the mercy of the underlying machine architecture and ! \C{} implementation for the accepted range and handling of overflow. Python does not support single-precision floating point numbers; the savings in processor and memory usage that are usually the reason for using --- 221,226 ---- \item[Floating point numbers] These represent machine-level double precision floating point numbers. ! You are at the mercy of the underlying machine architecture (and ! C or Java implementation) for the accepted range and handling of overflow. Python does not support single-precision floating point numbers; the savings in processor and memory usage that are usually the reason for using *************** *** 221,231 **** \indexii{floating point}{number} \indexii{C}{language} \item[Complex numbers] These represent complex numbers as a pair of machine-level double precision floating point numbers. The same caveats apply as for ! floating point numbers. The real and imaginary value of a complex ! number \code{z} can be retrieved through the attributes \code{z.real} ! and \code{z.imag}. \obindex{complex} \indexii{complex}{number} --- 231,242 ---- \indexii{floating point}{number} \indexii{C}{language} + \indexii{Java}{language} \item[Complex numbers] These represent complex numbers as a pair of machine-level double precision floating point numbers. The same caveats apply as for ! floating point numbers. The real and imaginary parts of a complex ! number \code{z} can be retrieved through the read-only attributes ! \code{z.real} and \code{z.imag}. \obindex{complex} \indexii{complex}{number} *************** *** 350,354 **** \index{slicing} ! There is currently a single mutable sequence type: \begin{description} --- 361,365 ---- \index{slicing} ! There is currently a single intrinsic mutable sequence type: \begin{description} *************** *** 396,400 **** dictionary entry. ! Dictionaries are mutable; they are created by the \code{\{...\}} notation (see section \ref{dict}, ``Dictionary Displays''). --- 407,411 ---- dictionary entry. ! Dictionaries are mutable; they can be created by the \code{\{...\}} notation (see section \ref{dict}, ``Dictionary Displays''). *************** *** 552,559 **** \item[Built-in methods] This is really a different disguise of a built-in function, this time ! containing an object passed to the \C{} function as an implicit extra argument. An example of a built-in method is ! \code{\var{list}.append()}, assuming ! \var{list} is a list object. In this case, the special read-only attribute \member{__self__} is set to the object denoted by \var{list}. --- 563,570 ---- \item[Built-in methods] This is really a different disguise of a built-in function, this time ! containing an object passed to the C function as an implicit extra argument. An example of a built-in method is ! \code{\var{alist}.append()}, assuming ! \var{alist} is a list object. In this case, the special read-only attribute \member{__self__} is set to the object denoted by \var{list}. *************** *** 941,946 **** Called\indexii{class}{constructor} when the instance is created. The arguments are those passed to the class constructor expression. If a ! base class has an \method{__init__()} method the derived class's ! \method{__init__()} method must explicitly call it to ensure proper initialization of the base class part of the instance; for example: \samp{BaseClass.__init__(\var{self}, [\var{args}...])}. As a special --- 952,957 ---- Called\indexii{class}{constructor} when the instance is created. The arguments are those passed to the class constructor expression. If a ! base class has an \method{__init__()} method, the derived class's ! \method{__init__()} method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: \samp{BaseClass.__init__(\var{self}, [\var{args}...])}. As a special *************** *** 953,957 **** Called when the instance is about to be destroyed. This is also called a destructor\index{destructor}. If a base class ! has a \method{__del__()} method, the derived class's \method{__del__()} method must explicitly call it to ensure proper deletion of the base class part of the instance. Note that it is possible (though not recommended!) --- 964,969 ---- Called when the instance is about to be destroyed. This is also called a destructor\index{destructor}. If a base class ! has a \method{__del__()} method, the derived class's \method{__del__()} ! method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance. Note that it is possible (though not recommended!) *************** *** 967,973 **** \samp{del x} doesn't directly call \code{x.__del__()} --- the former decrements the reference count for ! \code{x} by one, and the latter is only called when its reference count reaches zero. Some common situations that may prevent the ! reference count of an object to go to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object --- 979,985 ---- \samp{del x} doesn't directly call \code{x.__del__()} --- the former decrements the reference count for ! \code{x} by one, and the latter is only called when \code{x}'s reference count reaches zero. Some common situations that may prevent the ! reference count of an object from going to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object *************** *** 1015,1018 **** --- 1027,1033 ---- description...}>} should be returned. The return value must be a string object. + If a class defines \method{__repr__()} but not \method{__str__()}, + then \method{__repr__()} is also used when an ``informal'' string + representation of instances of that class is required. This is typically used for debugging, so it is important that the *************** *** 1054,1058 **** used in a Boolean context, the return value should be interpretable as a Boolean value, else a \exception{TypeError} will be raised. ! By convention, \code{0} is used for false and \code{1} for true. There are no reflected (swapped-argument) versions of these methods --- 1069,1073 ---- used in a Boolean context, the return value should be interpretable as a Boolean value, else a \exception{TypeError} will be raised. ! By convention, \code{False} is used for false and \code{True} for true. There are no reflected (swapped-argument) versions of these methods *************** *** 1079,1083 **** keys. (Note: the restriction that exceptions are not propagated by ! \method{__cmp__()} has been removed in Python 1.5.) \bifuncindex{cmp} \index{comparisons} --- 1094,1098 ---- keys. (Note: the restriction that exceptions are not propagated by ! \method{__cmp__()} has been removed since Python 1.5.) \bifuncindex{cmp} \index{comparisons} *************** *** 1201,1207 **** that mappings provide the methods \method{keys()}, \method{values()}, \method{items()}, \method{has_key()}, \method{get()}, \method{clear()}, \method{copy()}, and \method{update()} behaving similar to those for ! Python's standard dictionary objects; mutable sequences should provide methods \method{append()}, \method{count()}, \method{index()}, \method{insert()}, \method{pop()}, \method{remove()}, \method{reverse()} and \method{sort()}, like Python standard list objects. Finally, --- 1216,1229 ---- that mappings provide the methods \method{keys()}, \method{values()}, \method{items()}, \method{has_key()}, \method{get()}, \method{clear()}, + \method{setdefault()}, \method{iterkeys()}, \method{itervalues()}, + \method{iteritems()}, \method{pop()},, \method{popitem()}, \method{copy()}, and \method{update()} behaving similar to those for ! Python's standard dictionary objects. The \module{UserDict} module ! provides a \class{DictMixin} class to help create those methods ! from a base set of \method{__getitem__()}, \method{__setitem__()}, ! \method{__delitem__()}, and \method{keys()}. ! Mutable sequences should provide methods \method{append()}, \method{count()}, \method{index()}, + \method{extend()}, \method{insert()}, \method{pop()}, \method{remove()}, \method{reverse()} and \method{sort()}, like Python standard list objects. Finally, *************** *** 1215,1225 **** the \code{in} operator; for mappings, \code{in} should be equivalent of \method{has_key()}; for sequences, it should search through the ! values. \withsubitem{(mapping object method)}{ \ttindex{keys()} \ttindex{values()} \ttindex{items()} \ttindex{has_key()} \ttindex{get()} \ttindex{clear()} \ttindex{copy()} --- 1237,1257 ---- the \code{in} operator; for mappings, \code{in} should be equivalent of \method{has_key()}; for sequences, it should search through the ! values. It is further recommended that both mappings and sequences ! implement the \method{__iter__()} method to allow efficient iteration ! through the container; for mappings, \method{__iter__()} should be ! the same as \method{iterkeys()}; for sequences, it should iterate ! through the values. \withsubitem{(mapping object method)}{ \ttindex{keys()} \ttindex{values()} \ttindex{items()} + \ttindex{iterkeys()} + \ttindex{itervalues()} + \ttindex{iteritems()} \ttindex{has_key()} \ttindex{get()} + \ttindex{setdefault()} + \ttindex{pop()} + \ttindex{popitem()} \ttindex{clear()} \ttindex{copy()} *************** *** 1229,1232 **** --- 1261,1265 ---- \ttindex{append()} \ttindex{count()} + \ttindex{extend()} \ttindex{index()} \ttindex{insert()} *************** *** 1241,1245 **** \ttindex{__rmul__()} \ttindex{__imul__()} ! \ttindex{__contains__()}} \withsubitem{(numeric object method)}{\ttindex{__coerce__()}} --- 1274,1279 ---- \ttindex{__rmul__()} \ttindex{__imul__()} ! \ttindex{__contains__()} ! \ttindex{__iter__()}} \withsubitem{(numeric object method)}{\ttindex{__coerce__()}} *************** *** 1316,1322 **** \label{sequence-methods}} ! The following methods can be defined to further emulate sequence ! objects. Immutable sequences methods should only define ! \method{__getslice__()}; mutable sequences, should define all three three methods. --- 1350,1356 ---- \label{sequence-methods}} ! The following optional methods can be defined to further emulate sequence ! objects. Immutable sequences methods should at most only define ! \method{__getslice__()}; mutable sequences might define all three three methods. *************** *** 1342,1348 **** Same notes for \var{i} and \var{j} as for \method{__getslice__()}. ! This method is deprecated. If no \method{__setslice__()} is found, a ! slice object is created instead, and passed to \method{__setitem__()} ! instead. \end{methoddesc} --- 1376,1384 ---- Same notes for \var{i} and \var{j} as for \method{__getslice__()}. ! This method is deprecated. If no \method{__setslice__()} is found, ! or for extended slicing of the form ! \code{\var{self}[\var{i}:\var{j}:\var{k}]}, a ! slice object is created, and passed to \method{__setitem__()}, ! instead of \method{__setslice__()} being called. \end{methoddesc} *************** *** 1350,1356 **** Called to implement deletion of \code{\var{self}[\var{i}:\var{j}]}. Same notes for \var{i} and \var{j} as for \method{__getslice__()}. ! This method is deprecated. If no \method{__delslice__()} is found, a ! slice object is created instead, and passed to \method{__delitem__()} ! instead. \end{methoddesc} --- 1386,1394 ---- Called to implement deletion of \code{\var{self}[\var{i}:\var{j}]}. Same notes for \var{i} and \var{j} as for \method{__getslice__()}. ! This method is deprecated. If no \method{__delslice__()} is found, ! or for extended slicing of the form ! \code{\var{self}[\var{i}:\var{j}:\var{k}]}, a ! slice object is created, and passed to \method{__delitem__()}, ! instead of \method{__delslice__()} being called. \end{methoddesc} *************** *** 1388,1393 **** \end{verbatim} ! Note the calls to \function{max()}; these are actually necessary due ! to the handling of negative indices before the \method{__*slice__()} methods are called. When negative indexes are used, the \method{__*item__()} methods receive them as provided, but --- 1426,1431 ---- \end{verbatim} ! Note the calls to \function{max()}; these are necessary because of ! the handling of negative indices before the \method{__*slice__()} methods are called. When negative indexes are used, the \method{__*item__()} methods receive them as provided, but Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** ref6.tex 16 Jan 2003 11:30:08 -0000 1.60 --- ref6.tex 19 Jan 2003 13:08:18 -0000 1.61 *************** *** 639,645 **** \indexii{name}{binding} \kwindex{from} - % XXX Need to define what ``initialize'' means here ! The system maintains a table of modules that have been initialized, indexed by module name. This table is accessible as \code{sys.modules}. When a module name is found in --- 639,651 ---- \indexii{name}{binding} \kwindex{from} ! In this context, to ``initialize'' a built-in or extension module means to ! call an initialization function that the module must provide for the purpose ! (in the reference implementation, the function's name is obtained by ! prepending string ``init'' to the module's name); to ``initialize'' a ! Python-coded module means to execute the module's body. ! ! The system maintains a table of modules that have been or are being ! initialized, indexed by module name. This table is accessible as \code{sys.modules}. When a module name is found in From rhettinger@users.sourceforge.net Sun Jan 19 13:21:23 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 19 Jan 2003 05:21:23 -0800 Subject: [Python-checkins] python/dist/src/Lib inspect.py,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv6102 Modified Files: inspect.py Log Message: SF patch #634557: inspect.BlockFinder didn't do a good enough job finding the end of code blocks. Patch contributed by Patrick O'Brien. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** inspect.py 14 Jan 2003 02:19:36 -0000 1.40 --- inspect.py 19 Jan 2003 13:21:20 -0000 1.41 *************** *** 502,505 **** --- 502,507 ---- self.indent = self.indent - 1 if self.indent == 0: raise EndOfBlock, self.last + elif type == tokenize.NAME and scol == 0: + raise EndOfBlock, self.last def getblock(lines): From rhettinger@users.sourceforge.net Sun Jan 19 14:16:21 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 19 Jan 2003 06:16:21 -0800 Subject: [Python-checkins] python/dist/src/Lib inspect.py,1.26.10.2,1.26.10.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv11814 Modified Files: Tag: release22-maint inspect.py Log Message: Backport 1.40 and 1.41 so that inspect isn't fooled by single line definitions, pass statements, and lambdas. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.26.10.2 retrieving revision 1.26.10.3 diff -C2 -d -r1.26.10.2 -r1.26.10.3 *** inspect.py 17 Mar 2002 18:57:07 -0000 1.26.10.2 --- inspect.py 19 Jan 2003 14:16:19 -0000 1.26.10.3 *************** *** 411,415 **** raise IOError, 'could not find function definition' lnum = object.co_firstlineno - 1 ! pat = re.compile(r'^\s*def\s') while lnum > 0: if pat.match(lines[lnum]): break --- 411,415 ---- raise IOError, 'could not find function definition' lnum = object.co_firstlineno - 1 ! pat = re.compile(r'^(\s*def\s)|(.*\slambda(:|\s))') while lnum > 0: if pat.match(lines[lnum]): break *************** *** 490,493 **** --- 490,495 ---- self.indent = self.indent - 1 if self.indent == 0: raise EndOfBlock, self.last + elif type == tokenize.NAME and scol == 0: + raise EndOfBlock, self.last def getblock(lines): *************** *** 497,500 **** --- 499,504 ---- except EndOfBlock, eob: return lines[:eob.args[0]] + # Fooling the indent/dedent logic implies a one-line definition + return lines[:1] def getsourcelines(object): From rhettinger@users.sourceforge.net Sun Jan 19 14:54:11 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 19 Jan 2003 06:54:11 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref2.tex,1.34.6.6,1.34.6.7 ref3.tex,1.82.4.6,1.82.4.7 ref6.tex,1.47.4.6,1.47.4.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv6648 Modified Files: Tag: release22-maint ref2.tex ref3.tex ref6.tex Log Message: Backport SF patch #634866: Alex Martelli's corrections to the ref manual. Index: ref2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref2.tex,v retrieving revision 1.34.6.6 retrieving revision 1.34.6.7 diff -C2 -d -r1.34.6.6 -r1.34.6.7 *** ref2.tex 24 Oct 2002 19:58:03 -0000 1.34.6.6 --- ref2.tex 19 Jan 2003 14:54:08 -0000 1.34.6.7 *************** *** 293,297 **** \end{tableiii} ! (XXX need section references here.) Note: --- 293,299 ---- \end{tableiii} ! See sections: \ref{import}, ``The \keyword{import} statement''; ! \ref{specialnames}, ``Special method names''; ! \ref{atom-identifiers}, ``Identifiers (Names)''. Note: *************** *** 528,543 **** the letter `l' looks too much like the digit `1'. ! Plain integer decimal literals must be at most 2147483647 (i.e., the ! largest positive integer, using 32-bit arithmetic). Plain octal and ! hexadecimal literals may be as large as 4294967295, but values larger ! than 2147483647 are converted to a negative value by subtracting ! 4294967296. There is no limit for long integer literals apart from ! what can be stored in available memory. ! Some examples of plain and long integer literals: \begin{verbatim} 7 2147483647 0177 0x80000000 3L 79228162514264337593543950336L 0377L 0x100000000L \end{verbatim} --- 530,552 ---- the letter `l' looks too much like the digit `1'. ! Plain integer decimal literals that are above the largest representable ! plain integer (e.g., 2147483647 when using 32-bit arithmetic) are accepted ! as if they were long integers instead. Octal and hexadecimal literals ! behave similarly, but when in the range just above the largest representable ! plain integer but below the largest unsigned 32-bit number (on a machine ! using 32-bit arithmetic), 4294967296, they are taken as the negative plain ! integer obtained by subtracting 4294967296 from their unsigned value. There ! is no limit for long integer literals apart from what can be stored in ! available memory. For example, 0xdeadbeef is taken, on a 32-bit machine, ! as the value -559038737, while 0xdeadbeeffeed is taken as the value ! 244837814107885L. ! Some examples of plain integer literals (first row) and long integer ! literals (second and third rows): \begin{verbatim} 7 2147483647 0177 0x80000000 3L 79228162514264337593543950336L 0377L 0x100000000L + 79228162514264337593543950336 0xdeadbeeffeed \end{verbatim} Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.82.4.6 retrieving revision 1.82.4.7 diff -C2 -d -r1.82.4.6 -r1.82.4.7 *** ref3.tex 5 Oct 2002 06:40:49 -0000 1.82.4.6 --- ref3.tex 19 Jan 2003 14:54:08 -0000 1.82.4.7 *************** *** 18,22 **** representing its identity (currently implemented as its address). An object's \dfn{type} is ! also unchangeable. It determines the operations that an object supports (e.g., ``does it have a length?'') and also defines the possible values for objects of that type. The --- 18,30 ---- representing its identity (currently implemented as its address). An object's \dfn{type} is ! also unchangeable.\footnote{Since Python 2.2, a gradual merging of ! types and classes has been started that makes this and a few other ! assertions made in this manual not 100\% accurate and complete: ! for example, it \emph{is} now possible in some cases to change an ! object's type, under certain controlled conditions. Until this manual ! undergoes extensive revision, it must now be taken as authoritative ! only regarding ``classic classes'', that are still the default, for ! compatibility purposes, in Python 2.2 and 2.3.} ! An object's type determines the operations that the object supports (e.g., ``does it have a length?'') and also defines the possible values for objects of that type. The *************** *** 48,52 **** reachable. (Implementation note: the current implementation uses a reference-counting scheme with (optional) delayed detection of ! cyclicly linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the --- 56,60 ---- reachable. (Implementation note: the current implementation uses a reference-counting scheme with (optional) delayed detection of ! cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the *************** *** 101,105 **** Below is a list of the types that are built into Python. Extension ! modules written in \C{} can define additional types. Future versions of Python may add types to the type hierarchy (e.g., rational numbers, efficiently stored arrays of integers, etc.). --- 109,114 ---- Below is a list of the types that are built into Python. Extension ! modules (written in C, Java, or other languages, depending on ! the implementation) can define additional types. Future versions of Python may add types to the type hierarchy (e.g., rational numbers, efficiently stored arrays of integers, etc.). *************** *** 171,175 **** size, but not smaller.) When the result of an operation would fall outside this range, the ! exception \exception{OverflowError} is raised. For the purpose of shift and mask operations, integers are assumed to have a binary, 2's complement notation using 32 or more bits, and --- 180,185 ---- size, but not smaller.) When the result of an operation would fall outside this range, the ! result is normally returned as a long integer (in some cases, the ! exception \exception{OverflowError} is raised instead). For the purpose of shift and mask operations, integers are assumed to have a binary, 2's complement notation using 32 or more bits, and *************** *** 192,198 **** meaningful interpretation of shift and mask operations involving negative integers and the least surprises when switching between the ! plain and long integer domains. For any operation except left shift, if it yields a result in the plain integer domain without causing ! overflow, it will yield the same result in the long integer domain or when using mixed operands. \indexii{integer}{representation} --- 202,208 ---- meaningful interpretation of shift and mask operations involving negative integers and the least surprises when switching between the ! plain and long integer domains. Any operation except left shift, if it yields a result in the plain integer domain without causing ! overflow, will yield the same result in the long integer domain or when using mixed operands. \indexii{integer}{representation} *************** *** 200,205 **** \item[Floating point numbers] These represent machine-level double precision floating point numbers. ! You are at the mercy of the underlying machine architecture and ! \C{} implementation for the accepted range and handling of overflow. Python does not support single-precision floating point numbers; the savings in processor and memory usage that are usually the reason for using --- 210,215 ---- \item[Floating point numbers] These represent machine-level double precision floating point numbers. ! You are at the mercy of the underlying machine architecture (and ! C or Java implementation) for the accepted range and handling of overflow. Python does not support single-precision floating point numbers; the savings in processor and memory usage that are usually the reason for using *************** *** 210,220 **** \indexii{floating point}{number} \indexii{C}{language} \item[Complex numbers] These represent complex numbers as a pair of machine-level double precision floating point numbers. The same caveats apply as for ! floating point numbers. The real and imaginary value of a complex ! number \code{z} can be retrieved through the attributes \code{z.real} ! and \code{z.imag}. \obindex{complex} \indexii{complex}{number} --- 220,231 ---- \indexii{floating point}{number} \indexii{C}{language} + \indexii{Java}{language} \item[Complex numbers] These represent complex numbers as a pair of machine-level double precision floating point numbers. The same caveats apply as for ! floating point numbers. The real and imaginary parts of a complex ! number \code{z} can be retrieved through the read-only attributes ! \code{z.real} and \code{z.imag}. \obindex{complex} \indexii{complex}{number} *************** *** 331,335 **** \index{slicing} ! There is currently a single mutable sequence type: \begin{description} --- 342,346 ---- \index{slicing} ! There is currently a single intrinsic mutable sequence type: \begin{description} *************** *** 377,381 **** dictionary entry. ! Dictionaries are mutable; they are created by the \code{\{...\}} notation (see section \ref{dict}, ``Dictionary Displays''). --- 388,392 ---- dictionary entry. ! Dictionaries are mutable; they can be created by the \code{\{...\}} notation (see section \ref{dict}, ``Dictionary Displays''). *************** *** 535,542 **** \item[Built-in methods] This is really a different disguise of a built-in function, this time ! containing an object passed to the \C{} function as an implicit extra argument. An example of a built-in method is ! \code{\var{list}.append()}, assuming ! \var{list} is a list object. In this case, the special read-only attribute \member{__self__} is set to the object denoted by \var{list}. --- 546,553 ---- \item[Built-in methods] This is really a different disguise of a built-in function, this time ! containing an object passed to the C function as an implicit extra argument. An example of a built-in method is ! \code{\var{alist}.append()}, assuming ! \var{alist} is a list object. In this case, the special read-only attribute \member{__self__} is set to the object denoted by \var{list}. *************** *** 904,909 **** Called\indexii{class}{constructor} when the instance is created. The arguments are those passed to the class constructor expression. If a ! base class has an \method{__init__()} method the derived class's ! \method{__init__()} method must explicitly call it to ensure proper initialization of the base class part of the instance; for example: \samp{BaseClass.__init__(\var{self}, [\var{args}...])}. As a special --- 915,920 ---- Called\indexii{class}{constructor} when the instance is created. The arguments are those passed to the class constructor expression. If a ! base class has an \method{__init__()} method, the derived class's ! \method{__init__()} method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: \samp{BaseClass.__init__(\var{self}, [\var{args}...])}. As a special *************** *** 916,920 **** Called when the instance is about to be destroyed. This is also called a destructor\index{destructor}. If a base class ! has a \method{__del__()} method, the derived class's \method{__del__()} method must explicitly call it to ensure proper deletion of the base class part of the instance. Note that it is possible (though not recommended!) --- 927,932 ---- Called when the instance is about to be destroyed. This is also called a destructor\index{destructor}. If a base class ! has a \method{__del__()} method, the derived class's \method{__del__()} ! method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance. Note that it is possible (though not recommended!) *************** *** 930,936 **** \samp{del x} doesn't directly call \code{x.__del__()} --- the former decrements the reference count for ! \code{x} by one, and the latter is only called when its reference count reaches zero. Some common situations that may prevent the ! reference count of an object to go to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object --- 942,948 ---- \samp{del x} doesn't directly call \code{x.__del__()} --- the former decrements the reference count for ! \code{x} by one, and the latter is only called when \code{x}'s reference count reaches zero. Some common situations that may prevent the ! reference count of an object from going to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object *************** *** 978,981 **** --- 990,996 ---- description...}>} should be returned. The return value must be a string object. + If a class defines \method{__repr__()} but not \method{__str__()}, + then \method{__repr__()} is also used when an ``informal'' string + representation of instances of that class is required. This is typically used for debugging, so it is important that the *************** *** 1017,1021 **** used in a Boolean context, the return value should be interpretable as a Boolean value, else a \exception{TypeError} will be raised. ! By convention, \code{0} is used for false and \code{1} for true. There are no reflected (swapped-argument) versions of these methods --- 1032,1036 ---- used in a Boolean context, the return value should be interpretable as a Boolean value, else a \exception{TypeError} will be raised. ! By convention, \code{False} is used for false and \code{True} for true. There are no reflected (swapped-argument) versions of these methods *************** *** 1042,1046 **** keys. (Note: the restriction that exceptions are not propagated by ! \method{__cmp__()} has been removed in Python 1.5.) \bifuncindex{cmp} \index{comparisons} --- 1057,1061 ---- keys. (Note: the restriction that exceptions are not propagated by ! \method{__cmp__()} has been removed since Python 1.5.) \bifuncindex{cmp} \index{comparisons} *************** *** 1155,1161 **** that mappings provide the methods \method{keys()}, \method{values()}, \method{items()}, \method{has_key()}, \method{get()}, \method{clear()}, \method{copy()}, and \method{update()} behaving similar to those for ! Python's standard dictionary objects; mutable sequences should provide methods \method{append()}, \method{count()}, \method{index()}, \method{insert()}, \method{pop()}, \method{remove()}, \method{reverse()} and \method{sort()}, like Python standard list objects. Finally, --- 1170,1180 ---- that mappings provide the methods \method{keys()}, \method{values()}, \method{items()}, \method{has_key()}, \method{get()}, \method{clear()}, + \method{setdefault()}, \method{iterkeys()}, \method{itervalues()}, + \method{iteritems()}, \method{popitem()}, \method{copy()}, and \method{update()} behaving similar to those for ! Python's standard dictionary objects. ! Mutable sequences should provide methods \method{append()}, \method{count()}, \method{index()}, + \method{extend()}, \method{insert()}, \method{pop()}, \method{remove()}, \method{reverse()} and \method{sort()}, like Python standard list objects. Finally, *************** *** 1169,1179 **** the \code{in} operator; for mappings, \code{in} should be equivalent of \method{has_key()}; for sequences, it should search through the ! values. \withsubitem{(mapping object method)}{ \ttindex{keys()} \ttindex{values()} \ttindex{items()} \ttindex{has_key()} \ttindex{get()} \ttindex{clear()} \ttindex{copy()} --- 1188,1208 ---- the \code{in} operator; for mappings, \code{in} should be equivalent of \method{has_key()}; for sequences, it should search through the ! values. It is further recommended that both mappings and sequences ! implement the \method{__iter__()} method to allow efficient iteration ! through the container; for mappings, \method{__iter__()} should be ! the same as \method{iterkeys()}; for sequences, it should iterate ! through the values. \withsubitem{(mapping object method)}{ \ttindex{keys()} \ttindex{values()} \ttindex{items()} + \ttindex{iterkeys()} + \ttindex{itervalues()} + \ttindex{iteritems()} \ttindex{has_key()} \ttindex{get()} + \ttindex{setdefault()} + \ttindex{pop()} + \ttindex{popitem()} \ttindex{clear()} \ttindex{copy()} *************** *** 1183,1186 **** --- 1212,1216 ---- \ttindex{append()} \ttindex{count()} + \ttindex{extend()} \ttindex{index()} \ttindex{insert()} *************** *** 1195,1199 **** \ttindex{__rmul__()} \ttindex{__imul__()} ! \ttindex{__contains__()}} \withsubitem{(numeric object method)}{\ttindex{__coerce__()}} --- 1225,1230 ---- \ttindex{__rmul__()} \ttindex{__imul__()} ! \ttindex{__contains__()} ! \ttindex{__iter__()}} \withsubitem{(numeric object method)}{\ttindex{__coerce__()}} *************** *** 1270,1276 **** \label{sequence-methods}} ! The following methods can be defined to further emulate sequence ! objects. Immutable sequences methods should only define ! \method{__getslice__()}; mutable sequences, should define all three three methods. --- 1301,1307 ---- \label{sequence-methods}} ! The following optional methods can be defined to further emulate sequence ! objects. Immutable sequences methods should at most only define ! \method{__getslice__()}; mutable sequences might define all three three methods. *************** *** 1296,1302 **** Same notes for \var{i} and \var{j} as for \method{__getslice__()}. ! This method is deprecated. If no \method{__setslice__()} is found, a ! slice object is created instead, and passed to \method{__setitem__()} ! instead. \end{methoddesc} --- 1327,1335 ---- Same notes for \var{i} and \var{j} as for \method{__getslice__()}. ! This method is deprecated. If no \method{__setslice__()} is found, ! or for extended slicing of the form ! \code{\var{self}[\var{i}:\var{j}:\var{k}]}, a ! slice object is created, and passed to \method{__setitem__()}, ! instead of \method{__setslice__()} being called. \end{methoddesc} *************** *** 1304,1310 **** Called to implement deletion of \code{\var{self}[\var{i}:\var{j}]}. Same notes for \var{i} and \var{j} as for \method{__getslice__()}. ! This method is deprecated. If no \method{__delslice__()} is found, a ! slice object is created instead, and passed to \method{__delitem__()} ! instead. \end{methoddesc} --- 1337,1345 ---- Called to implement deletion of \code{\var{self}[\var{i}:\var{j}]}. Same notes for \var{i} and \var{j} as for \method{__getslice__()}. ! This method is deprecated. If no \method{__delslice__()} is found, ! or for extended slicing of the form ! \code{\var{self}[\var{i}:\var{j}:\var{k}]}, a ! slice object is created, and passed to \method{__delitem__()}, ! instead of \method{__delslice__()} being called. \end{methoddesc} *************** *** 1342,1347 **** \end{verbatim} ! Note the calls to \function{max()}; these are actually necessary due ! to the handling of negative indices before the \method{__*slice__()} methods are called. When negative indexes are used, the \method{__*item__()} methods receive them as provided, but --- 1377,1382 ---- \end{verbatim} ! Note the calls to \function{max()}; these are necessary because of ! the handling of negative indices before the \method{__*slice__()} methods are called. When negative indexes are used, the \method{__*item__()} methods receive them as provided, but Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.47.4.6 retrieving revision 1.47.4.7 diff -C2 -d -r1.47.4.6 -r1.47.4.7 *** ref6.tex 7 Dec 2002 15:59:37 -0000 1.47.4.6 --- ref6.tex 19 Jan 2003 14:54:08 -0000 1.47.4.7 *************** *** 639,645 **** \indexii{name}{binding} \kwindex{from} - % XXX Need to define what ``initialize'' means here ! The system maintains a table of modules that have been initialized, indexed by module name. This table is accessible as \code{sys.modules}. When a module name is found in --- 639,651 ---- \indexii{name}{binding} \kwindex{from} ! In this context, to ``initialize'' a built-in or extension module means to ! call an initialization function that the module must provide for the purpose ! (in the reference implementation, the function's name is obtained by ! prepending string ``init'' to the module's name); to ``initialize'' a ! Python-coded module means to execute the module's body. ! ! The system maintains a table of modules that have been or are being ! initialized, indexed by module name. This table is accessible as \code{sys.modules}. When a module name is found in From rhettinger@users.sourceforge.net Sun Jan 19 14:57:14 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 19 Jan 2003 06:57:14 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref3.tex,1.97,1.98 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv7890 Modified Files: ref3.tex Log Message: Fix typo Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -d -r1.97 -r1.98 *** ref3.tex 19 Jan 2003 13:08:18 -0000 1.97 --- ref3.tex 19 Jan 2003 14:57:12 -0000 1.98 *************** *** 1217,1221 **** \method{items()}, \method{has_key()}, \method{get()}, \method{clear()}, \method{setdefault()}, \method{iterkeys()}, \method{itervalues()}, ! \method{iteritems()}, \method{pop()},, \method{popitem()}, \method{copy()}, and \method{update()} behaving similar to those for Python's standard dictionary objects. The \module{UserDict} module --- 1217,1221 ---- \method{items()}, \method{has_key()}, \method{get()}, \method{clear()}, \method{setdefault()}, \method{iterkeys()}, \method{itervalues()}, ! \method{iteritems()}, \method{pop()}, \method{popitem()}, \method{copy()}, and \method{update()} behaving similar to those for Python's standard dictionary objects. The \module{UserDict} module From nnorwitz@users.sourceforge.net Sun Jan 19 15:40:12 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 19 Jan 2003 07:40:12 -0800 Subject: [Python-checkins] python/dist/src/Modules pyexpat.c,2.76,2.77 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv26544/Modules Modified Files: pyexpat.c Log Message: SF # 669553, fix memory (ref) leaks Will backport. Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.76 retrieving revision 2.77 diff -C2 -d -r2.76 -r2.77 *** pyexpat.c 8 Nov 2002 12:53:10 -0000 2.76 --- pyexpat.c 19 Jan 2003 15:40:09 -0000 2.77 *************** *** 1333,1354 **** } if (strcmp(name, "__members__") == 0) { int i; PyObject *rc = PyList_New(0); for (i = 0; handler_info[i].name != NULL; i++) { ! PyList_Append(rc, get_handler_name(&handler_info[i])); } ! PyList_Append(rc, PyString_FromString("ErrorCode")); ! PyList_Append(rc, PyString_FromString("ErrorLineNumber")); ! PyList_Append(rc, PyString_FromString("ErrorColumnNumber")); ! PyList_Append(rc, PyString_FromString("ErrorByteIndex")); ! PyList_Append(rc, PyString_FromString("buffer_size")); ! PyList_Append(rc, PyString_FromString("buffer_text")); ! PyList_Append(rc, PyString_FromString("buffer_used")); ! PyList_Append(rc, PyString_FromString("ordered_attributes")); ! PyList_Append(rc, PyString_FromString("returns_unicode")); ! PyList_Append(rc, PyString_FromString("specified_attributes")); ! PyList_Append(rc, PyString_FromString("intern")); return rc; } --- 1333,1366 ---- } + #define APPEND(list, str) \ + do { \ + PyObject *o = PyString_FromString(str); \ + if (o != NULL) \ + PyList_Append(list, o); \ + Py_XDECREF(o); \ + } while (0) + if (strcmp(name, "__members__") == 0) { int i; PyObject *rc = PyList_New(0); for (i = 0; handler_info[i].name != NULL; i++) { ! PyObject *o = get_handler_name(&handler_info[i]); ! if (o != NULL) ! PyList_Append(rc, o); ! Py_XDECREF(o); } ! APPEND(rc, "ErrorCode"); ! APPEND(rc, "ErrorLineNumber"); ! APPEND(rc, "ErrorColumnNumber"); ! APPEND(rc, "ErrorByteIndex"); ! APPEND(rc, "buffer_size"); ! APPEND(rc, "buffer_text"); ! APPEND(rc, "buffer_used"); ! APPEND(rc, "ordered_attributes"); ! APPEND(rc, "returns_unicode"); ! APPEND(rc, "specified_attributes"); ! APPEND(rc, "intern"); + #undef APPEND return rc; } From nnorwitz@users.sourceforge.net Sun Jan 19 15:40:11 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 19 Jan 2003 07:40:11 -0800 Subject: [Python-checkins] python/dist/src/Objects intobject.c,2.98,2.99 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv26544/Objects Modified Files: intobject.c Log Message: SF # 669553, fix memory (ref) leaks Will backport. Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.98 retrieving revision 2.99 diff -C2 -d -r2.98 -r2.99 *** intobject.c 31 Dec 2002 03:42:13 -0000 2.98 --- intobject.c 19 Jan 2003 15:40:09 -0000 2.99 *************** *** 607,613 **** x = -a; if (a < 0 && x < 0) { if (err_ovf("integer negation")) return NULL; ! return PyNumber_Negative(PyLong_FromLong(a)); } return PyInt_FromLong(x); --- 607,620 ---- x = -a; if (a < 0 && x < 0) { + PyObject *o; if (err_ovf("integer negation")) return NULL; ! o = PyLong_FromLong(a); ! if (o != NULL) { ! PyObject *result = PyNumber_Negative(o); ! Py_DECREF(o); ! return result; ! } ! return NULL; } return PyInt_FromLong(x); From nnorwitz@users.sourceforge.net Sun Jan 19 15:48:40 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 19 Jan 2003 07:48:40 -0800 Subject: [Python-checkins] python/dist/src/Objects intobject.c,2.79.6.5,2.79.6.6 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv31004/Objects Modified Files: Tag: release22-maint intobject.c Log Message: Backport SF # 669553, fix memory (ref) leaks Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.79.6.5 retrieving revision 2.79.6.6 diff -C2 -d -r2.79.6.5 -r2.79.6.6 *** intobject.c 23 Sep 2002 21:02:33 -0000 2.79.6.5 --- intobject.c 19 Jan 2003 15:48:38 -0000 2.79.6.6 *************** *** 650,656 **** x = -a; if (a < 0 && x < 0) { if (err_ovf("integer negation")) return NULL; ! return PyNumber_Negative(PyLong_FromLong(a)); } return PyInt_FromLong(x); --- 650,663 ---- x = -a; if (a < 0 && x < 0) { + PyObject *o; if (err_ovf("integer negation")) return NULL; ! o = PyLong_FromLong(a); ! if (o != NULL) { ! PyObject *result = PyNumber_Negative(o); ! Py_DECREF(o); ! return result; ! } ! return NULL; } return PyInt_FromLong(x); From nnorwitz@users.sourceforge.net Sun Jan 19 15:48:41 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 19 Jan 2003 07:48:41 -0800 Subject: [Python-checkins] python/dist/src/Modules pyexpat.c,2.57.6.4,2.57.6.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv31004/Modules Modified Files: Tag: release22-maint pyexpat.c Log Message: Backport SF # 669553, fix memory (ref) leaks Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.57.6.4 retrieving revision 2.57.6.5 diff -C2 -d -r2.57.6.4 -r2.57.6.5 *** pyexpat.c 7 Oct 2002 09:47:20 -0000 2.57.6.4 --- pyexpat.c 19 Jan 2003 15:48:38 -0000 2.57.6.5 *************** *** 1313,1330 **** return self->handlers[handlernum]; } if (strcmp(name, "__members__") == 0) { int i; PyObject *rc = PyList_New(0); ! for(i = 0; handler_info[i].name != NULL; i++) { ! PyList_Append(rc, PyString_FromString(handler_info[i].name)); } ! PyList_Append(rc, PyString_FromString("ErrorCode")); ! PyList_Append(rc, PyString_FromString("ErrorLineNumber")); ! PyList_Append(rc, PyString_FromString("ErrorColumnNumber")); ! PyList_Append(rc, PyString_FromString("ErrorByteIndex")); ! PyList_Append(rc, PyString_FromString("ordered_attributes")); ! PyList_Append(rc, PyString_FromString("returns_unicode")); ! PyList_Append(rc, PyString_FromString("specified_attributes")); return rc; } --- 1313,1340 ---- return self->handlers[handlernum]; } + + #define APPEND(list, str) \ + do { \ + PyObject *o = PyString_FromString(str); \ + if (o != NULL) \ + PyList_Append(list, o); \ + Py_XDECREF(o); \ + } while (0) + if (strcmp(name, "__members__") == 0) { int i; PyObject *rc = PyList_New(0); ! for (i = 0; handler_info[i].name != NULL; i++) { ! APPEND(rc, handler_info[i].name); } ! APPEND(rc, "ErrorCode"); ! APPEND(rc, "ErrorLineNumber"); ! APPEND(rc, "ErrorColumnNumber"); ! APPEND(rc, "ErrorByteIndex"); ! APPEND(rc, "ordered_attributes"); ! APPEND(rc, "returns_unicode"); ! APPEND(rc, "specified_attributes"); + #undef APPEND return rc; } From doerwalter@users.sourceforge.net Sun Jan 19 16:24:02 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 19 Jan 2003 08:24:02 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_builtin.py,1.2,1.3 test_b1.py,1.58,NONE test_b2.py,1.38,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv16923/Lib/test Modified Files: test_builtin.py Removed Files: test_b1.py test_b2.py Log Message: Combine test_b1.py and test_b2.py into test_builtin.py, port the tests to PyUnit and add many tests for error cases. This increases code coverage in Python/bltinmodule.c from 75% to 92%. (From SF patch #662807, with assert_(not fcmp(x, y)) replaced with assertAlmostEqual(x, y) where possible) Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_builtin.py 30 Jul 2002 23:26:01 -0000 1.2 --- test_builtin.py 19 Jan 2003 16:23:58 -0000 1.3 *************** *** 1,13 **** ! # Python test set -- part 4, built-in functions ! from test.test_support import unload ! print '4. Built-in functions' ! print 'test_b1' ! unload('test_b1') ! from test import test_b1 [...1063 lines suppressed...] ! self.assertEqual( ! zip(SequenceWithoutALength(), xrange(2**30)), ! list(enumerate(range(5))) ! ) ! ! class BadSeq: ! def __getitem__(self, i): ! if i == 5: ! raise ValueError ! else: ! return i ! self.assertRaises(ValueError, zip, BadSeq(), BadSeq()) ! ! def test_main(): ! suite = unittest.TestSuite() ! suite.addTest(unittest.makeSuite(BuiltinTest)) ! test.test_support.run_suite(suite) ! ! if __name__ == "__main__": ! test_main() --- test_b1.py DELETED --- --- test_b2.py DELETED --- From doerwalter@users.sourceforge.net Sun Jan 19 16:24:01 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 19 Jan 2003 08:24:01 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_builtin,1.7,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv16923/Lib/test/output Removed Files: test_builtin Log Message: Combine test_b1.py and test_b2.py into test_builtin.py, port the tests to PyUnit and add many tests for error cases. This increases code coverage in Python/bltinmodule.c from 75% to 92%. (From SF patch #662807, with assert_(not fcmp(x, y)) replaced with assertAlmostEqual(x, y) where possible) --- test_builtin DELETED --- From doerwalter@users.sourceforge.net Sun Jan 19 16:59:23 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 19 Jan 2003 08:59:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_unicode,1.14,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv32572/Lib/test/output Removed Files: test_unicode Log Message: Port test_unicode.py to PyUnit and add tests for error cases and a few methods. This increases code coverage in Objects/unicodeobject.c from 81% to 85%. (From SF patch #662807) --- test_unicode DELETED --- From doerwalter@users.sourceforge.net Sun Jan 19 16:59:24 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 19 Jan 2003 08:59:24 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_unicode.py,1.75,1.76 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv32572/Lib/test Modified Files: test_unicode.py Log Message: Port test_unicode.py to PyUnit and add tests for error cases and a few methods. This increases code coverage in Objects/unicodeobject.c from 81% to 85%. (From SF patch #662807) Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -d -r1.75 -r1.76 *** test_unicode.py 8 Jan 2003 23:02:34 -0000 1.75 --- test_unicode.py 19 Jan 2003 16:59:20 -0000 1.76 *************** *** 7,58 **** """#" ! from test.test_support import verify, vereq, verbose, TestFailed ! import sys, string ! if not sys.platform.startswith('java'): ! # Test basic sanity of repr() ! verify(repr(u'abc') == "u'abc'") ! verify(repr(u'ab\\c') == "u'ab\\\\c'") ! verify(repr(u'ab\\') == "u'ab\\\\'") [...1882 lines suppressed...] ! ! def test_slice(self): ! self.checkmethod('__getslice__', u'abc', u'abc', 0, 1000) ! self.checkmethod('__getslice__', u'abc', u'abc', 0, 3) ! self.checkmethod('__getslice__', u'abc', u'ab', 0, 2) ! self.checkmethod('__getslice__', u'abc', u'bc', 1, 3) ! self.checkmethod('__getslice__', u'abc', u'b', 1, 2) ! self.checkmethod('__getslice__', u'abc', u'', 2, 2) ! self.checkmethod('__getslice__', u'abc', u'', 1000, 1000) ! self.checkmethod('__getslice__', u'abc', u'', 2000, 1000) ! self.checkmethod('__getslice__', u'abc', u'', 2, 1) ! # FIXME What about negative indizes? This is handled differently by [] and __getslice__ ! ! def test_main(): ! suite = unittest.TestSuite() ! suite.addTest(unittest.makeSuite(UnicodeTest)) ! test.test_support.run_suite(suite) ! ! if __name__ == "__main__": ! test_main() From jackjansen@users.sourceforge.net Sun Jan 19 21:54:03 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 19 Jan 2003 13:54:03 -0800 Subject: [Python-checkins] python/dist/src/Tools/bgen/bgen bgenBuffer.py,1.7,1.8 bgenGenerator.py,1.14,1.15 bgenGeneratorGroup.py,1.6,1.7 bgenHeapBuffer.py,1.3,1.4 bgenModule.py,1.11,1.12 bgenObjectDefinition.py,1.24,1.25 bgenOutput.py,1.4,1.5 bgenStackBuffer.py,1.2,1.3 bgenStringBuffer.py,1.1,1.2 bgenType.py,1.9,1.10 bgenVariable.py,1.1,1.2 macsupport.py,1.28,1.29 scantools.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory sc8-pr-cvs1:/tmp/cvs-serv6862 Modified Files: bgenBuffer.py bgenGenerator.py bgenGeneratorGroup.py bgenHeapBuffer.py bgenModule.py bgenObjectDefinition.py bgenOutput.py bgenStackBuffer.py bgenStringBuffer.py bgenType.py bgenVariable.py macsupport.py scantools.py Log Message: Sigh, due to sloppiness on my part bgen has become pretty mixed up wrt. tabs and spaces. Detabbed the lot. Index: bgenBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenBuffer.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** bgenBuffer.py 1 Jan 2002 22:40:08 -0000 1.7 --- bgenBuffer.py 19 Jan 2003 21:53:55 -0000 1.8 *************** *** 13,24 **** # Map common types to their format characters type2format = { ! 'long': 'l', ! 'int': 'i', ! 'short': 'h', ! 'char': 'b', ! 'unsigned long': 'l', ! 'unsigned int': 'i', ! 'unsigned short': 'h', ! 'unsigned char': 'b', } --- 13,24 ---- # Map common types to their format characters type2format = { ! 'long': 'l', ! 'int': 'i', ! 'short': 'h', ! 'char': 'b', ! 'unsigned long': 'l', ! 'unsigned int': 'i', ! 'unsigned short': 'h', ! 'unsigned char': 'b', } *************** *** 28,264 **** class FixedInputOutputBufferType(InputOnlyType): ! ! """Fixed buffer -- passed as (inbuffer, outbuffer).""" ! def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None): ! self.typeName = "Buffer" ! self.size = str(size) ! self.datatype = datatype ! self.sizetype = sizetype ! self.sizeformat = sizeformat or type2format[sizetype] ! self.label_needed = 0 ! def declare(self, name): ! self.declareBuffer(name) ! self.declareSize(name) ! ! def declareBuffer(self, name): ! self.declareInputBuffer(name) ! self.declareOutputBuffer(name) ! ! def declareInputBuffer(self, name): ! Output("%s *%s__in__;", self.datatype, name) ! ! def declareOutputBuffer(self, name): ! Output("%s %s__out__[%s];", self.datatype, name, self.size) ! def declareSize(self, name): ! Output("%s %s__len__;", self.sizetype, name) ! Output("int %s__in_len__;", name) ! def getargsFormat(self): ! return "s#" ! def getargsArgs(self, name): ! return "&%s__in__, &%s__in_len__" % (name, name) ! ! def getargsCheck(self, name): ! Output("if (%s__in_len__ != %s)", name, self.size) ! OutLbrace() ! Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");', ! self.size) ! Output("goto %s__error__;", name) ! self.label_needed = 1 ! OutRbrace() ! self.transferSize(name) ! ! def transferSize(self, name): ! Output("%s__len__ = %s__in_len__;", name, name) ! def passOutput(self, name): ! return "%s__in__, %s__out__" % (name, name) ! ! def mkvalueFormat(self): ! return "s#" ! def mkvalueArgs(self, name): ! return "%s__out__, (int)%s" % (name, self.size) ! ! def cleanup(self, name): ! if self.label_needed: ! DedentLevel() ! Output(" %s__error__: ;", name) ! IndentLevel() class FixedCombinedInputOutputBufferType(FixedInputOutputBufferType): ! ! """Like fixed buffer -- but same parameter is input and output.""" ! ! def passOutput(self, name): ! return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \ ! (self.datatype, name, name, self.size) class InputOnlyBufferMixIn(InputOnlyMixIn): ! def declareOutputBuffer(self, name): ! pass class OutputOnlyBufferMixIn(OutputOnlyMixIn): ! def declareInputBuffer(self, name): ! pass class OptionalInputBufferMixIn: ! ! """Add to input buffers if the buffer may be omitted: pass None in Python ! and the C code will get a NULL pointer and zero size""" ! ! def getargsFormat(self): ! return "z#" class FixedInputBufferType(InputOnlyBufferMixIn, FixedInputOutputBufferType): ! """Fixed size input buffer -- passed without size information. ! Instantiate with the size as parameter. ! """ ! def passInput(self, name): ! return "%s__in__" % name class OptionalFixedInputBufferType(OptionalInputBufferMixIn, FixedInputBufferType): ! pass class FixedOutputBufferType(OutputOnlyBufferMixIn, FixedInputOutputBufferType): ! """Fixed size output buffer -- passed without size information. ! Instantiate with the size as parameter. ! """ ! def passOutput(self, name): ! return "%s__out__" % name class VarInputBufferType(FixedInputBufferType): ! """Variable size input buffer -- passed as (buffer, size). ! ! Instantiate without size parameter. ! """ ! ! def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): ! FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) ! ! def getargsCheck(self, name): ! Output("%s__len__ = %s__in_len__;", name, name) ! ! def passInput(self, name): ! return "%s__in__, %s__len__" % (name, name) ! class ReverseInputBufferMixin: ! """ Mixin for input buffers that are passed as (size, buffer) """ ! ! def passInput(self, name): ! return "%s__len__, %s__in__" % (name, name) ! class OptionalVarInputBufferType(OptionalInputBufferMixIn, VarInputBufferType): ! pass ! # ----- PART 2: Structure buffers ----- class StructInputOutputBufferType(FixedInputOutputBufferType): ! ! """Structure buffer -- passed as a structure pointer. ! Instantiate with the struct type as parameter. ! """ ! ! def __init__(self, type): ! FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type) ! self.typeName = self.type = type ! ! def declareInputBuffer(self, name): ! Output("%s *%s__in__;", self.type, name) ! ! def declareSize(self, name): ! Output("int %s__in_len__;", name) ! ! def declareOutputBuffer(self, name): ! Output("%s %s__out__;", self.type, name) ! ! def getargsArgs(self, name): ! return "(char **)&%s__in__, &%s__in_len__" % (name, name) ! ! def transferSize(self, name): ! pass ! ! def passInput(self, name): ! return "%s__in__" % name ! ! def passOutput(self, name): ! return "%s__in__, &%s__out__" % (name, name) ! ! def mkvalueArgs(self, name): ! return "(char *)&%s__out__, (int)%s" % (name, self.size) class StructCombinedInputOutputBufferType(StructInputOutputBufferType): ! """Like structure buffer -- but same parameter is input and output.""" ! ! def passOutput(self, name): ! return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \ ! (self.type, name, name, self.size) class StructInputBufferType(InputOnlyBufferMixIn, StructInputOutputBufferType): ! """Fixed size input buffer -- passed as a pointer to a structure. ! Instantiate with the struct type as parameter. ! """ class StructByValueBufferType(StructInputBufferType): ! """Fixed size input buffer -- passed as a structure BY VALUE. ! Instantiate with the struct type as parameter. ! """ ! def passInput(self, name): ! return "*%s__in__" % name class StructOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType): ! """Fixed size output buffer -- passed as a pointer to a structure. ! Instantiate with the struct type as parameter. ! """ ! ! def declareSize(self, name): ! pass ! def passOutput(self, name): ! return "&%s__out__" % name class ArrayOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType): ! """Fixed size output buffer -- declared as a typedef, passed as an array. ! Instantiate with the struct type as parameter. ! """ ! ! def declareSize(self, name): ! pass ! def passOutput(self, name): ! return "%s__out__" % name --- 28,264 ---- class FixedInputOutputBufferType(InputOnlyType): ! ! """Fixed buffer -- passed as (inbuffer, outbuffer).""" ! def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None): ! self.typeName = "Buffer" ! self.size = str(size) ! self.datatype = datatype ! self.sizetype = sizetype ! self.sizeformat = sizeformat or type2format[sizetype] ! self.label_needed = 0 ! def declare(self, name): ! self.declareBuffer(name) ! self.declareSize(name) ! ! def declareBuffer(self, name): ! self.declareInputBuffer(name) ! self.declareOutputBuffer(name) ! ! def declareInputBuffer(self, name): ! Output("%s *%s__in__;", self.datatype, name) ! ! def declareOutputBuffer(self, name): ! Output("%s %s__out__[%s];", self.datatype, name, self.size) ! def declareSize(self, name): ! Output("%s %s__len__;", self.sizetype, name) ! Output("int %s__in_len__;", name) ! def getargsFormat(self): ! return "s#" ! def getargsArgs(self, name): ! return "&%s__in__, &%s__in_len__" % (name, name) ! ! def getargsCheck(self, name): ! Output("if (%s__in_len__ != %s)", name, self.size) ! OutLbrace() ! Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");', ! self.size) ! Output("goto %s__error__;", name) ! self.label_needed = 1 ! OutRbrace() ! self.transferSize(name) ! ! def transferSize(self, name): ! Output("%s__len__ = %s__in_len__;", name, name) ! def passOutput(self, name): ! return "%s__in__, %s__out__" % (name, name) ! ! def mkvalueFormat(self): ! return "s#" ! def mkvalueArgs(self, name): ! return "%s__out__, (int)%s" % (name, self.size) ! ! def cleanup(self, name): ! if self.label_needed: ! DedentLevel() ! Output(" %s__error__: ;", name) ! IndentLevel() class FixedCombinedInputOutputBufferType(FixedInputOutputBufferType): ! ! """Like fixed buffer -- but same parameter is input and output.""" ! ! def passOutput(self, name): ! return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \ ! (self.datatype, name, name, self.size) class InputOnlyBufferMixIn(InputOnlyMixIn): ! def declareOutputBuffer(self, name): ! pass class OutputOnlyBufferMixIn(OutputOnlyMixIn): ! def declareInputBuffer(self, name): ! pass class OptionalInputBufferMixIn: ! ! """Add to input buffers if the buffer may be omitted: pass None in Python ! and the C code will get a NULL pointer and zero size""" ! ! def getargsFormat(self): ! return "z#" class FixedInputBufferType(InputOnlyBufferMixIn, FixedInputOutputBufferType): ! """Fixed size input buffer -- passed without size information. ! Instantiate with the size as parameter. ! """ ! def passInput(self, name): ! return "%s__in__" % name class OptionalFixedInputBufferType(OptionalInputBufferMixIn, FixedInputBufferType): ! pass class FixedOutputBufferType(OutputOnlyBufferMixIn, FixedInputOutputBufferType): ! """Fixed size output buffer -- passed without size information. ! Instantiate with the size as parameter. ! """ ! def passOutput(self, name): ! return "%s__out__" % name class VarInputBufferType(FixedInputBufferType): ! """Variable size input buffer -- passed as (buffer, size). ! ! Instantiate without size parameter. ! """ ! ! def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): ! FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) ! ! def getargsCheck(self, name): ! Output("%s__len__ = %s__in_len__;", name, name) ! ! def passInput(self, name): ! return "%s__in__, %s__len__" % (name, name) ! class ReverseInputBufferMixin: ! """ Mixin for input buffers that are passed as (size, buffer) """ ! ! def passInput(self, name): ! return "%s__len__, %s__in__" % (name, name) ! class OptionalVarInputBufferType(OptionalInputBufferMixIn, VarInputBufferType): ! pass ! # ----- PART 2: Structure buffers ----- class StructInputOutputBufferType(FixedInputOutputBufferType): ! ! """Structure buffer -- passed as a structure pointer. ! Instantiate with the struct type as parameter. ! """ ! ! def __init__(self, type): ! FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type) ! self.typeName = self.type = type ! ! def declareInputBuffer(self, name): ! Output("%s *%s__in__;", self.type, name) ! ! def declareSize(self, name): ! Output("int %s__in_len__;", name) ! ! def declareOutputBuffer(self, name): ! Output("%s %s__out__;", self.type, name) ! ! def getargsArgs(self, name): ! return "(char **)&%s__in__, &%s__in_len__" % (name, name) ! ! def transferSize(self, name): ! pass ! ! def passInput(self, name): ! return "%s__in__" % name ! ! def passOutput(self, name): ! return "%s__in__, &%s__out__" % (name, name) ! ! def mkvalueArgs(self, name): ! return "(char *)&%s__out__, (int)%s" % (name, self.size) class StructCombinedInputOutputBufferType(StructInputOutputBufferType): ! """Like structure buffer -- but same parameter is input and output.""" ! ! def passOutput(self, name): ! return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \ ! (self.type, name, name, self.size) class StructInputBufferType(InputOnlyBufferMixIn, StructInputOutputBufferType): ! """Fixed size input buffer -- passed as a pointer to a structure. ! Instantiate with the struct type as parameter. ! """ class StructByValueBufferType(StructInputBufferType): ! """Fixed size input buffer -- passed as a structure BY VALUE. ! Instantiate with the struct type as parameter. ! """ ! def passInput(self, name): ! return "*%s__in__" % name class StructOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType): ! """Fixed size output buffer -- passed as a pointer to a structure. ! Instantiate with the struct type as parameter. ! """ ! ! def declareSize(self, name): ! pass ! def passOutput(self, name): ! return "&%s__out__" % name class ArrayOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType): ! """Fixed size output buffer -- declared as a typedef, passed as an array. ! Instantiate with the struct type as parameter. ! """ ! ! def declareSize(self, name): ! pass ! def passOutput(self, name): ! return "%s__out__" % name Index: bgenGenerator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenGenerator.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** bgenGenerator.py 11 Sep 2002 20:36:00 -0000 1.14 --- bgenGenerator.py 19 Jan 2003 21:53:56 -0000 1.15 *************** *** 16,274 **** class BaseFunctionGenerator: ! def __init__(self, name, condition=None): ! if DEBUG: print "<--", name ! self.name = name ! self.prefix = name ! self.objecttype = "PyObject" # Type of _self argument to function ! self.condition = condition ! def setprefix(self, prefix): ! self.prefix = prefix ! def generate(self): ! if DEBUG: print "-->", self.name ! if self.condition: ! Output() ! Output(self.condition) ! self.functionheader() ! self.functionbody() ! self.functiontrailer() ! if self.condition: ! Output("#endif") ! def functionheader(self): ! Output() ! Output("static PyObject *%s_%s(%s *_self, PyObject *_args)", ! self.prefix, self.name, self.objecttype) ! OutLbrace() ! Output("PyObject *_res = NULL;") ! def functionbody(self): ! Output("/* XXX To be provided */") ! def functiontrailer(self): ! OutRbrace() ! def reference(self, name = None): ! if name is None: ! name = self.name ! docstring = self.docstring() ! if self.condition: ! Output() ! Output(self.condition) ! Output("{\"%s\", (PyCFunction)%s_%s, 1,", name, self.prefix, self.name) ! Output(" PyDoc_STR(%s)},", stringify(docstring)) ! if self.condition: ! Output("#endif") ! def docstring(self): ! return None ! def __cmp__(self, other): ! if not hasattr(other, 'name'): ! return cmp(id(self), id(other)) ! return cmp(self.name, other.name) _stringify_map = {'\n': '\\n', '\t': '\\t', '\r': '\\r', '\b': '\\b', '\e': '\\e', '\a': '\\a', '\f': '\\f', '"': '\\"'} def stringify(str): ! if str is None: return "NULL" ! res = '"' ! map = _stringify_map ! for c in str: ! if map.has_key(c): res = res + map[c] ! elif ' ' <= c <= '~': res = res + c ! else: res = res + '\\%03o' % ord(c) ! res = res + '"' ! return res class ManualGenerator(BaseFunctionGenerator): ! def __init__(self, name, body, condition=None): ! BaseFunctionGenerator.__init__(self, name, condition=condition) ! self.body = body ! def functionbody(self): ! Output("%s", self.body) ! ! def setselftype(self, selftype, itselftype): ! self.objecttype = selftype ! self.itselftype = itselftype class FunctionGenerator(BaseFunctionGenerator): ! def __init__(self, returntype, name, *argumentList, **conditionlist): ! BaseFunctionGenerator.__init__(self, name, **conditionlist) ! self.returntype = returntype ! self.argumentList = [] ! self.setreturnvar() ! self.parseArgumentList(argumentList) ! self.prefix = "XXX" # Will be changed by setprefix() call ! self.itselftype = None # Type of _self->ob_itself, if defined ! def setreturnvar(self): ! if self.returntype: ! self.rv = self.makereturnvar() ! self.argumentList.append(self.rv) ! else: ! self.rv = None ! ! def makereturnvar(self): ! return Variable(self.returntype, "_rv", OutMode) ! def setselftype(self, selftype, itselftype): ! self.objecttype = selftype ! self.itselftype = itselftype ! def parseArgumentList(self, argumentList): ! iarg = 0 ! for type, name, mode in argumentList: ! iarg = iarg + 1 ! if name is None: name = "_arg%d" % iarg ! arg = Variable(type, name, mode) ! self.argumentList.append(arg) ! ! def docstring(self): ! input = [] ! output = [] ! for arg in self.argumentList: ! if arg.flags == ErrorMode or arg.flags == SelfMode: ! continue ! if arg.type == None: ! str = 'void' ! else: ! if hasattr(arg.type, 'typeName'): ! typeName = arg.type.typeName ! if typeName is None: # Suppressed type ! continue ! else: ! typeName = "?" ! print "Nameless type", arg.type ! ! str = typeName + ' ' + arg.name ! if arg.mode in (InMode, InOutMode): ! input.append(str) ! if arg.mode in (InOutMode, OutMode): ! output.append(str) ! if not input: ! instr = "()" ! else: ! instr = "(%s)" % ", ".join(input) ! if not output or output == ["void"]: ! outstr = "None" ! else: ! outstr = "(%s)" % ", ".join(output) ! return instr + " -> " + outstr ! ! def functionbody(self): ! self.declarations() ! self.precheck() ! self.getargs() ! self.callit() ! self.checkit() ! self.returnvalue() ! def declarations(self): ! for arg in self.argumentList: ! arg.declare() ! def getargs(self): ! fmt = "" ! lst = "" ! sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(") ! for arg in self.argumentList: ! if arg.flags == SelfMode: ! continue ! if arg.mode in (InMode, InOutMode): ! fmt = fmt + arg.getargsFormat() ! args = arg.getargsArgs() ! if args: ! lst = lst + sep + args ! Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst) ! IndentLevel() ! Output("return NULL;") ! DedentLevel() ! for arg in self.argumentList: ! if arg.flags == SelfMode: ! continue ! if arg.mode in (InMode, InOutMode): ! arg.getargsCheck() ! ! def precheck(self): ! pass ! def callit(self): ! args = "" ! if self.rv: ! s = "%s = %s(" % (self.rv.name, self.name) ! else: ! s = "%s(" % self.name ! sep = ",\n" + ' '*len(s) ! for arg in self.argumentList: ! if arg is self.rv: ! continue ! s = arg.passArgument() ! if args: s = sep + s ! args = args + s ! if self.rv: ! Output("%s = %s(%s);", ! self.rv.name, self.name, args) ! else: ! Output("%s(%s);", self.name, args) ! def checkit(self): ! for arg in self.argumentList: ! arg.errorCheck() ! def returnvalue(self): ! fmt = "" ! lst = "" ! sep = ",\n" + ' '*len("return Py_BuildValue(") ! for arg in self.argumentList: ! if not arg: continue ! if arg.flags == ErrorMode: continue ! if arg.mode in (OutMode, InOutMode): ! fmt = fmt + arg.mkvalueFormat() ! lst = lst + sep + arg.mkvalueArgs() ! if fmt == "": ! Output("Py_INCREF(Py_None);") ! Output("_res = Py_None;"); ! else: ! Output("_res = Py_BuildValue(\"%s\"%s);", fmt, lst) ! tmp = self.argumentList[:] ! tmp.reverse() ! for arg in tmp: ! if not arg: continue ! arg.cleanup() ! Output("return _res;") class MethodGenerator(FunctionGenerator): ! def parseArgumentList(self, args): ! a0, args = args[0], args[1:] ! t0, n0, m0 = a0 ! if m0 != InMode: ! raise ValueError, "method's 'self' must be 'InMode'" ! self.itself = Variable(t0, "_self->ob_itself", SelfMode) ! self.argumentList.append(self.itself) ! FunctionGenerator.parseArgumentList(self, args) def _test(): ! void = None ! eggs = FunctionGenerator(void, "eggs", ! (stringptr, 'cmd', InMode), ! (int, 'x', InMode), ! (double, 'y', InOutMode), ! (int, 'status', ErrorMode), ! ) ! eggs.setprefix("spam") ! print "/* START */" ! eggs.generate() if __name__ == "__main__": ! _test() --- 16,274 ---- class BaseFunctionGenerator: ! def __init__(self, name, condition=None): ! if DEBUG: print "<--", name ! self.name = name ! self.prefix = name ! self.objecttype = "PyObject" # Type of _self argument to function ! self.condition = condition ! def setprefix(self, prefix): ! self.prefix = prefix ! def generate(self): ! if DEBUG: print "-->", self.name ! if self.condition: ! Output() ! Output(self.condition) ! self.functionheader() ! self.functionbody() ! self.functiontrailer() ! if self.condition: ! Output("#endif") ! def functionheader(self): ! Output() ! Output("static PyObject *%s_%s(%s *_self, PyObject *_args)", ! self.prefix, self.name, self.objecttype) ! OutLbrace() ! Output("PyObject *_res = NULL;") ! def functionbody(self): ! Output("/* XXX To be provided */") ! def functiontrailer(self): ! OutRbrace() ! def reference(self, name = None): ! if name is None: ! name = self.name ! docstring = self.docstring() ! if self.condition: ! Output() ! Output(self.condition) ! Output("{\"%s\", (PyCFunction)%s_%s, 1,", name, self.prefix, self.name) ! Output(" PyDoc_STR(%s)},", stringify(docstring)) ! if self.condition: ! Output("#endif") ! def docstring(self): ! return None ! def __cmp__(self, other): ! if not hasattr(other, 'name'): ! return cmp(id(self), id(other)) ! return cmp(self.name, other.name) _stringify_map = {'\n': '\\n', '\t': '\\t', '\r': '\\r', '\b': '\\b', '\e': '\\e', '\a': '\\a', '\f': '\\f', '"': '\\"'} def stringify(str): ! if str is None: return "NULL" ! res = '"' ! map = _stringify_map ! for c in str: ! if map.has_key(c): res = res + map[c] ! elif ' ' <= c <= '~': res = res + c ! else: res = res + '\\%03o' % ord(c) ! res = res + '"' ! return res class ManualGenerator(BaseFunctionGenerator): ! def __init__(self, name, body, condition=None): ! BaseFunctionGenerator.__init__(self, name, condition=condition) ! self.body = body ! def functionbody(self): ! Output("%s", self.body) ! ! def setselftype(self, selftype, itselftype): ! self.objecttype = selftype ! self.itselftype = itselftype class FunctionGenerator(BaseFunctionGenerator): ! def __init__(self, returntype, name, *argumentList, **conditionlist): ! BaseFunctionGenerator.__init__(self, name, **conditionlist) ! self.returntype = returntype ! self.argumentList = [] ! self.setreturnvar() ! self.parseArgumentList(argumentList) ! self.prefix = "XXX" # Will be changed by setprefix() call ! self.itselftype = None # Type of _self->ob_itself, if defined ! def setreturnvar(self): ! if self.returntype: ! self.rv = self.makereturnvar() ! self.argumentList.append(self.rv) ! else: ! self.rv = None ! ! def makereturnvar(self): ! return Variable(self.returntype, "_rv", OutMode) ! def setselftype(self, selftype, itselftype): ! self.objecttype = selftype ! self.itselftype = itselftype ! def parseArgumentList(self, argumentList): ! iarg = 0 ! for type, name, mode in argumentList: ! iarg = iarg + 1 ! if name is None: name = "_arg%d" % iarg ! arg = Variable(type, name, mode) ! self.argumentList.append(arg) ! ! def docstring(self): ! input = [] ! output = [] ! for arg in self.argumentList: ! if arg.flags == ErrorMode or arg.flags == SelfMode: ! continue ! if arg.type == None: ! str = 'void' ! else: ! if hasattr(arg.type, 'typeName'): ! typeName = arg.type.typeName ! if typeName is None: # Suppressed type ! continue ! else: ! typeName = "?" ! print "Nameless type", arg.type ! ! str = typeName + ' ' + arg.name ! if arg.mode in (InMode, InOutMode): ! input.append(str) ! if arg.mode in (InOutMode, OutMode): ! output.append(str) ! if not input: ! instr = "()" ! else: ! instr = "(%s)" % ", ".join(input) ! if not output or output == ["void"]: ! outstr = "None" ! else: ! outstr = "(%s)" % ", ".join(output) ! return instr + " -> " + outstr ! ! def functionbody(self): ! self.declarations() ! self.precheck() ! self.getargs() ! self.callit() ! self.checkit() ! self.returnvalue() ! def declarations(self): ! for arg in self.argumentList: ! arg.declare() ! def getargs(self): ! fmt = "" ! lst = "" ! sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(") ! for arg in self.argumentList: ! if arg.flags == SelfMode: ! continue ! if arg.mode in (InMode, InOutMode): ! fmt = fmt + arg.getargsFormat() ! args = arg.getargsArgs() ! if args: ! lst = lst + sep + args ! Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst) ! IndentLevel() ! Output("return NULL;") ! DedentLevel() ! for arg in self.argumentList: ! if arg.flags == SelfMode: ! continue ! if arg.mode in (InMode, InOutMode): ! arg.getargsCheck() ! ! def precheck(self): ! pass ! def callit(self): ! args = "" ! if self.rv: ! s = "%s = %s(" % (self.rv.name, self.name) ! else: ! s = "%s(" % self.name ! sep = ",\n" + ' '*len(s) ! for arg in self.argumentList: ! if arg is self.rv: ! continue ! s = arg.passArgument() ! if args: s = sep + s ! args = args + s ! if self.rv: ! Output("%s = %s(%s);", ! self.rv.name, self.name, args) ! else: ! Output("%s(%s);", self.name, args) ! def checkit(self): ! for arg in self.argumentList: ! arg.errorCheck() ! def returnvalue(self): ! fmt = "" ! lst = "" ! sep = ",\n" + ' '*len("return Py_BuildValue(") ! for arg in self.argumentList: ! if not arg: continue ! if arg.flags == ErrorMode: continue ! if arg.mode in (OutMode, InOutMode): ! fmt = fmt + arg.mkvalueFormat() ! lst = lst + sep + arg.mkvalueArgs() ! if fmt == "": ! Output("Py_INCREF(Py_None);") ! Output("_res = Py_None;"); ! else: ! Output("_res = Py_BuildValue(\"%s\"%s);", fmt, lst) ! tmp = self.argumentList[:] ! tmp.reverse() ! for arg in tmp: ! if not arg: continue ! arg.cleanup() ! Output("return _res;") class MethodGenerator(FunctionGenerator): ! def parseArgumentList(self, args): ! a0, args = args[0], args[1:] ! t0, n0, m0 = a0 ! if m0 != InMode: ! raise ValueError, "method's 'self' must be 'InMode'" ! self.itself = Variable(t0, "_self->ob_itself", SelfMode) ! self.argumentList.append(self.itself) ! FunctionGenerator.parseArgumentList(self, args) def _test(): ! void = None ! eggs = FunctionGenerator(void, "eggs", ! (stringptr, 'cmd', InMode), ! (int, 'x', InMode), ! (double, 'y', InOutMode), ! (int, 'status', ErrorMode), ! ) ! eggs.setprefix("spam") ! print "/* START */" ! eggs.generate() if __name__ == "__main__": ! _test() Index: bgenGeneratorGroup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenGeneratorGroup.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** bgenGeneratorGroup.py 27 Aug 2001 14:30:55 -0000 1.6 --- bgenGeneratorGroup.py 19 Jan 2003 21:53:56 -0000 1.7 *************** *** 3,40 **** class GeneratorGroup: ! def __init__(self, prefix): ! self.prefix = prefix ! self.generators = [] ! def add(self, g, dupcheck=0): ! if dupcheck: ! if g in self.generators: ! print 'DUP', g.name ! return ! g.setprefix(self.prefix) ! self.generators.append(g) ! def generate(self): ! for g in self.generators: ! g.generate() ! Output() ! Output("static PyMethodDef %s_methods[] = {", self.prefix) ! IndentLevel() ! for g in self.generators: ! g.reference() ! Output("{NULL, NULL, 0}") ! DedentLevel() ! Output("};") def _test(): ! void = None ! from bgenGenerator import FunctionGenerator ! group = GeneratorGroup("spam") ! eggs = FunctionGenerator(void, "eggs") ! group.add(eggs) ! print "/* START */" ! group.generate() if __name__ == "__main__": ! _test() --- 3,40 ---- class GeneratorGroup: ! def __init__(self, prefix): ! self.prefix = prefix ! self.generators = [] ! def add(self, g, dupcheck=0): ! if dupcheck: ! if g in self.generators: ! print 'DUP', g.name ! return ! g.setprefix(self.prefix) ! self.generators.append(g) ! def generate(self): ! for g in self.generators: ! g.generate() ! Output() ! Output("static PyMethodDef %s_methods[] = {", self.prefix) ! IndentLevel() ! for g in self.generators: ! g.reference() ! Output("{NULL, NULL, 0}") ! DedentLevel() ! Output("};") def _test(): ! void = None ! from bgenGenerator import FunctionGenerator ! group = GeneratorGroup("spam") ! eggs = FunctionGenerator(void, "eggs") ! group.add(eggs) ! print "/* START */" ! group.generate() if __name__ == "__main__": ! _test() Index: bgenHeapBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenHeapBuffer.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** bgenHeapBuffer.py 5 Sep 2001 10:27:53 -0000 1.3 --- bgenHeapBuffer.py 19 Jan 2003 21:53:56 -0000 1.4 *************** *** 8,111 **** class HeapInputOutputBufferType(FixedInputOutputBufferType): ! """Input-output buffer allocated on the heap -- passed as (inbuffer, outbuffer, size). ! Instantiate without parameters. ! Call from Python with input buffer. ! """ ! def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): ! FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) ! def declareOutputBuffer(self, name): ! Output("%s *%s__out__;", self.datatype, name) ! def getargsCheck(self, name): ! Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name) ! OutLbrace() ! Output('PyErr_NoMemory();') ! Output("goto %s__error__;", name) ! self.label_needed = 1 ! OutRbrace() ! Output("%s__len__ = %s__in_len__;", name, name) ! def passOutput(self, name): ! return "%s__in__, %s__out__, (%s)%s__len__" % \ ! (name, name, self.sizetype, name) ! def mkvalueArgs(self, name): ! return "%s__out__, (int)%s__len__" % (name, name) ! def cleanup(self, name): ! Output("free(%s__out__);", name) ! FixedInputOutputBufferType.cleanup(self, name) class VarHeapInputOutputBufferType(HeapInputOutputBufferType): ! """same as base class, but passed as (inbuffer, outbuffer, &size)""" ! ! def passOutput(self, name): ! return "%s__in__, %s__out__, &%s__len__" % (name, name, name) class HeapCombinedInputOutputBufferType(HeapInputOutputBufferType): ! """same as base class, but passed as (inoutbuffer, size)""" ! ! def passOutput(self, name): ! return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \ ! (self.datatype, name, name, name) class VarHeapCombinedInputOutputBufferType(HeapInputOutputBufferType): ! """same as base class, but passed as (inoutbuffer, &size)""" ! ! def passOutput(self, name): ! return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \ ! (self.datatype, name, name, name) class HeapOutputBufferType(OutputOnlyMixIn, HeapInputOutputBufferType): ! """Output buffer allocated on the heap -- passed as (buffer, size). ! Instantiate without parameters. ! Call from Python with buffer size. ! """ ! ! def declareInputBuffer(self, name): ! pass ! ! def getargsFormat(self): ! return "i" ! ! def getargsArgs(self, name): ! return "&%s__in_len__" % name ! ! def passOutput(self, name): ! return "%s__out__, %s__len__" % (name, name) class VarHeapOutputBufferType(HeapOutputBufferType): ! """Output buffer allocated on the heap -- passed as (buffer, &size). ! Instantiate without parameters. ! Call from Python with buffer size. ! """ ! def passOutput(self, name): ! return "%s__out__, &%s__len__" % (name, name) class VarVarHeapOutputBufferType(VarHeapOutputBufferType): ! """Output buffer allocated on the heap -- passed as (buffer, size, &size). ! Instantiate without parameters. ! Call from Python with buffer size. ! """ ! def passOutput(self, name): ! return "%s__out__, %s__len__, &%s__len__" % (name, name, name) --- 8,111 ---- class HeapInputOutputBufferType(FixedInputOutputBufferType): ! """Input-output buffer allocated on the heap -- passed as (inbuffer, outbuffer, size). ! Instantiate without parameters. ! Call from Python with input buffer. ! """ ! def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): ! FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) ! def declareOutputBuffer(self, name): ! Output("%s *%s__out__;", self.datatype, name) ! def getargsCheck(self, name): ! Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name) ! OutLbrace() ! Output('PyErr_NoMemory();') ! Output("goto %s__error__;", name) ! self.label_needed = 1 ! OutRbrace() ! Output("%s__len__ = %s__in_len__;", name, name) ! def passOutput(self, name): ! return "%s__in__, %s__out__, (%s)%s__len__" % \ ! (name, name, self.sizetype, name) ! def mkvalueArgs(self, name): ! return "%s__out__, (int)%s__len__" % (name, name) ! def cleanup(self, name): ! Output("free(%s__out__);", name) ! FixedInputOutputBufferType.cleanup(self, name) class VarHeapInputOutputBufferType(HeapInputOutputBufferType): ! """same as base class, but passed as (inbuffer, outbuffer, &size)""" ! ! def passOutput(self, name): ! return "%s__in__, %s__out__, &%s__len__" % (name, name, name) class HeapCombinedInputOutputBufferType(HeapInputOutputBufferType): ! """same as base class, but passed as (inoutbuffer, size)""" ! ! def passOutput(self, name): ! return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \ ! (self.datatype, name, name, name) class VarHeapCombinedInputOutputBufferType(HeapInputOutputBufferType): ! """same as base class, but passed as (inoutbuffer, &size)""" ! ! def passOutput(self, name): ! return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \ ! (self.datatype, name, name, name) class HeapOutputBufferType(OutputOnlyMixIn, HeapInputOutputBufferType): ! """Output buffer allocated on the heap -- passed as (buffer, size). ! Instantiate without parameters. ! Call from Python with buffer size. ! """ ! ! def declareInputBuffer(self, name): ! pass ! ! def getargsFormat(self): ! return "i" ! ! def getargsArgs(self, name): ! return "&%s__in_len__" % name ! ! def passOutput(self, name): ! return "%s__out__, %s__len__" % (name, name) class VarHeapOutputBufferType(HeapOutputBufferType): ! """Output buffer allocated on the heap -- passed as (buffer, &size). ! Instantiate without parameters. ! Call from Python with buffer size. ! """ ! def passOutput(self, name): ! return "%s__out__, &%s__len__" % (name, name) class VarVarHeapOutputBufferType(VarHeapOutputBufferType): ! """Output buffer allocated on the heap -- passed as (buffer, size, &size). ! Instantiate without parameters. ! Call from Python with buffer size. ! """ ! def passOutput(self, name): ! return "%s__out__, %s__len__, &%s__len__" % (name, name, name) Index: bgenModule.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenModule.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** bgenModule.py 17 Dec 2002 22:08:48 -0000 1.11 --- bgenModule.py 19 Jan 2003 21:53:56 -0000 1.12 *************** *** 4,94 **** class Module(GeneratorGroup): ! def __init__(self, name, prefix = None, ! includestuff = None, ! finalstuff = None, ! initstuff = None, ! variablestuff = None, ! longname = None): ! GeneratorGroup.__init__(self, prefix or name) ! self.name = name ! if longname: ! self.longname = longname ! else: ! self.longname = name ! self.includestuff = includestuff ! self.initstuff = initstuff ! self.finalstuff = finalstuff ! self.variablestuff = variablestuff ! self.typeobjects = [] ! def addobject(self, od): ! self.generators.append(od) ! self.typeobjects.append(od) ! od.setmodulename(self.longname) ! def generate(self): ! OutHeader1("Module " + self.name) ! Output("#include \"Python.h\"") ! Output() ! if self.includestuff: ! Output() ! Output("%s", self.includestuff) ! self.declareModuleVariables() ! GeneratorGroup.generate(self) ! ! if self.finalstuff: ! Output() ! Output("%s", self.finalstuff) ! Output() ! Output("void init%s(void)", self.name) ! OutLbrace() ! Output("PyObject *m;") ! Output("PyObject *d;") ! Output() ! if self.initstuff: ! Output("%s", self.initstuff) ! Output() ! Output("m = Py_InitModule(\"%s\", %s_methods);", ! self.name, self.prefix) ! Output("d = PyModule_GetDict(m);") ! self.createModuleVariables() ! OutRbrace() ! OutHeader1("End module " + self.name) ! def declareModuleVariables(self): ! self.errorname = self.prefix + "_Error" ! Output("static PyObject *%s;", self.errorname) ! def createModuleVariables(self): ! Output("""%s = %s;""", self.errorname, self.exceptionInitializer()) ! Output("""if (%s == NULL ||""", self.errorname) ! Output(""" PyDict_SetItemString(d, "Error", %s) != 0)""", ! self.errorname) ! IndentLevel() ! Output("""return;""") ! DedentLevel() ! for tp in self.typeobjects: ! tp.outputTypeObjectInitializer() ! if self.variablestuff: ! Output("%s", self.variablestuff) ! Output() ! def exceptionInitializer(self): ! return """PyErr_NewException("%s.Error", NULL, NULL)""" % self.name def _test(): ! from bgenGenerator import FunctionGenerator ! m = Module("spam", "", "#include ") ! g = FunctionGenerator(None, "bacon") ! m.add(g) ! m.generate() if __name__ == "__main__": ! _test() --- 4,94 ---- class Module(GeneratorGroup): ! def __init__(self, name, prefix = None, ! includestuff = None, ! finalstuff = None, ! initstuff = None, ! variablestuff = None, ! longname = None): ! GeneratorGroup.__init__(self, prefix or name) ! self.name = name ! if longname: ! self.longname = longname ! else: ! self.longname = name ! self.includestuff = includestuff ! self.initstuff = initstuff ! self.finalstuff = finalstuff ! self.variablestuff = variablestuff ! self.typeobjects = [] ! def addobject(self, od): ! self.generators.append(od) ! self.typeobjects.append(od) ! od.setmodulename(self.longname) ! def generate(self): ! OutHeader1("Module " + self.name) ! Output("#include \"Python.h\"") ! Output() ! if self.includestuff: ! Output() ! Output("%s", self.includestuff) ! self.declareModuleVariables() ! GeneratorGroup.generate(self) ! ! if self.finalstuff: ! Output() ! Output("%s", self.finalstuff) ! Output() ! Output("void init%s(void)", self.name) ! OutLbrace() ! Output("PyObject *m;") ! Output("PyObject *d;") ! Output() ! if self.initstuff: ! Output("%s", self.initstuff) ! Output() ! Output("m = Py_InitModule(\"%s\", %s_methods);", ! self.name, self.prefix) ! Output("d = PyModule_GetDict(m);") ! self.createModuleVariables() ! OutRbrace() ! OutHeader1("End module " + self.name) ! def declareModuleVariables(self): ! self.errorname = self.prefix + "_Error" ! Output("static PyObject *%s;", self.errorname) ! def createModuleVariables(self): ! Output("""%s = %s;""", self.errorname, self.exceptionInitializer()) ! Output("""if (%s == NULL ||""", self.errorname) ! Output(""" PyDict_SetItemString(d, "Error", %s) != 0)""", ! self.errorname) ! IndentLevel() ! Output("""return;""") ! DedentLevel() ! for tp in self.typeobjects: ! tp.outputTypeObjectInitializer() ! if self.variablestuff: ! Output("%s", self.variablestuff) ! Output() ! def exceptionInitializer(self): ! return """PyErr_NewException("%s.Error", NULL, NULL)""" % self.name def _test(): ! from bgenGenerator import FunctionGenerator ! m = Module("spam", "", "#include ") ! g = FunctionGenerator(None, "bacon") ! m.add(g) ! m.generate() if __name__ == "__main__": ! _test() Index: bgenObjectDefinition.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenObjectDefinition.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** bgenObjectDefinition.py 23 Dec 2002 22:33:49 -0000 1.24 --- bgenObjectDefinition.py 19 Jan 2003 21:53:56 -0000 1.25 *************** *** 3,486 **** class ObjectDefinition(GeneratorGroup): ! "Spit out code that together defines a new Python object type" ! basechain = "NULL" ! tp_flags = "Py_TPFLAGS_DEFAULT" ! basetype = None ! def __init__(self, name, prefix, itselftype): ! """ObjectDefinition constructor. May be extended, but do not override. ! ! - name: the object's official name, e.g. 'SndChannel'. ! - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'. ! - itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'. ! ! XXX For official Python data types, rules for the 'Py' prefix are a problem. ! """ ! ! GeneratorGroup.__init__(self, prefix or name) ! self.name = name ! self.itselftype = itselftype ! self.objecttype = name + 'Object' ! self.typename = name + '_Type' ! self.argref = "" # set to "*" if arg to _New should be pointer ! self.static = "static " # set to "" to make _New and _Convert public ! self.modulename = None ! if hasattr(self, "assertions"): ! self.assertions() ! def add(self, g, dupcheck=0): ! g.setselftype(self.objecttype, self.itselftype) ! GeneratorGroup.add(self, g, dupcheck) ! def reference(self): ! # In case we are referenced from a module ! pass ! ! def setmodulename(self, name): ! self.modulename = name ! def generate(self): ! # XXX This should use long strings and %(varname)s substitution! ! OutHeader2("Object type " + self.name) ! sf = self.static and "static " ! Output("%sPyTypeObject %s;", sf, self.typename) ! Output() ! Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))", ! self.prefix, self.typename, self.typename) ! Output() ! Output("typedef struct %s {", self.objecttype) ! IndentLevel() ! Output("PyObject_HEAD") ! self.outputStructMembers() ! DedentLevel() ! Output("} %s;", self.objecttype) ! self.outputNew() ! ! self.outputConvert() ! self.outputDealloc() ! GeneratorGroup.generate(self) ! Output() ! self.outputMethodChain() ! self.outputGetattr() ! self.outputSetattr() ! ! self.outputCompare() ! ! self.outputRepr() ! ! self.outputHash() ! ! self.outputPEP253Hooks() ! ! self.outputTypeObject() ! OutHeader2("End object type " + self.name) ! ! def outputMethodChain(self): ! Output("%sPyMethodChain %s_chain = { %s_methods, %s };", ! self.static, self.prefix, self.prefix, self.basechain) ! def outputStructMembers(self): ! Output("%s ob_itself;", self.itselftype) ! def outputNew(self): ! Output() ! Output("%sPyObject *%s_New(%s %sitself)", self.static, self.prefix, ! self.itselftype, self.argref) ! OutLbrace() ! Output("%s *it;", self.objecttype) ! self.outputCheckNewArg() ! Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename) ! Output("if (it == NULL) return NULL;") ! if self.basetype: ! Output("/* XXXX Should we tp_init or tp_new our basetype? */") ! self.outputInitStructMembers() ! Output("return (PyObject *)it;") ! OutRbrace() ! def outputInitStructMembers(self): ! Output("it->ob_itself = %sitself;", self.argref) ! ! def outputCheckNewArg(self): ! "Override this method to apply additional checks/conversions" ! ! def outputConvert(self): ! Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, ! self.itselftype) ! OutLbrace() ! self.outputCheckConvertArg() ! Output("if (!%s_Check(v))", self.prefix) ! OutLbrace() ! Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name) ! Output("return 0;") ! OutRbrace() ! Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype) ! Output("return 1;") ! OutRbrace() ! def outputCheckConvertArg(self): ! "Override this method to apply additional conversions" ! def outputDealloc(self): ! Output() ! Output("static void %s_dealloc(%s *self)", self.prefix, self.objecttype) ! OutLbrace() ! self.outputCleanupStructMembers() ! if self.basetype: ! Output("%s.tp_dealloc(self)", self.basetype) ! elif hasattr(self, 'output_tp_free'): ! # This is a new-style object with tp_free slot ! Output("self->ob_type->tp_free((PyObject *)self);") ! else: ! Output("PyObject_Free((PyObject *)self);") ! OutRbrace() ! def outputCleanupStructMembers(self): ! self.outputFreeIt("self->ob_itself") ! def outputFreeIt(self, name): ! Output("/* Cleanup of %s goes here */", name) ! def outputGetattr(self): ! Output() ! Output("static PyObject *%s_getattr(%s *self, char *name)", self.prefix, self.objecttype) ! OutLbrace() ! self.outputGetattrBody() ! OutRbrace() ! def outputGetattrBody(self): ! self.outputGetattrHook() ! Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);", ! self.prefix) ! def outputGetattrHook(self): ! pass ! def outputSetattr(self): ! Output() ! Output("#define %s_setattr NULL", self.prefix) ! def outputCompare(self): ! Output() ! Output("#define %s_compare NULL", self.prefix) ! def outputRepr(self): ! Output() ! Output("#define %s_repr NULL", self.prefix) ! def outputHash(self): ! Output() ! Output("#define %s_hash NULL", self.prefix) ! def outputTypeObject(self): ! sf = self.static and "static " ! Output() ! Output("%sPyTypeObject %s = {", sf, self.typename) ! IndentLevel() ! Output("PyObject_HEAD_INIT(NULL)") ! Output("0, /*ob_size*/") ! if self.modulename: ! Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) ! else: ! Output("\"%s\", /*tp_name*/", self.name) ! Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) ! Output("0, /*tp_itemsize*/") ! Output("/* methods */") ! Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) ! Output("0, /*tp_print*/") ! Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix) ! Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix) ! Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) ! Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) ! Output("(PyNumberMethods *)0, /* tp_as_number */") ! Output("(PySequenceMethods *)0, /* tp_as_sequence */") ! Output("(PyMappingMethods *)0, /* tp_as_mapping */") ! Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) ! DedentLevel() ! Output("};") ! ! def outputTypeObjectInitializer(self): ! Output("""%s.ob_type = &PyType_Type;""", self.typename) ! if self.basetype: ! Output("%s.tp_base = %s;", self.typename, self.basetype) ! Output("if (PyType_Ready(&%s) < 0) return;", self.typename) ! Output("""Py_INCREF(&%s);""", self.typename) ! Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename); ! Output("/* Backward-compatible name */") ! Output("""Py_INCREF(&%s);""", self.typename); ! Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename); ! def outputPEP253Hooks(self): ! pass ! class PEP252Mixin: ! getsetlist = [] ! ! def assertions(self): ! # Check that various things aren't overridden. If they are it could ! # signify a bgen-client that has been partially converted to PEP252. ! assert self.outputGetattr.im_func == PEP252Mixin.outputGetattr.im_func ! assert self.outputSetattr.im_func == PEP252Mixin.outputSetattr.im_func ! assert self.outputGetattrBody == None ! assert self.outputGetattrHook == None ! assert self.basechain == "NULL" ! ! def outputGetattr(self): ! pass ! ! outputGetattrBody = None ! outputGetattrHook = None ! def outputSetattr(self): ! pass ! ! def outputMethodChain(self): ! # This is a good place to output the getters and setters ! self.outputGetSetList() ! ! def outputHook(self, name): ! methodname = "outputHook_" + name ! if hasattr(self, methodname): ! func = getattr(self, methodname) ! func() ! else: ! Output("0, /*%s*/", name) ! ! def outputTypeObject(self): ! sf = self.static and "static " ! Output() ! Output("%sPyTypeObject %s = {", sf, self.typename) ! IndentLevel() ! Output("PyObject_HEAD_INIT(NULL)") ! Output("0, /*ob_size*/") ! if self.modulename: ! Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) ! else: ! Output("\"%s\", /*tp_name*/", self.name) ! Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) ! Output("0, /*tp_itemsize*/") ! ! Output("/* methods */") ! Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) ! Output("0, /*tp_print*/") ! Output("(getattrfunc)0, /*tp_getattr*/") ! Output("(setattrfunc)0, /*tp_setattr*/") ! Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) ! Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) ! ! Output("(PyNumberMethods *)0, /* tp_as_number */") ! Output("(PySequenceMethods *)0, /* tp_as_sequence */") ! Output("(PyMappingMethods *)0, /* tp_as_mapping */") ! ! Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) ! self.outputHook("tp_call") ! Output("0, /*tp_str*/") ! Output("PyObject_GenericGetAttr, /*tp_getattro*/") ! Output("PyObject_GenericSetAttr, /*tp_setattro */") ! ! self.outputHook("tp_as_buffer") ! Output("%s, /* tp_flags */", self.tp_flags) ! self.outputHook("tp_doc") ! self.outputHook("tp_traverse") ! self.outputHook("tp_clear") ! self.outputHook("tp_richcompare") ! self.outputHook("tp_weaklistoffset") ! self.outputHook("tp_iter") ! self.outputHook("tp_iternext") ! Output("%s_methods, /* tp_methods */", self.prefix) ! self.outputHook("tp_members") ! Output("%s_getsetlist, /*tp_getset*/", self.prefix) ! self.outputHook("tp_base") ! self.outputHook("tp_dict") ! self.outputHook("tp_descr_get") ! self.outputHook("tp_descr_set") ! self.outputHook("tp_dictoffset") ! self.outputHook("tp_init") ! self.outputHook("tp_alloc") ! self.outputHook("tp_new") ! self.outputHook("tp_free") ! DedentLevel() ! Output("};") ! ! def outputGetSetList(self): ! if self.getsetlist: ! for name, get, set, doc in self.getsetlist: ! if get: ! self.outputGetter(name, get) ! else: ! Output("#define %s_get_%s NULL", self.prefix, name) ! Output() ! if set: ! self.outputSetter(name, set) ! else: ! Output("#define %s_set_%s NULL", self.prefix, name) ! Output() ! ! Output("static PyGetSetDef %s_getsetlist[] = {", self.prefix) ! IndentLevel() ! for name, get, set, doc in self.getsetlist: ! if doc: ! doc = '"' + doc + '"' ! else: ! doc = "NULL" ! Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s},", ! name, self.prefix, name, self.prefix, name, doc) ! Output("{NULL, NULL, NULL, NULL},") ! DedentLevel() ! Output("};") ! else: ! Output("#define %s_getsetlist NULL", self.prefix) ! Output() ! ! def outputGetter(self, name, code): ! Output("static PyObject *%s_get_%s(%s *self, void *closure)", ! self.prefix, name, self.objecttype) ! OutLbrace() ! Output(code) ! OutRbrace() ! Output() ! ! def outputSetter(self, name, code): ! Output("static int %s_set_%s(%s *self, PyObject *v, void *closure)", ! self.prefix, name, self.objecttype) ! OutLbrace() ! Output(code) ! Output("return 0;") ! OutRbrace() ! Output() ! class PEP253Mixin(PEP252Mixin): ! tp_flags = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE" ! ! def outputHook_tp_init(self): ! Output("%s_tp_init, /* tp_init */", self.prefix) ! ! def outputHook_tp_alloc(self): ! Output("%s_tp_alloc, /* tp_alloc */", self.prefix) ! ! def outputHook_tp_new(self): ! Output("%s_tp_new, /* tp_new */", self.prefix) ! ! def outputHook_tp_free(self): ! Output("%s_tp_free, /* tp_free */", self.prefix) ! ! output_tp_initBody = None ! ! def output_tp_init(self): ! if self.output_tp_initBody: ! Output("static int %s_tp_init(PyObject *self, PyObject *args, PyObject *kwds)", self.prefix) ! OutLbrace() ! self.output_tp_initBody() ! OutRbrace() ! else: ! Output("#define %s_tp_init 0", self.prefix) ! Output() ! ! output_tp_allocBody = None ! ! def output_tp_alloc(self): ! if self.output_tp_allocBody: ! Output("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)", ! self.prefix) ! OutLbrace() ! self.output_tp_allocBody() ! OutRbrace() ! else: ! Output("#define %s_tp_alloc PyType_GenericAlloc", self.prefix) ! Output() ! ! def output_tp_newBody(self): ! Output("PyObject *self;"); ! Output("%s itself;", self.itselftype); ! Output("char *kw[] = {\"itself\", 0};") ! Output() ! Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;", ! self.prefix); ! Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") ! Output("((%s *)self)->ob_itself = itself;", self.objecttype) ! Output("return self;") ! ! def output_tp_new(self): ! if self.output_tp_newBody: ! Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", self.prefix) ! OutLbrace() ! self.output_tp_newBody() ! OutRbrace() ! else: ! Output("#define %s_tp_new PyType_GenericNew", self.prefix) ! Output() ! ! output_tp_freeBody = None ! ! def output_tp_free(self): ! if self.output_tp_freeBody: ! Output("static void %s_tp_free(PyObject *self)", self.prefix) ! OutLbrace() ! self.output_tp_freeBody() ! OutRbrace() ! else: ! Output("#define %s_tp_free PyObject_Del", self.prefix) ! Output() ! ! def outputPEP253Hooks(self): ! self.output_tp_init() ! self.output_tp_alloc() ! self.output_tp_new() ! self.output_tp_free() class GlobalObjectDefinition(ObjectDefinition): ! """Like ObjectDefinition but exports some parts. ! ! XXX Should also somehow generate a .h file for them. ! """ ! def __init__(self, name, prefix = None, itselftype = None): ! ObjectDefinition.__init__(self, name, prefix or name, itselftype or name) ! self.static = "" class ObjectIdentityMixin: ! """A mixin class for objects that makes the identity of ob_itself ! govern comparisons and dictionary lookups. Useful if the C object can ! be returned by library calls and it is difficult (or impossible) to find ! the corresponding Python objects. With this you can create Python object ! wrappers on the fly""" ! ! def outputCompare(self): ! Output() ! Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, ! self.objecttype) ! OutLbrace() ! Output("unsigned long v, w;") ! Output() ! Output("if (!%s_Check((PyObject *)other))", self.prefix) ! OutLbrace() ! Output("v=(unsigned long)self;") ! Output("w=(unsigned long)other;") ! OutRbrace() ! Output("else") ! OutLbrace() ! Output("v=(unsigned long)self->ob_itself;") ! Output("w=(unsigned long)other->ob_itself;") ! OutRbrace() ! Output("if( v < w ) return -1;") ! Output("if( v > w ) return 1;") ! Output("return 0;") ! OutRbrace() ! ! def outputHash(self): ! Output() ! Output("static long %s_hash(%s *self)", self.prefix, self.objecttype) ! OutLbrace() ! Output("return (long)self->ob_itself;") ! OutRbrace() ! --- 3,486 ---- class ObjectDefinition(GeneratorGroup): ! "Spit out code that together defines a new Python object type" ! basechain = "NULL" ! tp_flags = "Py_TPFLAGS_DEFAULT" ! basetype = None ! def __init__(self, name, prefix, itselftype): ! """ObjectDefinition constructor. May be extended, but do not override. ! ! - name: the object's official name, e.g. 'SndChannel'. ! - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'. ! - itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'. ! ! XXX For official Python data types, rules for the 'Py' prefix are a problem. ! """ ! ! GeneratorGroup.__init__(self, prefix or name) ! self.name = name ! self.itselftype = itselftype ! self.objecttype = name + 'Object' ! self.typename = name + '_Type' ! self.argref = "" # set to "*" if arg to _New should be pointer ! self.static = "static " # set to "" to make _New and _Convert public ! self.modulename = None ! if hasattr(self, "assertions"): ! self.assertions() ! def add(self, g, dupcheck=0): ! g.setselftype(self.objecttype, self.itselftype) ! GeneratorGroup.add(self, g, dupcheck) ! def reference(self): ! # In case we are referenced from a module ! pass ! ! def setmodulename(self, name): ! self.modulename = name ! def generate(self): ! # XXX This should use long strings and %(varname)s substitution! ! OutHeader2("Object type " + self.name) ! sf = self.static and "static " ! Output("%sPyTypeObject %s;", sf, self.typename) ! Output() ! Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))", ! self.prefix, self.typename, self.typename) ! Output() ! Output("typedef struct %s {", self.objecttype) ! IndentLevel() ! Output("PyObject_HEAD") ! self.outputStructMembers() ! DedentLevel() ! Output("} %s;", self.objecttype) ! self.outputNew() ! ! self.outputConvert() ! self.outputDealloc() ! GeneratorGroup.generate(self) ! Output() ! self.outputMethodChain() ! self.outputGetattr() ! self.outputSetattr() ! ! self.outputCompare() ! ! self.outputRepr() ! ! self.outputHash() ! ! self.outputPEP253Hooks() ! ! self.outputTypeObject() ! OutHeader2("End object type " + self.name) ! ! def outputMethodChain(self): ! Output("%sPyMethodChain %s_chain = { %s_methods, %s };", ! self.static, self.prefix, self.prefix, self.basechain) ! def outputStructMembers(self): ! Output("%s ob_itself;", self.itselftype) ! def outputNew(self): ! Output() ! Output("%sPyObject *%s_New(%s %sitself)", self.static, self.prefix, ! self.itselftype, self.argref) ! OutLbrace() ! Output("%s *it;", self.objecttype) ! self.outputCheckNewArg() ! Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename) ! Output("if (it == NULL) return NULL;") ! if self.basetype: ! Output("/* XXXX Should we tp_init or tp_new our basetype? */") ! self.outputInitStructMembers() ! Output("return (PyObject *)it;") ! OutRbrace() ! def outputInitStructMembers(self): ! Output("it->ob_itself = %sitself;", self.argref) ! ! def outputCheckNewArg(self): ! "Override this method to apply additional checks/conversions" ! ! def outputConvert(self): ! Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, ! self.itselftype) ! OutLbrace() ! self.outputCheckConvertArg() ! Output("if (!%s_Check(v))", self.prefix) ! OutLbrace() ! Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name) ! Output("return 0;") ! OutRbrace() ! Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype) ! Output("return 1;") ! OutRbrace() ! def outputCheckConvertArg(self): ! "Override this method to apply additional conversions" ! def outputDealloc(self): ! Output() ! Output("static void %s_dealloc(%s *self)", self.prefix, self.objecttype) ! OutLbrace() ! self.outputCleanupStructMembers() ! if self.basetype: ! Output("%s.tp_dealloc(self)", self.basetype) ! elif hasattr(self, 'output_tp_free'): ! # This is a new-style object with tp_free slot ! Output("self->ob_type->tp_free((PyObject *)self);") ! else: ! Output("PyObject_Free((PyObject *)self);") ! OutRbrace() ! def outputCleanupStructMembers(self): ! self.outputFreeIt("self->ob_itself") ! def outputFreeIt(self, name): ! Output("/* Cleanup of %s goes here */", name) ! def outputGetattr(self): ! Output() ! Output("static PyObject *%s_getattr(%s *self, char *name)", self.prefix, self.objecttype) ! OutLbrace() ! self.outputGetattrBody() ! OutRbrace() ! def outputGetattrBody(self): ! self.outputGetattrHook() ! Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);", ! self.prefix) ! def outputGetattrHook(self): ! pass ! def outputSetattr(self): ! Output() ! Output("#define %s_setattr NULL", self.prefix) ! def outputCompare(self): ! Output() ! Output("#define %s_compare NULL", self.prefix) ! def outputRepr(self): ! Output() ! Output("#define %s_repr NULL", self.prefix) ! def outputHash(self): ! Output() ! Output("#define %s_hash NULL", self.prefix) ! def outputTypeObject(self): ! sf = self.static and "static " ! Output() ! Output("%sPyTypeObject %s = {", sf, self.typename) ! IndentLevel() ! Output("PyObject_HEAD_INIT(NULL)") ! Output("0, /*ob_size*/") ! if self.modulename: ! Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) ! else: ! Output("\"%s\", /*tp_name*/", self.name) ! Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) ! Output("0, /*tp_itemsize*/") ! Output("/* methods */") ! Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) ! Output("0, /*tp_print*/") ! Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix) ! Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix) ! Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) ! Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) ! Output("(PyNumberMethods *)0, /* tp_as_number */") ! Output("(PySequenceMethods *)0, /* tp_as_sequence */") ! Output("(PyMappingMethods *)0, /* tp_as_mapping */") ! Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) ! DedentLevel() ! Output("};") ! ! def outputTypeObjectInitializer(self): ! Output("""%s.ob_type = &PyType_Type;""", self.typename) ! if self.basetype: ! Output("%s.tp_base = %s;", self.typename, self.basetype) ! Output("if (PyType_Ready(&%s) < 0) return;", self.typename) ! Output("""Py_INCREF(&%s);""", self.typename) ! Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename); ! Output("/* Backward-compatible name */") ! Output("""Py_INCREF(&%s);""", self.typename); ! Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename); ! def outputPEP253Hooks(self): ! pass ! class PEP252Mixin: ! getsetlist = [] ! ! def assertions(self): ! # Check that various things aren't overridden. If they are it could ! # signify a bgen-client that has been partially converted to PEP252. ! assert self.outputGetattr.im_func == PEP252Mixin.outputGetattr.im_func ! assert self.outputSetattr.im_func == PEP252Mixin.outputSetattr.im_func ! assert self.outputGetattrBody == None ! assert self.outputGetattrHook == None ! assert self.basechain == "NULL" ! ! def outputGetattr(self): ! pass ! ! outputGetattrBody = None ! outputGetattrHook = None ! def outputSetattr(self): ! pass ! ! def outputMethodChain(self): ! # This is a good place to output the getters and setters ! self.outputGetSetList() ! ! def outputHook(self, name): ! methodname = "outputHook_" + name ! if hasattr(self, methodname): ! func = getattr(self, methodname) ! func() ! else: ! Output("0, /*%s*/", name) ! ! def outputTypeObject(self): ! sf = self.static and "static " ! Output() ! Output("%sPyTypeObject %s = {", sf, self.typename) ! IndentLevel() ! Output("PyObject_HEAD_INIT(NULL)") ! Output("0, /*ob_size*/") ! if self.modulename: ! Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) ! else: ! Output("\"%s\", /*tp_name*/", self.name) ! Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) ! Output("0, /*tp_itemsize*/") ! ! Output("/* methods */") ! Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) ! Output("0, /*tp_print*/") ! Output("(getattrfunc)0, /*tp_getattr*/") ! Output("(setattrfunc)0, /*tp_setattr*/") ! Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) ! Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) ! ! Output("(PyNumberMethods *)0, /* tp_as_number */") ! Output("(PySequenceMethods *)0, /* tp_as_sequence */") ! Output("(PyMappingMethods *)0, /* tp_as_mapping */") ! ! Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) ! self.outputHook("tp_call") ! Output("0, /*tp_str*/") ! Output("PyObject_GenericGetAttr, /*tp_getattro*/") ! Output("PyObject_GenericSetAttr, /*tp_setattro */") ! ! self.outputHook("tp_as_buffer") ! Output("%s, /* tp_flags */", self.tp_flags) ! self.outputHook("tp_doc") ! self.outputHook("tp_traverse") ! self.outputHook("tp_clear") ! self.outputHook("tp_richcompare") ! self.outputHook("tp_weaklistoffset") ! self.outputHook("tp_iter") ! self.outputHook("tp_iternext") ! Output("%s_methods, /* tp_methods */", self.prefix) ! self.outputHook("tp_members") ! Output("%s_getsetlist, /*tp_getset*/", self.prefix) ! self.outputHook("tp_base") ! self.outputHook("tp_dict") ! self.outputHook("tp_descr_get") ! self.outputHook("tp_descr_set") ! self.outputHook("tp_dictoffset") ! self.outputHook("tp_init") ! self.outputHook("tp_alloc") ! self.outputHook("tp_new") ! self.outputHook("tp_free") ! DedentLevel() ! Output("};") ! ! def outputGetSetList(self): ! if self.getsetlist: ! for name, get, set, doc in self.getsetlist: ! if get: ! self.outputGetter(name, get) ! else: ! Output("#define %s_get_%s NULL", self.prefix, name) ! Output() ! if set: ! self.outputSetter(name, set) ! else: ! Output("#define %s_set_%s NULL", self.prefix, name) ! Output() ! ! Output("static PyGetSetDef %s_getsetlist[] = {", self.prefix) ! IndentLevel() ! for name, get, set, doc in self.getsetlist: ! if doc: ! doc = '"' + doc + '"' ! else: ! doc = "NULL" ! Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s},", ! name, self.prefix, name, self.prefix, name, doc) ! Output("{NULL, NULL, NULL, NULL},") ! DedentLevel() ! Output("};") ! else: ! Output("#define %s_getsetlist NULL", self.prefix) ! Output() ! ! def outputGetter(self, name, code): ! Output("static PyObject *%s_get_%s(%s *self, void *closure)", ! self.prefix, name, self.objecttype) ! OutLbrace() ! Output(code) ! OutRbrace() ! Output() ! ! def outputSetter(self, name, code): ! Output("static int %s_set_%s(%s *self, PyObject *v, void *closure)", ! self.prefix, name, self.objecttype) ! OutLbrace() ! Output(code) ! Output("return 0;") ! OutRbrace() ! Output() ! class PEP253Mixin(PEP252Mixin): ! tp_flags = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE" ! ! def outputHook_tp_init(self): ! Output("%s_tp_init, /* tp_init */", self.prefix) ! ! def outputHook_tp_alloc(self): ! Output("%s_tp_alloc, /* tp_alloc */", self.prefix) ! ! def outputHook_tp_new(self): ! Output("%s_tp_new, /* tp_new */", self.prefix) ! ! def outputHook_tp_free(self): ! Output("%s_tp_free, /* tp_free */", self.prefix) ! ! output_tp_initBody = None ! ! def output_tp_init(self): ! if self.output_tp_initBody: ! Output("static int %s_tp_init(PyObject *self, PyObject *args, PyObject *kwds)", self.prefix) ! OutLbrace() ! self.output_tp_initBody() ! OutRbrace() ! else: ! Output("#define %s_tp_init 0", self.prefix) ! Output() ! ! output_tp_allocBody = None ! ! def output_tp_alloc(self): ! if self.output_tp_allocBody: ! Output("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)", ! self.prefix) ! OutLbrace() ! self.output_tp_allocBody() ! OutRbrace() ! else: ! Output("#define %s_tp_alloc PyType_GenericAlloc", self.prefix) ! Output() ! ! def output_tp_newBody(self): ! Output("PyObject *self;"); ! Output("%s itself;", self.itselftype); ! Output("char *kw[] = {\"itself\", 0};") ! Output() ! Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;", ! self.prefix); ! Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") ! Output("((%s *)self)->ob_itself = itself;", self.objecttype) ! Output("return self;") ! ! def output_tp_new(self): ! if self.output_tp_newBody: ! Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", self.prefix) ! OutLbrace() ! self.output_tp_newBody() ! OutRbrace() ! else: ! Output("#define %s_tp_new PyType_GenericNew", self.prefix) ! Output() ! ! output_tp_freeBody = None ! ! def output_tp_free(self): ! if self.output_tp_freeBody: ! Output("static void %s_tp_free(PyObject *self)", self.prefix) ! OutLbrace() ! self.output_tp_freeBody() ! OutRbrace() ! else: ! Output("#define %s_tp_free PyObject_Del", self.prefix) ! Output() ! ! def outputPEP253Hooks(self): ! self.output_tp_init() ! self.output_tp_alloc() ! self.output_tp_new() ! self.output_tp_free() class GlobalObjectDefinition(ObjectDefinition): ! """Like ObjectDefinition but exports some parts. ! ! XXX Should also somehow generate a .h file for them. ! """ ! def __init__(self, name, prefix = None, itselftype = None): ! ObjectDefinition.__init__(self, name, prefix or name, itselftype or name) ! self.static = "" class ObjectIdentityMixin: ! """A mixin class for objects that makes the identity of ob_itself ! govern comparisons and dictionary lookups. Useful if the C object can ! be returned by library calls and it is difficult (or impossible) to find ! the corresponding Python objects. With this you can create Python object ! wrappers on the fly""" ! ! def outputCompare(self): ! Output() ! Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, ! self.objecttype) ! OutLbrace() ! Output("unsigned long v, w;") ! Output() ! Output("if (!%s_Check((PyObject *)other))", self.prefix) ! OutLbrace() ! Output("v=(unsigned long)self;") ! Output("w=(unsigned long)other;") ! OutRbrace() ! Output("else") ! OutLbrace() ! Output("v=(unsigned long)self->ob_itself;") ! Output("w=(unsigned long)other->ob_itself;") ! OutRbrace() ! Output("if( v < w ) return -1;") ! Output("if( v > w ) return 1;") ! Output("return 0;") ! OutRbrace() ! ! def outputHash(self): ! Output() ! Output("static long %s_hash(%s *self)", self.prefix, self.objecttype) ! OutLbrace() ! Output("return (long)self->ob_itself;") ! OutRbrace() ! Index: bgenOutput.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenOutput.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** bgenOutput.py 11 Sep 2002 20:36:00 -0000 1.4 --- bgenOutput.py 19 Jan 2003 21:53:57 -0000 1.5 *************** *** 10,206 **** def SetOutputFile(file = None, needclose = 0): ! """Call this with an open file object to make it the output file. ! Call it without arguments to close the current file (if necessary) ! and reset it to sys.stdout. ! If the second argument is true, the new file will be explicitly closed ! on a subsequence call. ! """ ! global _File, _NeedClose ! if _NeedClose: ! tmp = _File ! _NeedClose = 0 ! _File = None ! tmp.close() ! if file is None: ! import sys ! file = sys.stdout ! _File = file ! _NeedClose = file and needclose def SetOutputFileName(filename = None): ! """Call this with a filename to make it the output file. ! ! Call it without arguments to close the current file (if necessary) ! and reset it to sys.stdout. ! """ ! SetOutputFile() ! if filename: ! SetOutputFile(open(filename, 'w'), 1) ! SetOutputFile() # Initialize _File ! _Level = 0 # Indentation level def GetLevel(): ! """Return the current indentation level.""" ! return _Level def SetLevel(level): ! """Set the current indentation level. ! This does no type or range checking -- use at own risk. ! """ ! global _Level ! _Level = level def Output(format = "", *args): ! VaOutput(format, args) def VaOutput(format, args): ! """Call this with a format string and and argument tuple for the format. ! A newline is always added. Each line in the output is indented ! to the proper indentation level -- even if the result of the ! format expansion contains embedded newlines. Exception: lines ! beginning with '#' are not indented -- these are assumed to be ! C preprprocessor lines. ! """ ! text = format % args ! if _Level > 0: ! indent = '\t' * _Level ! lines = text.split('\n') ! for i in range(len(lines)): ! if lines[i] and lines[i][0] != '#': ! lines[i] = indent + lines[i] ! text = '\n'.join(lines) ! _File.write(text + '\n') def IndentLevel(by = 1): ! """Increment the indentation level by one. ! When called with an argument, adds it to the indentation level. ! """ ! global _Level ! if _Level+by < 0: ! raise Error, "indentation underflow (internal error)" ! _Level = _Level + by def DedentLevel(by = 1): ! """Decrement the indentation level by one. ! When called with an argument, subtracts it from the indentation level. ! """ ! IndentLevel(-by) def OutIndent(format = "", *args): ! """Combine Output() followed by IndentLevel(). ! ! If no text is given, acts like lone IndentLevel(). ! """ ! if format: VaOutput(format, args) ! IndentLevel() def OutDedent(format = "", *args): ! """Combine Output() followed by DedentLevel(). ! ! If no text is given, acts like loneDedentLevel(). ! """ ! if format: VaOutput(format, args) ! DedentLevel() def OutLbrace(format = "", *args): ! """Like Output, but add a '{' and increase the indentation level. ! ! If no text is given a lone '{' is output. ! """ ! if format: ! format = format + " {" ! else: ! format = "{" ! VaOutput(format, args) ! IndentLevel() def OutRbrace(): ! """Decrease the indentation level and output a '}' on a line by itself.""" ! DedentLevel() ! Output("}") def OutHeader(text, dash): ! """Output a header comment using a given dash character.""" ! n = 64 - len(text) ! Output() ! Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2)) ! Output() def OutHeader1(text): ! """Output a level 1 header comment (uses '=' dashes).""" ! OutHeader(text, "=") def OutHeader2(text): ! """Output a level 2 header comment (uses '-' dashes).""" ! OutHeader(text, "-") def Out(text): ! """Output multiline text that's internally indented. ! ! Pass this a multiline character string. The whitespace before the ! first nonblank line of the string will be subtracted from all lines. ! The lines are then output using Output(), but without interpretation ! of formatting (if you need formatting you can do it before the call). ! Recommended use: ! ! Out(''' ! int main(argc, argv) ! int argc; ! char *argv; ! { ! printf("Hello, world\\n"); ! exit(0); ! } ! ''') ! ! Caveat: the indentation must be consistent -- if you use three tabs ! in the first line, (up to) three tabs are removed from following lines, ! but a line beginning with 24 spaces is not trimmed at all. Don't use ! this as a feature. ! """ ! # (Don't you love using triple quotes *inside* triple quotes? :-) ! ! lines = text.split('\n') ! indent = "" ! for line in lines: ! if line.strip(): ! for c in line: ! if not c.isspace(): ! break ! indent = indent + c ! break ! n = len(indent) ! for line in lines: ! if line[:n] == indent: ! line = line[n:] ! else: ! for c in indent: ! if line[:1] <> c: break ! line = line[1:] ! VaOutput("%s", line) def _test(): ! """Test program. Run when the module is run as a script.""" ! OutHeader1("test bgenOutput") ! Out(""" ! #include ! #include ! ! main(argc, argv) ! int argc; ! char **argv; ! { ! int i; ! """) ! IndentLevel() ! Output("""\ /* Here are a few comment lines. Just to test indenting multiple lines. --- 10,206 ---- def SetOutputFile(file = None, needclose = 0): ! """Call this with an open file object to make it the output file. ! Call it without arguments to close the current file (if necessary) ! and reset it to sys.stdout. ! If the second argument is true, the new file will be explicitly closed ! on a subsequence call. ! """ ! global _File, _NeedClose ! if _NeedClose: ! tmp = _File ! _NeedClose = 0 ! _File = None ! tmp.close() ! if file is None: ! import sys ! file = sys.stdout ! _File = file ! _NeedClose = file and needclose def SetOutputFileName(filename = None): ! """Call this with a filename to make it the output file. ! ! Call it without arguments to close the current file (if necessary) ! and reset it to sys.stdout. ! """ ! SetOutputFile() ! if filename: ! SetOutputFile(open(filename, 'w'), 1) ! SetOutputFile() # Initialize _File ! _Level = 0 # Indentation level def GetLevel(): ! """Return the current indentation level.""" ! return _Level def SetLevel(level): ! """Set the current indentation level. ! This does no type or range checking -- use at own risk. ! """ ! global _Level ! _Level = level def Output(format = "", *args): ! VaOutput(format, args) def VaOutput(format, args): ! """Call this with a format string and and argument tuple for the format. ! A newline is always added. Each line in the output is indented ! to the proper indentation level -- even if the result of the ! format expansion contains embedded newlines. Exception: lines ! beginning with '#' are not indented -- these are assumed to be ! C preprprocessor lines. ! """ ! text = format % args ! if _Level > 0: ! indent = '\t' * _Level ! lines = text.split('\n') ! for i in range(len(lines)): ! if lines[i] and lines[i][0] != '#': ! lines[i] = indent + lines[i] ! text = '\n'.join(lines) ! _File.write(text + '\n') def IndentLevel(by = 1): ! """Increment the indentation level by one. ! When called with an argument, adds it to the indentation level. ! """ ! global _Level ! if _Level+by < 0: ! raise Error, "indentation underflow (internal error)" ! _Level = _Level + by def DedentLevel(by = 1): ! """Decrement the indentation level by one. ! When called with an argument, subtracts it from the indentation level. ! """ ! IndentLevel(-by) def OutIndent(format = "", *args): ! """Combine Output() followed by IndentLevel(). ! ! If no text is given, acts like lone IndentLevel(). ! """ ! if format: VaOutput(format, args) ! IndentLevel() def OutDedent(format = "", *args): ! """Combine Output() followed by DedentLevel(). ! ! If no text is given, acts like loneDedentLevel(). ! """ ! if format: VaOutput(format, args) ! DedentLevel() def OutLbrace(format = "", *args): ! """Like Output, but add a '{' and increase the indentation level. ! ! If no text is given a lone '{' is output. ! """ ! if format: ! format = format + " {" ! else: ! format = "{" ! VaOutput(format, args) ! IndentLevel() def OutRbrace(): ! """Decrease the indentation level and output a '}' on a line by itself.""" ! DedentLevel() ! Output("}") def OutHeader(text, dash): ! """Output a header comment using a given dash character.""" ! n = 64 - len(text) ! Output() ! Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2)) ! Output() def OutHeader1(text): ! """Output a level 1 header comment (uses '=' dashes).""" ! OutHeader(text, "=") def OutHeader2(text): ! """Output a level 2 header comment (uses '-' dashes).""" ! OutHeader(text, "-") def Out(text): ! """Output multiline text that's internally indented. ! ! Pass this a multiline character string. The whitespace before the ! first nonblank line of the string will be subtracted from all lines. ! The lines are then output using Output(), but without interpretation ! of formatting (if you need formatting you can do it before the call). ! Recommended use: ! ! Out(''' ! int main(argc, argv) ! int argc; ! char *argv; ! { ! printf("Hello, world\\n"); ! exit(0); ! } ! ''') ! ! Caveat: the indentation must be consistent -- if you use three tabs ! in the first line, (up to) three tabs are removed from following lines, ! but a line beginning with 24 spaces is not trimmed at all. Don't use ! this as a feature. ! """ ! # (Don't you love using triple quotes *inside* triple quotes? :-) ! ! lines = text.split('\n') ! indent = "" ! for line in lines: ! if line.strip(): ! for c in line: ! if not c.isspace(): ! break ! indent = indent + c ! break ! n = len(indent) ! for line in lines: ! if line[:n] == indent: ! line = line[n:] ! else: ! for c in indent: ! if line[:1] <> c: break ! line = line[1:] ! VaOutput("%s", line) def _test(): ! """Test program. Run when the module is run as a script.""" ! OutHeader1("test bgenOutput") ! Out(""" ! #include ! #include ! ! main(argc, argv) ! int argc; ! char **argv; ! { ! int i; ! """) ! IndentLevel() ! Output("""\ /* Here are a few comment lines. Just to test indenting multiple lines. *************** *** 208,219 **** End of the comment lines. */ """) ! Output("for (i = 0; i < argc; i++)") ! OutLbrace() ! Output('printf("argv[%%d] = %%s\\n", i, argv[i]);') ! OutRbrace() ! Output("exit(0)") ! OutRbrace() ! OutHeader2("end test") if __name__ == '__main__': ! _test() --- 208,219 ---- End of the comment lines. */ """) ! Output("for (i = 0; i < argc; i++)") ! OutLbrace() ! Output('printf("argv[%%d] = %%s\\n", i, argv[i]);') ! OutRbrace() ! Output("exit(0)") ! OutRbrace() ! OutHeader2("end test") if __name__ == '__main__': ! _test() Index: bgenStackBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenStackBuffer.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** bgenStackBuffer.py 10 Mar 1995 14:37:53 -0000 1.2 --- bgenStackBuffer.py 19 Jan 2003 21:53:57 -0000 1.3 *************** *** 7,59 **** class StackOutputBufferType(FixedOutputBufferType): ! """Fixed output buffer allocated on the stack -- passed as (buffer, size). ! Instantiate with the buffer size as parameter. ! """ ! def passOutput(self, name): ! return "%s__out__, %s" % (name, self.size) class VarStackOutputBufferType(StackOutputBufferType): ! """Output buffer allocated on the stack -- passed as (buffer, &size). ! Instantiate with the buffer size as parameter. ! """ ! def declareSize(self, name): ! Output("int %s__len__ = %s;", name, self.size) ! def passOutput(self, name): ! return "%s__out__, &%s__len__" % (name, name) ! def mkvalueArgs(self, name): ! return "%s__out__, (int)%s__len__" % (name, name) class VarVarStackOutputBufferType(VarStackOutputBufferType): ! """Output buffer allocated on the stack -- passed as (buffer, size, &size). ! Instantiate with the buffer size as parameter. ! """ ! def passOutput(self, name): ! return "%s__out__, %s__len__, &%s__len__" % (name, name, name) class ReturnVarStackOutputBufferType(VarStackOutputBufferType): ! """Output buffer allocated on the stack -- passed as (buffer, size) -> size. ! Instantiate with the buffer size as parameter. ! The function's return value is the size. ! (XXX Should have a way to suppress returning it separately, too.) ! """ ! def passOutput(self, name): ! return "%s__out__, %s__len__" % (name, name) ! def mkvalueArgs(self, name): ! return "%s__out__, (int)_rv" % name --- 7,59 ---- class StackOutputBufferType(FixedOutputBufferType): ! """Fixed output buffer allocated on the stack -- passed as (buffer, size). ! Instantiate with the buffer size as parameter. ! """ ! def passOutput(self, name): ! return "%s__out__, %s" % (name, self.size) class VarStackOutputBufferType(StackOutputBufferType): ! """Output buffer allocated on the stack -- passed as (buffer, &size). ! Instantiate with the buffer size as parameter. ! """ ! def declareSize(self, name): ! Output("int %s__len__ = %s;", name, self.size) ! def passOutput(self, name): ! return "%s__out__, &%s__len__" % (name, name) ! def mkvalueArgs(self, name): ! return "%s__out__, (int)%s__len__" % (name, name) class VarVarStackOutputBufferType(VarStackOutputBufferType): ! """Output buffer allocated on the stack -- passed as (buffer, size, &size). ! Instantiate with the buffer size as parameter. ! """ ! def passOutput(self, name): ! return "%s__out__, %s__len__, &%s__len__" % (name, name, name) class ReturnVarStackOutputBufferType(VarStackOutputBufferType): ! """Output buffer allocated on the stack -- passed as (buffer, size) -> size. ! Instantiate with the buffer size as parameter. ! The function's return value is the size. ! (XXX Should have a way to suppress returning it separately, too.) ! """ ! def passOutput(self, name): ! return "%s__out__, %s__len__" % (name, name) ! def mkvalueArgs(self, name): ! return "%s__out__, (int)_rv" % name Index: bgenStringBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenStringBuffer.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** bgenStringBuffer.py 25 Jan 1995 22:59:18 -0000 1.1 --- bgenStringBuffer.py 19 Jan 2003 21:53:57 -0000 1.2 *************** *** 9,64 **** class StringBufferMixIn: ! """Mix-in class to create various string buffer types. ! Strings are character arrays terminated by a null byte. ! (For input, this is also covered by stringptr.) ! For output, there are again three variants: ! - Fixed: size is a constant given in the documentation; or ! - Stack: size is passed to the C function but we decide on a size at ! code generation time so we can still allocate on the heap); or ! - Heap: size is passed to the C function and we let the Python caller ! pass a size. ! (Note that this doesn't cover output parameters in which a string ! pointer is returned. These are actually easier (no allocation) but far ! less common. I'll write the classes when there is demand.) ! """ ! ! def declareSize(self, name): ! pass ! ! def getargsFormat(self): ! return "s" ! ! def getargsArgs(self, name): ! return "&%s__in__" % name ! def mkvalueFormat(self): ! return "s" ! def mkvalueArgs(self, name): ! return "%s__out__" % name class FixedOutputStringType(StringBufferMixIn, FixedOutputBufferType): ! """Null-terminated output string -- passed without size. ! Instantiate with buffer size as parameter. ! """ class StackOutputStringType(StringBufferMixIn, StackOutputBufferType): ! """Null-terminated output string -- passed as (buffer, size). ! Instantiate with buffer size as parameter. ! """ class HeapOutputStringType(StringBufferMixIn, HeapOutputBufferType): ! """Null-terminated output string -- passed as (buffer, size). ! Instantiate without parameters. ! Call from Python with buffer size. ! """ --- 9,64 ---- class StringBufferMixIn: ! """Mix-in class to create various string buffer types. ! Strings are character arrays terminated by a null byte. ! (For input, this is also covered by stringptr.) ! For output, there are again three variants: ! - Fixed: size is a constant given in the documentation; or ! - Stack: size is passed to the C function but we decide on a size at ! code generation time so we can still allocate on the heap); or ! - Heap: size is passed to the C function and we let the Python caller ! pass a size. ! (Note that this doesn't cover output parameters in which a string ! pointer is returned. These are actually easier (no allocation) but far ! less common. I'll write the classes when there is demand.) ! """ ! ! def declareSize(self, name): ! pass ! ! def getargsFormat(self): ! return "s" ! ! def getargsArgs(self, name): ! return "&%s__in__" % name ! def mkvalueFormat(self): ! return "s" ! def mkvalueArgs(self, name): ! return "%s__out__" % name class FixedOutputStringType(StringBufferMixIn, FixedOutputBufferType): ! """Null-terminated output string -- passed without size. ! Instantiate with buffer size as parameter. ! """ class StackOutputStringType(StringBufferMixIn, StackOutputBufferType): ! """Null-terminated output string -- passed as (buffer, size). ! Instantiate with buffer size as parameter. ! """ class HeapOutputStringType(StringBufferMixIn, HeapOutputBufferType): ! """Null-terminated output string -- passed as (buffer, size). ! Instantiate without parameters. ! Call from Python with buffer size. ! """ Index: bgenType.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenType.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** bgenType.py 12 Apr 2002 13:14:54 -0000 1.9 --- bgenType.py 19 Jan 2003 21:53:57 -0000 1.10 *************** *** 7,109 **** class Type: ! """Define the various things you can do with a C type. ! Most methods are intended to be extended or overridden. ! """ ! def __init__(self, typeName, fmt): ! """Call with the C name and getargs format for the type. ! Example: int = Type("int", "i") ! """ ! self.typeName = typeName ! self.fmt = fmt ! def declare(self, name): ! """Declare a variable of the type with a given name. ! Example: int.declare('spam') prints "int spam;" ! """ ! Output("%s %s;", self.typeName, name) ! def getargs(self): ! return self.getargsFormat(), self.getargsArgs() ! def getargsFormat(self): ! """Return the format for this type for use with [new]getargs(). ! Example: int.getargsFormat() returns the string "i". ! """ ! return self.fmt ! def getargsArgs(self, name): ! """Return an argument for use with [new]getargs(). ! Example: int.getargsArgs("spam") returns the string "&spam". ! """ ! return "&" + name ! def getargsCheck(self, name): ! """Perform any needed post-[new]getargs() checks. ! This is type-dependent; the default does not check for errors. ! An example would be a check for a maximum string length.""" ! def passInput(self, name): ! """Return an argument for passing a variable into a call. ! Example: int.passInput("spam") returns the string "spam". ! """ ! return name ! def passOutput(self, name): ! """Return an argument for returning a variable out of a call. ! Example: int.passOutput("spam") returns the string "&spam". ! """ ! return "&" + name ! def errorCheck(self, name): ! """Check for an error returned in the variable. ! This is type-dependent; the default does not check for errors. ! An example would be a check for a NULL pointer. ! If an error is found, the generated routine should ! raise an exception and return NULL. ! XXX There should be a way to add error clean-up code. ! """ ! Output("/* XXX no err check for %s %s */", self.typeName, name) ! def mkvalue(self): ! return self.mkvalueFormat(), self.mkvalueArgs() ! def mkvalueFormat(self): ! """Return the format for this type for use with mkvalue(). ! This is normally the same as getargsFormat() but it is ! a separate function to allow future divergence. ! """ ! return self.getargsFormat() ! def mkvalueArgs(self, name): ! """Return an argument for use with mkvalue(). ! Example: int.mkvalueArgs("spam") returns the string "spam". ! """ ! return name ! def cleanup(self, name): ! """Clean up if necessary. ! This is normally empty; it may deallocate buffers etc. ! """ ! pass class ByAddressType(Type): ! "Simple type that is also passed by address for input" ! def passInput(self, name): ! return "&%s" % name --- 7,109 ---- class Type: ! """Define the various things you can do with a C type. ! Most methods are intended to be extended or overridden. ! """ ! def __init__(self, typeName, fmt): ! """Call with the C name and getargs format for the type. ! Example: int = Type("int", "i") ! """ ! self.typeName = typeName ! self.fmt = fmt ! def declare(self, name): ! """Declare a variable of the type with a given name. ! Example: int.declare('spam') prints "int spam;" ! """ ! Output("%s %s;", self.typeName, name) ! def getargs(self): ! return self.getargsFormat(), self.getargsArgs() ! def getargsFormat(self): ! """Return the format for this type for use with [new]getargs(). ! Example: int.getargsFormat() returns the string "i". ! """ ! return self.fmt ! def getargsArgs(self, name): ! """Return an argument for use with [new]getargs(). ! Example: int.getargsArgs("spam") returns the string "&spam". ! """ ! return "&" + name ! def getargsCheck(self, name): ! """Perform any needed post-[new]getargs() checks. ! This is type-dependent; the default does not check for errors. ! An example would be a check for a maximum string length.""" ! def passInput(self, name): ! """Return an argument for passing a variable into a call. ! Example: int.passInput("spam") returns the string "spam". ! """ ! return name ! def passOutput(self, name): ! """Return an argument for returning a variable out of a call. ! Example: int.passOutput("spam") returns the string "&spam". ! """ ! return "&" + name ! def errorCheck(self, name): ! """Check for an error returned in the variable. ! This is type-dependent; the default does not check for errors. ! An example would be a check for a NULL pointer. ! If an error is found, the generated routine should ! raise an exception and return NULL. ! XXX There should be a way to add error clean-up code. ! """ ! Output("/* XXX no err check for %s %s */", self.typeName, name) ! def mkvalue(self): ! return self.mkvalueFormat(), self.mkvalueArgs() ! def mkvalueFormat(self): ! """Return the format for this type for use with mkvalue(). ! This is normally the same as getargsFormat() but it is ! a separate function to allow future divergence. ! """ ! return self.getargsFormat() ! def mkvalueArgs(self, name): ! """Return an argument for use with mkvalue(). ! Example: int.mkvalueArgs("spam") returns the string "spam". ! """ ! return name ! def cleanup(self, name): ! """Clean up if necessary. ! This is normally empty; it may deallocate buffers etc. ! """ ! pass class ByAddressType(Type): ! "Simple type that is also passed by address for input" ! def passInput(self, name): ! return "&%s" % name *************** *** 113,135 **** class InputOnlyMixIn: ! "Mix-in class to boobytrap passOutput" ! def passOutput(self, name): ! raise RuntimeError, "Type '%s' can only be used for input parameters" % self.typeName class InputOnlyType(InputOnlyMixIn, Type): ! "Same as Type, but only usable for input parameters -- passOutput is boobytrapped" class OutputOnlyMixIn: ! "Mix-in class to boobytrap passInput" ! def passInput(self, name): ! raise RuntimeError, "Type '%s' can only be used for output parameters" % self.typeName class OutputOnlyType(OutputOnlyMixIn, Type): ! "Same as Type, but only usable for output parameters -- passInput is boobytrapped" --- 113,135 ---- class InputOnlyMixIn: ! "Mix-in class to boobytrap passOutput" ! def passOutput(self, name): ! raise RuntimeError, "Type '%s' can only be used for input parameters" % self.typeName class InputOnlyType(InputOnlyMixIn, Type): ! "Same as Type, but only usable for input parameters -- passOutput is boobytrapped" class OutputOnlyMixIn: ! "Mix-in class to boobytrap passInput" ! def passInput(self, name): ! raise RuntimeError, "Type '%s' can only be used for output parameters" % self.typeName class OutputOnlyType(OutputOnlyMixIn, Type): ! "Same as Type, but only usable for output parameters -- passInput is boobytrapped" *************** *** 161,258 **** class FakeType(InputOnlyType): ! """A type that is not represented in the Python version of the interface. ! Instantiate with a value to pass in the call. ! """ ! def __init__(self, substitute): ! self.substitute = substitute ! self.typeName = None # Don't show this argument in __doc__ string ! def declare(self, name): ! pass ! def getargsFormat(self): ! return "" ! def getargsArgs(self, name): ! return None ! def passInput(self, name): ! return self.substitute class OpaqueType(Type): ! """A type represented by an opaque object type, always passed by address. ! Instantiate with the type name and the names of the new and convert procs. ! If fewer than three arguments are passed, the second argument is used ! to derive the new and convert procs by appending _New and _Convert; it ! defaults to the first argument. ! """ ! def __init__(self, name, arg = None, extra = None): ! self.typeName = name ! if extra is None: ! # Two arguments (name, usetype) or one (name) ! arg = arg or name ! self.new = arg + '_New' ! self.convert = arg + '_Convert' ! else: ! # Three arguments (name, new, convert) ! self.new = arg ! self.convert = extra ! def getargsFormat(self): ! return "O&" ! def getargsArgs(self, name): ! return "%s, &%s" % (self.convert, name) ! def passInput(self, name): ! return "&%s" % name ! def mkvalueFormat(self): ! return "O&" ! def mkvalueArgs(self, name): ! return "%s, &%s" % (self.new, name) class OpaqueByValueType(OpaqueType): ! """A type represented by an opaque object type, on input passed BY VALUE. ! Instantiate with the type name, and optionally an object type name whose ! New/Convert functions will be used. ! """ ! def passInput(self, name): ! return name ! def mkvalueArgs(self, name): ! return "%s, %s" % (self.new, name) ! class OpaqueByValueStructType(OpaqueByValueType): ! """Similar to OpaqueByValueType, but we also pass this to mkvalue by ! address, in stead of by value. ! """ ! def mkvalueArgs(self, name): ! return "%s, &%s" % (self.new, name) class OpaqueArrayType(OpaqueByValueType): ! """A type represented by an opaque object type, with ARRAY passing semantics. ! Instantiate with the type name, and optional an object type name whose ! New/Convert functions will be used. ! """ ! def getargsArgs(self, name): ! return "%s, %s" % (self.convert, name) ! def passOutput(self, name): ! return name --- 161,258 ---- class FakeType(InputOnlyType): ! """A type that is not represented in the Python version of the interface. ! Instantiate with a value to pass in the call. ! """ ! def __init__(self, substitute): ! self.substitute = substitute ! self.typeName = None # Don't show this argument in __doc__ string ! def declare(self, name): ! pass ! def getargsFormat(self): ! return "" ! def getargsArgs(self, name): ! return None ! def passInput(self, name): ! return self.substitute class OpaqueType(Type): ! """A type represented by an opaque object type, always passed by address. ! Instantiate with the type name and the names of the new and convert procs. ! If fewer than three arguments are passed, the second argument is used ! to derive the new and convert procs by appending _New and _Convert; it ! defaults to the first argument. ! """ ! def __init__(self, name, arg = None, extra = None): ! self.typeName = name ! if extra is None: ! # Two arguments (name, usetype) or one (name) ! arg = arg or name ! self.new = arg + '_New' ! self.convert = arg + '_Convert' ! else: ! # Three arguments (name, new, convert) ! self.new = arg ! self.convert = extra ! def getargsFormat(self): ! return "O&" ! def getargsArgs(self, name): ! return "%s, &%s" % (self.convert, name) ! def passInput(self, name): ! return "&%s" % name ! def mkvalueFormat(self): ! return "O&" ! def mkvalueArgs(self, name): ! return "%s, &%s" % (self.new, name) class OpaqueByValueType(OpaqueType): ! """A type represented by an opaque object type, on input passed BY VALUE. ! Instantiate with the type name, and optionally an object type name whose ! New/Convert functions will be used. ! """ ! def passInput(self, name): ! return name ! def mkvalueArgs(self, name): ! return "%s, %s" % (self.new, name) ! class OpaqueByValueStructType(OpaqueByValueType): ! """Similar to OpaqueByValueType, but we also pass this to mkvalue by ! address, in stead of by value. ! """ ! def mkvalueArgs(self, name): ! return "%s, &%s" % (self.new, name) class OpaqueArrayType(OpaqueByValueType): ! """A type represented by an opaque object type, with ARRAY passing semantics. ! Instantiate with the type name, and optional an object type name whose ! New/Convert functions will be used. ! """ ! def getargsArgs(self, name): ! return "%s, %s" % (self.convert, name) ! def passOutput(self, name): ! return name Index: bgenVariable.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenVariable.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** bgenVariable.py 25 Jan 1995 22:59:20 -0000 1.1 --- bgenVariable.py 19 Jan 2003 21:53:57 -0000 1.2 *************** *** 18,88 **** class Variable: ! """A Variable holds a type, a name, a transfer mode and flags. ! Most of its methods call the correponding type method with the ! variable name. ! """ ! def __init__(self, type, name = None, flags = InMode): ! """Call with a type, a name and flags. ! If name is None, it muse be set later. ! flags defaults to InMode. ! """ ! self.type = type ! self.name = name ! self.flags = flags ! self.mode = flags & ModeMask ! def declare(self): ! """Declare the variable if necessary. ! If it is "self", it is not declared. ! """ ! if self.flags != SelfMode: ! self.type.declare(self.name) ! def getargsFormat(self): ! """Call the type's getargsFormatmethod.""" ! return self.type.getargsFormat() ! def getargsArgs(self): ! """Call the type's getargsArgsmethod.""" ! return self.type.getargsArgs(self.name) ! def getargsCheck(self): ! return self.type.getargsCheck(self.name) ! def passArgument(self): ! """Return the string required to pass the variable as argument. ! For "in" arguments, return the variable name. ! For "out" and "in out" arguments, ! return its name prefixed with "&". ! """ ! if self.mode == InMode: ! return self.type.passInput(self.name) ! if self.mode in (OutMode, InOutMode): ! return self.type.passOutput(self.name) ! # XXX Shouldn't get here ! return "/*mode?*/" + self.type.passInput(self.name) ! def errorCheck(self): ! """Check for an error if necessary. ! This only generates code if the variable's mode is ErrorMode. ! """ ! if self.flags == ErrorMode: ! self.type.errorCheck(self.name) ! def mkvalueFormat (self): ! """Call the type's mkvalueFormat method.""" ! return self.type.mkvalueFormat() ! def mkvalueArgs(self): ! """Call the type's mkvalueArgs method.""" ! return self.type.mkvalueArgs(self.name) ! def cleanup(self): ! """Call the type's cleanup method.""" ! return self.type.cleanup(self.name) --- 18,88 ---- class Variable: ! """A Variable holds a type, a name, a transfer mode and flags. ! Most of its methods call the correponding type method with the ! variable name. ! """ ! def __init__(self, type, name = None, flags = InMode): ! """Call with a type, a name and flags. ! If name is None, it muse be set later. ! flags defaults to InMode. ! """ ! self.type = type ! self.name = name ! self.flags = flags ! self.mode = flags & ModeMask ! def declare(self): ! """Declare the variable if necessary. ! If it is "self", it is not declared. ! """ ! if self.flags != SelfMode: ! self.type.declare(self.name) ! def getargsFormat(self): ! """Call the type's getargsFormatmethod.""" ! return self.type.getargsFormat() ! def getargsArgs(self): ! """Call the type's getargsArgsmethod.""" ! return self.type.getargsArgs(self.name) ! def getargsCheck(self): ! return self.type.getargsCheck(self.name) ! def passArgument(self): ! """Return the string required to pass the variable as argument. ! For "in" arguments, return the variable name. ! For "out" and "in out" arguments, ! return its name prefixed with "&". ! """ ! if self.mode == InMode: ! return self.type.passInput(self.name) ! if self.mode in (OutMode, InOutMode): ! return self.type.passOutput(self.name) ! # XXX Shouldn't get here ! return "/*mode?*/" + self.type.passInput(self.name) ! def errorCheck(self): ! """Check for an error if necessary. ! This only generates code if the variable's mode is ErrorMode. ! """ ! if self.flags == ErrorMode: ! self.type.errorCheck(self.name) ! def mkvalueFormat (self): ! """Call the type's mkvalueFormat method.""" ! return self.type.mkvalueFormat() ! def mkvalueArgs(self): ! """Call the type's mkvalueArgs method.""" ! return self.type.mkvalueArgs(self.name) ! def cleanup(self): ! """Call the type's cleanup method.""" ! return self.type.cleanup(self.name) Index: macsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/macsupport.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** macsupport.py 22 Aug 2002 23:30:48 -0000 1.28 --- macsupport.py 19 Jan 2003 21:53:57 -0000 1.29 *************** *** 53,57 **** # OSType and ResType: 4-byte character strings def OSTypeType(typename): ! return OpaqueByValueType(typename, "PyMac_BuildOSType", "PyMac_GetOSType") OSType = OSTypeType("OSType") ResType = OSTypeType("ResType") --- 53,57 ---- # OSType and ResType: 4-byte character strings def OSTypeType(typename): ! return OpaqueByValueType(typename, "PyMac_BuildOSType", "PyMac_GetOSType") OSType = OSTypeType("OSType") ResType = OSTypeType("ResType") *************** *** 105,111 **** # (Could do this with less code using a variant of mkvalue("O&")?) class OSErrType(Type): ! def errorCheck(self, name): ! Output("if (%s != noErr) return PyMac_Error(%s);", name, name) ! self.used = 1 OSErr = OSErrType("OSErr", 'h') OSStatus = OSErrType("OSStatus", 'l') --- 105,111 ---- # (Could do this with less code using a variant of mkvalue("O&")?) class OSErrType(Type): ! def errorCheck(self, name): ! Output("if (%s != noErr) return PyMac_Error(%s);", name, name) ! self.used = 1 OSErr = OSErrType("OSErr", 'h') OSStatus = OSErrType("OSStatus", 'l') *************** *** 114,126 **** # Various buffer types ! InBuffer = VarInputBufferType('char', 'long', 'l') # (buf, len) ! UcharInBuffer = VarInputBufferType('unsigned char', 'long', 'l') # (buf, len) ! OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l') # (buf, len) ! InOutBuffer = HeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, len) VarInOutBuffer = VarHeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, &len) ! OutBuffer = HeapOutputBufferType('char', 'long', 'l') # (buf, len) ! VarOutBuffer = VarHeapOutputBufferType('char', 'long', 'l') # (buf, &len) VarVarOutBuffer = VarVarHeapOutputBufferType('char', 'long', 'l') # (buf, len, &len) --- 114,126 ---- # Various buffer types ! InBuffer = VarInputBufferType('char', 'long', 'l') # (buf, len) ! UcharInBuffer = VarInputBufferType('unsigned char', 'long', 'l') # (buf, len) ! OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l') # (buf, len) ! InOutBuffer = HeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, len) VarInOutBuffer = VarHeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, &len) ! OutBuffer = HeapOutputBufferType('char', 'long', 'l') # (buf, len) ! VarOutBuffer = VarHeapOutputBufferType('char', 'long', 'l') # (buf, &len) VarVarOutBuffer = VarVarHeapOutputBufferType('char', 'long', 'l') # (buf, len, &len) *************** *** 128,137 **** class VarUnicodeInputBufferType(VarInputBufferType): ! def getargsFormat(self): ! return "u#" ! class VarUnicodeReverseInputBufferType(ReverseInputBufferMixin, VarUnicodeInputBufferType): ! pass ! UnicodeInBuffer = VarUnicodeInputBufferType('UniChar', 'UniCharCount', 'l') UnicodeReverseInBuffer = VarUnicodeReverseInputBufferType('UniChar', 'UniCharCount', 'l') --- 128,137 ---- class VarUnicodeInputBufferType(VarInputBufferType): ! def getargsFormat(self): ! return "u#" ! class VarUnicodeReverseInputBufferType(ReverseInputBufferMixin, VarUnicodeInputBufferType): ! pass ! UnicodeInBuffer = VarUnicodeInputBufferType('UniChar', 'UniCharCount', 'l') UnicodeReverseInBuffer = VarUnicodeReverseInputBufferType('UniChar', 'UniCharCount', 'l') *************** *** 152,158 **** /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\\ ! PyErr_SetString(PyExc_NotImplementedError, \\ ! "Not available in this shared library/OS version"); \\ ! return NULL; \\ }} while(0) --- 152,158 ---- /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\\ ! PyErr_SetString(PyExc_NotImplementedError, \\ ! "Not available in this shared library/OS version"); \\ ! return NULL; \\ }} while(0) *************** *** 174,183 **** # errorCheck method. class OSErrMixIn: ! "Mix-in class to treat OSErr/OSStatus return values special" ! def makereturnvar(self): ! if self.returntype.__class__ == OSErrType: ! return Variable(self.returntype, "_err", ErrorMode) ! else: ! return Variable(self.returntype, "_rv", OutMode) class OSErrFunctionGenerator(OSErrMixIn, FunctionGenerator): pass --- 174,183 ---- # errorCheck method. class OSErrMixIn: ! "Mix-in class to treat OSErr/OSStatus return values special" ! def makereturnvar(self): ! if self.returntype.__class__ == OSErrType: ! return Variable(self.returntype, "_err", ErrorMode) ! else: ! return Variable(self.returntype, "_rv", OutMode) class OSErrFunctionGenerator(OSErrMixIn, FunctionGenerator): pass *************** *** 185,194 **** class WeakLinkMixIn: ! "Mix-in to test the function actually exists (!= NULL) before calling" ! ! def precheck(self): ! Output('#ifndef %s', self.name) ! Output('PyMac_PRECHECK(%s);', self.name) ! Output('#endif') class WeakLinkFunctionGenerator(WeakLinkMixIn, FunctionGenerator): pass --- 185,194 ---- class WeakLinkMixIn: ! "Mix-in to test the function actually exists (!= NULL) before calling" ! ! def precheck(self): ! Output('#ifndef %s', self.name) ! Output('PyMac_PRECHECK(%s);', self.name) ! Output('#endif') class WeakLinkFunctionGenerator(WeakLinkMixIn, FunctionGenerator): pass *************** *** 198,210 **** class MacModule(Module): ! "Subclass which gets the exception initializer from macglue.c" ! def exceptionInitializer(self): ! return "PyMac_GetOSErrException()" _SetOutputFileName = SetOutputFileName # Save original def SetOutputFileName(file = None): ! "Set the output file name and set its creator&type to CWIE&TEXT" ! _SetOutputFileName(file) ! if file: ! import MacOS ! MacOS.SetCreatorAndType(file, 'CWIE', 'TEXT') --- 198,210 ---- class MacModule(Module): ! "Subclass which gets the exception initializer from macglue.c" ! def exceptionInitializer(self): ! return "PyMac_GetOSErrException()" _SetOutputFileName = SetOutputFileName # Save original def SetOutputFileName(file = None): ! "Set the output file name and set its creator&type to CWIE&TEXT" ! _SetOutputFileName(file) ! if file: ! import MacOS ! MacOS.SetCreatorAndType(file, 'CWIE', 'TEXT') Index: scantools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/scantools.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** scantools.py 11 Sep 2002 20:36:00 -0000 1.32 --- scantools.py 19 Jan 2003 21:53:57 -0000 1.33 *************** *** 21,33 **** from types import * try: ! import MacOS except ImportError: ! MacOS = None try: ! from bgenlocations import CREATOR, INCLUDEDIR except ImportError: ! CREATOR = None [...1270 lines suppressed...] ! out = [] ! for c in s: ! o = ord(c) ! if o >= 128: ! out.append("\\" + hex(o)[1:]) ! else: ! out.append(c) ! s = "".join(out) ! return s def test(): ! input = "D:Development:THINK C:Mac #includes:Apple #includes:AppleEvents.h" ! output = "@aespecs.py" ! defsoutput = "@aedefs.py" ! s = Scanner(input, output, defsoutput) ! s.scan() if __name__ == '__main__': ! test() From jackjansen@users.sourceforge.net Sun Jan 19 22:59:55 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 19 Jan 2003 14:59:55 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/file _Filemodule.c,1.13,1.14 filesupport.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/file In directory sc8-pr-cvs1:/tmp/cvs-serv3246 Modified Files: _Filemodule.c filesupport.py Log Message: Added a convenience routine pathname() which accepts either a string, unicode, FSSpec or FSRef object and returns an 8-bit pathname (utf8 encoded). Index: _Filemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/_Filemodule.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** _Filemodule.c 15 Jan 2003 22:36:16 -0000 1.13 --- _Filemodule.c 19 Jan 2003 22:59:52 -0000 1.14 *************** *** 15,21 **** /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ ! PyErr_SetString(PyExc_NotImplementedError, \ ! "Not available in this shared library/OS version"); \ ! return NULL; \ }} while(0) --- 15,21 ---- /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ ! PyErr_SetString(PyExc_NotImplementedError, \ ! "Not available in this shared library/OS version"); \ ! return NULL; \ }} while(0) *************** *** 3000,3003 **** --- 3000,3020 ---- } + static PyObject *File_pathname(PyObject *_self, PyObject *_args) + { + PyObject *_res = NULL; + + PyObject *obj; + + if (!PyArg_ParseTuple(_args, "O", &obj)) + return NULL; + if (PyString_Check(obj)) + return obj; + if (PyUnicode_Check(obj)) + return PyUnicode_AsEncodedString(obj, "utf8", "strict"); + _res = PyObject_CallMethod(obj, "as_pathname", NULL); + return _res; + + } + static PyMethodDef File_methods[] = { {"UnmountVol", (PyCFunction)File_UnmountVol, 1, *************** *** 3101,3104 **** --- 3118,3123 ---- {"FSUpdateAlias", (PyCFunction)File_FSUpdateAlias, 1, PyDoc_STR("(FSRef fromFile, FSRef target, AliasHandle alias) -> (Boolean wasChanged)")}, + {"pathname", (PyCFunction)File_pathname, 1, + PyDoc_STR("(str|unicode|FSSpec|FSref) -> pathname")}, {NULL, NULL, 0} }; Index: filesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filesupport.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** filesupport.py 15 Jan 2003 22:36:16 -0000 1.12 --- filesupport.py 19 Jan 2003 22:59:52 -0000 1.13 *************** *** 845,848 **** --- 845,863 ---- fsspec_methods.append(f) + pathname_body = """ + PyObject *obj; + + if (!PyArg_ParseTuple(_args, "O", &obj)) + return NULL; + if (PyString_Check(obj)) + return obj; + if (PyUnicode_Check(obj)) + return PyUnicode_AsEncodedString(obj, "utf8", "strict"); + _res = PyObject_CallMethod(obj, "as_pathname", NULL); + return _res; + """ + f = ManualGenerator("pathname", pathname_body) + f.docstring = lambda: "(str|unicode|FSSpec|FSref) -> pathname" + functions.append(f) # add the populated lists to the generator groups From doerwalter@users.sourceforge.net Sun Jan 19 23:27:01 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 19 Jan 2003 15:27:01 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_userdict.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14825/Lib/test Modified Files: test_userdict.py Log Message: Port test_userdict.py to PyUnit. From SF patch #662807, with additional tests for setdefault(), pop() and popitem(). Index: test_userdict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_userdict.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_userdict.py 11 Dec 2002 07:16:06 -0000 1.11 --- test_userdict.py 19 Jan 2003 23:26:59 -0000 1.12 *************** *** 1,6 **** # Check every path through every method of UserDict ! from test.test_support import verify, verbose ! from UserDict import UserDict, IterableUserDict d0 = {} --- 1,7 ---- # Check every path through every method of UserDict ! import test.test_support, unittest ! ! import UserDict d0 = {} *************** *** 11,145 **** d5 = {"one": 1, "two": 1} ! # Test constructors ! ! u = UserDict() ! u0 = UserDict(d0) ! u1 = UserDict(d1) ! u2 = IterableUserDict(d2) ! ! uu = UserDict(u) ! uu0 = UserDict(u0) ! uu1 = UserDict(u1) ! uu2 = UserDict(u2) ! ! verify(UserDict(one=1, two=2) == d2) # keyword arg constructor ! verify(UserDict([('one',1), ('two',2)]) == d2) # item sequence constructor ! verify(UserDict(dict=[('one',1), ('two',2)]) == d2) ! verify(UserDict([('one',1), ('two',2)], two=3, three=5) == d3) # both together ! ! verify(UserDict.fromkeys('one two'.split()) == d4) # alternate constructor ! verify(UserDict().fromkeys('one two'.split()) == d4) ! verify(UserDict.fromkeys('one two'.split(), 1) == d5) ! verify(UserDict().fromkeys('one two'.split(), 1) == d5) ! verify(u1.fromkeys('one two'.split()) is not u1) ! verify(isinstance(u1.fromkeys('one two'.split()), UserDict)) ! verify(isinstance(u2.fromkeys('one two'.split()), IterableUserDict)) ! ! # Test __repr__ ! ! verify(str(u0) == str(d0)) ! verify(repr(u1) == repr(d1)) ! verify(`u2` == `d2`) ! ! # Test __cmp__ and __len__ ! ! all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2] ! for a in all: ! for b in all: ! verify(cmp(a, b) == cmp(len(a), len(b))) ! ! # Test __getitem__ ! verify(u2["one"] == 1) ! try: ! u1["two"] ! except KeyError: ! pass ! else: ! verify(0, "u1['two'] shouldn't exist") ! # Test __setitem__ ! u3 = UserDict(u2) ! u3["two"] = 2 ! u3["three"] = 3 ! # Test __delitem__ ! del u3["three"] ! try: ! del u3["three"] ! except KeyError: ! pass ! else: ! verify(0, "u3['three'] shouldn't exist") ! # Test clear ! u3.clear() ! verify(u3 == {}) ! # Test copy() ! u2a = u2.copy() ! verify(u2a == u2) ! class MyUserDict(UserDict): ! def display(self): print self ! m2 = MyUserDict(u2) ! m2a = m2.copy() ! verify(m2a == m2) ! # SF bug #476616 -- copy() of UserDict subclass shared data ! m2['foo'] = 'bar' ! verify(m2a != m2) ! # Test keys, items, values ! verify(u2.keys() == d2.keys()) ! verify(u2.items() == d2.items()) ! verify(u2.values() == d2.values()) ! # Test has_key and "in". ! for i in u2.keys(): ! verify(u2.has_key(i) == 1) ! verify((i in u2) == 1) ! verify(u1.has_key(i) == d1.has_key(i)) ! verify((i in u1) == (i in d1)) ! verify(u0.has_key(i) == d0.has_key(i)) ! verify((i in u0) == (i in d0)) ! # Test update ! t = UserDict() ! t.update(u2) ! verify(t == u2) ! # Test get ! for i in u2.keys(): ! verify(u2.get(i) == u2[i]) ! verify(u1.get(i) == d1.get(i)) ! verify(u0.get(i) == d0.get(i)) ! # Test "in" iteration. ! for i in xrange(20): ! u2[i] = str(i) ! ikeys = [] ! for k in u2: ! ikeys.append(k) ! ikeys.sort() ! keys = u2.keys() ! keys.sort() ! verify(ikeys == keys) ########################## # Test Dict Mixin ! from UserDict import DictMixin ! ! class SeqDict(DictMixin): """Dictionary lookalike implemented with lists. --- 12,153 ---- d5 = {"one": 1, "two": 1} ! class UserDictTest(unittest.TestCase): ! def test_all(self): ! # Test constructors ! u = UserDict.UserDict() ! u0 = UserDict.UserDict(d0) ! u1 = UserDict.UserDict(d1) ! u2 = UserDict.IterableUserDict(d2) ! uu = UserDict.UserDict(u) ! uu0 = UserDict.UserDict(u0) ! uu1 = UserDict.UserDict(u1) ! uu2 = UserDict.UserDict(u2) ! # keyword arg constructor ! self.assertEqual(UserDict.UserDict(one=1, two=2), d2) ! # item sequence constructor ! self.assertEqual(UserDict.UserDict([('one',1), ('two',2)]), d2) ! self.assertEqual(UserDict.UserDict(dict=[('one',1), ('two',2)]), d2) ! # both together ! self.assertEqual(UserDict.UserDict([('one',1), ('two',2)], two=3, three=5), d3) ! # alternate constructor ! self.assertEqual(UserDict.UserDict.fromkeys('one two'.split()), d4) ! self.assertEqual(UserDict.UserDict().fromkeys('one two'.split()), d4) ! self.assertEqual(UserDict.UserDict.fromkeys('one two'.split(), 1), d5) ! self.assertEqual(UserDict.UserDict().fromkeys('one two'.split(), 1), d5) ! self.assert_(u1.fromkeys('one two'.split()) is not u1) ! self.assert_(isinstance(u1.fromkeys('one two'.split()), UserDict.UserDict)) ! self.assert_(isinstance(u2.fromkeys('one two'.split()), UserDict.IterableUserDict)) ! # Test __repr__ ! self.assertEqual(str(u0), str(d0)) ! self.assertEqual(repr(u1), repr(d1)) ! self.assertEqual(`u2`, `d2`) ! # Test __cmp__ and __len__ ! all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2] ! for a in all: ! for b in all: ! self.assertEqual(cmp(a, b), cmp(len(a), len(b))) ! # Test __getitem__ ! self.assertEqual(u2["one"], 1) ! self.assertRaises(KeyError, u1.__getitem__, "two") ! # Test __setitem__ ! u3 = UserDict.UserDict(u2) ! u3["two"] = 2 ! u3["three"] = 3 ! # Test __delitem__ ! del u3["three"] ! self.assertRaises(KeyError, u3.__delitem__, "three") ! # Test clear ! u3.clear() ! self.assertEqual(u3, {}) ! # Test copy() ! u2a = u2.copy() ! self.assertEqual(u2a, u2) ! u2b = UserDict.UserDict(x=42, y=23) ! u2c = u2b.copy() # making a copy of a UserDict is special cased ! self.assertEqual(u2b, u2c) ! class MyUserDict(UserDict.UserDict): ! def display(self): print self ! m2 = MyUserDict(u2) ! m2a = m2.copy() ! self.assertEqual(m2a, m2) ! # SF bug #476616 -- copy() of UserDict subclass shared data ! m2['foo'] = 'bar' ! self.assertNotEqual(m2a, m2) ! # Test keys, items, values ! self.assertEqual(u2.keys(), d2.keys()) ! self.assertEqual(u2.items(), d2.items()) ! self.assertEqual(u2.values(), d2.values()) ! # Test has_key and "in". ! for i in u2.keys(): ! self.assert_(u2.has_key(i)) ! self.assert_(i in u2) ! self.assertEqual(u1.has_key(i), d1.has_key(i)) ! self.assertEqual(i in u1, i in d1) ! self.assertEqual(u0.has_key(i), d0.has_key(i)) ! self.assertEqual(i in u0, i in d0) ! # Test update ! t = UserDict.UserDict() ! t.update(u2) ! self.assertEqual(t, u2) ! class Items: ! def items(self): ! return (("x", 42), ("y", 23)) ! t = UserDict.UserDict() ! t.update(Items()) ! self.assertEqual(t, {"x": 42, "y": 23}) ! # Test get ! for i in u2.keys(): ! self.assertEqual(u2.get(i), u2[i]) ! self.assertEqual(u1.get(i), d1.get(i)) ! self.assertEqual(u0.get(i), d0.get(i)) ! # Test "in" iteration. ! for i in xrange(20): ! u2[i] = str(i) ! ikeys = [] ! for k in u2: ! ikeys.append(k) ! ikeys.sort() ! keys = u2.keys() ! keys.sort() ! self.assertEqual(ikeys, keys) ! # Test setdefault ! t = UserDict.UserDict() ! self.assertEqual(t.setdefault("x", 42), 42) ! self.assert_(t.has_key("x")) ! self.assertEqual(t.setdefault("x", 23), 42) ! # Test pop ! t = UserDict.UserDict(x=42) ! self.assertEqual(t.pop("x"), 42) ! self.assertRaises(KeyError, t.pop, "x") ! # Test popitem ! t = UserDict.UserDict(x=42) ! self.assertEqual(t.popitem(), ("x", 42)) ! self.assertRaises(KeyError, t.popitem) ########################## # Test Dict Mixin ! class SeqDict(UserDict.DictMixin): """Dictionary lookalike implemented with lists. *************** *** 172,237 **** return list(self.keylist) ! ## Setup test and verify working of the test class ! s = SeqDict() # check init ! s[10] = 'ten' # exercise setitem ! s[20] = 'twenty' ! s[30] = 'thirty' ! del s[20] # exercise delitem ! verify(s[10] == 'ten') # check getitem and setitem ! verify(s.keys() == [10, 30]) # check keys() and delitem ! ## Now, test the DictMixin methods one by one ! verify(s.has_key(10)) # has_key ! verify(not s.has_key(20)) ! verify(10 in s) # __contains__ ! verify(20 not in s) ! verify([k for k in s] == [10, 30]) # __iter__ ! verify(len(s) == 2) # __len__ ! verify(list(s.iteritems()) == [(10,'ten'), (30, 'thirty')]) # iteritems ! verify(list(s.iterkeys()) == [10, 30]) # iterkeys ! verify(list(s.itervalues()) == ['ten', 'thirty']) # itervalues ! verify(s.values() == ['ten', 'thirty']) # values ! verify(s.items() == [(10,'ten'), (30, 'thirty')]) # items ! verify(s.get(10) == 'ten') # get ! verify(s.get(15,'fifteen') == 'fifteen') ! verify(s.get(15) == None) ! verify(s.setdefault(40, 'forty') == 'forty') # setdefault ! verify(s.setdefault(10, 'null') == 'ten') ! del s[40] ! verify(s.pop(10) == 'ten') # pop ! verify(10 not in s) ! s[10] = 'ten' ! k, v = s.popitem() # popitem ! verify(k not in s) ! s[k] = v ! s.clear() # clear ! verify(len(s) == 0) ! try: # empty popitem ! s.popitem() ! except KeyError: ! pass ! else: ! verify(0, "popitem from an empty list should raise KeyError") ! s.update({10: 'ten', 20:'twenty'}) # update ! verify(s[10]=='ten' and s[20]=='twenty') ! verify(s == {10: 'ten', 20:'twenty'}) # cmp ! t = SeqDict() ! t[20] = 'twenty' ! t[10] = 'ten' ! verify(s == t) --- 180,277 ---- return list(self.keylist) ! class UserDictMixinTest(unittest.TestCase): ! def test_all(self): ! ## Setup test and verify working of the test class ! # check init ! s = SeqDict() ! # exercise setitem ! s[10] = 'ten' ! s[20] = 'twenty' ! s[30] = 'thirty' ! # exercise delitem ! del s[20] ! # check getitem and setitem ! self.assertEqual(s[10], 'ten') ! # check keys() and delitem ! self.assertEqual(s.keys(), [10, 30]) ! ## Now, test the DictMixin methods one by one ! # has_key ! self.assert_(s.has_key(10)) ! self.assert_(not s.has_key(20)) ! # __contains__ ! self.assert_(10 in s) ! self.assert_(20 not in s) ! # __iter__ ! self.assertEqual([k for k in s], [10, 30]) ! # __len__ ! self.assertEqual(len(s), 2) ! # iteritems ! self.assertEqual(list(s.iteritems()), [(10,'ten'), (30, 'thirty')]) ! # iterkeys ! self.assertEqual(list(s.iterkeys()), [10, 30]) ! # itervalues ! self.assertEqual(list(s.itervalues()), ['ten', 'thirty']) ! # values ! self.assertEqual(s.values(), ['ten', 'thirty']) ! # items ! self.assertEqual(s.items(), [(10,'ten'), (30, 'thirty')]) ! # get ! self.assertEqual(s.get(10), 'ten') ! self.assertEqual(s.get(15,'fifteen'), 'fifteen') ! self.assertEqual(s.get(15), None) ! # setdefault ! self.assertEqual(s.setdefault(40, 'forty'), 'forty') ! self.assertEqual(s.setdefault(10, 'null'), 'ten') ! del s[40] ! # pop ! self.assertEqual(s.pop(10), 'ten') ! self.assert_(10 not in s) ! s[10] = 'ten' ! # popitem ! k, v = s.popitem() ! self.assert_(k not in s) ! s[k] = v ! # clear ! s.clear() ! self.assertEqual(len(s), 0) ! ! # empty popitem ! self.assertRaises(KeyError, s.popitem) ! ! # update ! s.update({10: 'ten', 20:'twenty'}) ! self.assertEqual(s[10], 'ten') ! self.assertEqual(s[20], 'twenty') ! ! # cmp ! self.assertEqual(s, {10: 'ten', 20:'twenty'}) ! t = SeqDict() ! t[20] = 'twenty' ! t[10] = 'ten' ! self.assertEqual(s, t) ! ! def test_main(): ! suite = unittest.TestSuite() ! suite.addTest(unittest.makeSuite(UserDictTest)) ! suite.addTest(unittest.makeSuite(UserDictMixinTest)) ! test.test_support.run_suite(suite) ! ! if __name__ == "__main__": ! test_main() From bwarsaw@users.sourceforge.net Mon Jan 20 01:13:23 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sun, 19 Jan 2003 17:13:23 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv17509 Modified Files: Makefile.pre.in Log Message: Install email/test, email/test/data and bsddb/test subdirectories. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.109 retrieving revision 1.110 diff -C2 -d -r1.109 -r1.110 *** Makefile.pre.in 3 Jan 2003 20:39:29 -0000 1.109 --- Makefile.pre.in 20 Jan 2003 01:13:21 -0000 1.110 *************** *** 622,626 **** plat-mac/lib-scriptpackages/Terminal LIBSUBDIRS= lib-old lib-tk site-packages test test/output test/data \ ! encodings email compiler hotshot logging bsddb \ distutils distutils/command $(XMLLIBSUBDIRS) curses $(MACHDEPS) libinstall: $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR) --- 622,627 ---- plat-mac/lib-scriptpackages/Terminal LIBSUBDIRS= lib-old lib-tk site-packages test test/output test/data \ ! encodings email email/test email/test/data compiler hotshot \ ! logging bsddb bsddb/test \ distutils distutils/command $(XMLLIBSUBDIRS) curses $(MACHDEPS) libinstall: $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR) From bwarsaw@users.sourceforge.net Mon Jan 20 02:13:48 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sun, 19 Jan 2003 18:13:48 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.73.4.3,1.73.4.4 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv2987 Modified Files: Tag: release22-maint Makefile.pre.in Log Message: Partial backport from Python 2.3. Be sure to install the email and email/test directories. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.73.4.3 retrieving revision 1.73.4.4 diff -C2 -d -r1.73.4.3 -r1.73.4.4 *** Makefile.pre.in 23 Aug 2002 16:05:49 -0000 1.73.4.3 --- Makefile.pre.in 20 Jan 2003 02:13:45 -0000 1.73.4.4 *************** *** 584,588 **** XMLLIBSUBDIRS= xml xml/dom xml/parsers xml/sax LIBSUBDIRS= lib-old lib-tk site-packages test test/output test/data \ ! encodings email compiler hotshot \ distutils distutils/command $(XMLLIBSUBDIRS) curses $(MACHDEPS) libinstall: $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR) --- 584,588 ---- XMLLIBSUBDIRS= xml xml/dom xml/parsers xml/sax LIBSUBDIRS= lib-old lib-tk site-packages test test/output test/data \ ! encodings email email/test email/test/data compiler hotshot \ distutils distutils/command $(XMLLIBSUBDIRS) curses $(MACHDEPS) libinstall: $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR) From doerwalter@users.sourceforge.net Mon Jan 20 02:34:09 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Sun, 19 Jan 2003 18:34:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_codeccallbacks.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv8946/Lib/test Modified Files: test_codeccallbacks.py Log Message: Add comments and remove duplicate tests. Index: test_codeccallbacks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codeccallbacks.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_codeccallbacks.py 9 Jan 2003 11:38:50 -0000 1.7 --- test_codeccallbacks.py 20 Jan 2003 02:34:07 -0000 1.8 *************** *** 223,227 **** # check with one missing argument self.assertRaises(TypeError, exctype, *args[:-1]) ! # check with one missing argument self.assertRaises(TypeError, exctype, *(args + ["too much"])) # check with one argument of the wrong type --- 223,227 ---- # check with one missing argument self.assertRaises(TypeError, exctype, *args[:-1]) ! # check with one argument too much self.assertRaises(TypeError, exctype, *(args + ["too much"])) # check with one argument of the wrong type *************** *** 239,242 **** --- 239,244 ---- callargs.append(args[i]) self.assertRaises(TypeError, exctype, *callargs) + + # check with the correct number and type of arguments exc = exctype(*args) self.assertEquals(str(exc), msg) *************** *** 284,287 **** --- 286,290 ---- def test_badandgoodstrictexceptions(self): + # "strict" complains about a non-exception passed in self.assertRaises( TypeError, *************** *** 289,292 **** --- 292,296 ---- 42 ) + # "strict" complains about the wrong exception type self.assertRaises( Exception, *************** *** 295,298 **** --- 299,303 ---- ) + # If the correct exception is passed in, "strict" raises it self.assertRaises( UnicodeEncodeError, *************** *** 302,305 **** --- 307,311 ---- def test_badandgoodignoreexceptions(self): + # "ignore" complains about a non-exception passed in self.assertRaises( TypeError, *************** *** 307,310 **** --- 313,317 ---- 42 ) + # "ignore" complains about the wrong exception type self.assertRaises( TypeError, *************** *** 312,315 **** --- 319,323 ---- UnicodeError("ouch") ) + # If the correct exception is passed in, "ignore" returns an empty replacement self.assertEquals( codecs.ignore_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")), *************** *** 326,329 **** --- 334,338 ---- def test_badandgoodreplaceexceptions(self): + # "replace" complains about a non-exception passed in self.assertRaises( TypeError, *************** *** 331,334 **** --- 340,344 ---- 42 ) + # "replace" complains about the wrong exception type self.assertRaises( TypeError, *************** *** 336,339 **** --- 346,350 ---- UnicodeError("ouch") ) + # With the correct exception, "ignore" returns an empty replacement self.assertEquals( codecs.replace_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")), *************** *** 350,353 **** --- 361,365 ---- def test_badandgoodxmlcharrefreplaceexceptions(self): + # "xmlcharrefreplace" complains about a non-exception passed in self.assertRaises( TypeError, *************** *** 355,358 **** --- 367,371 ---- 42 ) + # "xmlcharrefreplace" complains about the wrong exception types self.assertRaises( TypeError, *************** *** 360,372 **** UnicodeError("ouch") ) ! self.assertEquals( ! codecs.xmlcharrefreplace_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")), ! (u"&#%d;" % 0x3042, 1) ! ) ! self.assertRaises( ! TypeError, ! codecs.xmlcharrefreplace_errors, ! UnicodeError("ouch") ! ) self.assertRaises( TypeError, --- 373,377 ---- UnicodeError("ouch") ) ! # "xmlcharrefreplace" can only be used for encoding self.assertRaises( TypeError, *************** *** 379,384 **** --- 384,395 ---- UnicodeTranslateError(u"\u3042", 0, 1, "ouch") ) + # Use the correct exception + self.assertEquals( + codecs.xmlcharrefreplace_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")), + (u"&#%d;" % 0x3042, 1) + ) def test_badandgoodbackslashreplaceexceptions(self): + # "backslashreplace" complains about a non-exception passed in self.assertRaises( TypeError, *************** *** 386,389 **** --- 397,401 ---- 42 ) + # "backslashreplace" complains about the wrong exception types self.assertRaises( TypeError, *************** *** 391,394 **** --- 403,418 ---- UnicodeError("ouch") ) + # "backslashreplace" can only be used for encoding + self.assertRaises( + TypeError, + codecs.backslashreplace_errors, + UnicodeDecodeError("ascii", "\xff", 0, 1, "ouch") + ) + self.assertRaises( + TypeError, + codecs.backslashreplace_errors, + UnicodeTranslateError(u"\u3042", 0, 1, "ouch") + ) + # Use the correct exception self.assertEquals( codecs.backslashreplace_errors(UnicodeEncodeError("ascii", u"\u3042", 0, 1, "ouch")), *************** *** 420,439 **** (u"\\U0010ffff", 1) ) - - self.assertRaises( - TypeError, - codecs.backslashreplace_errors, - UnicodeError("ouch") - ) - self.assertRaises( - TypeError, - codecs.backslashreplace_errors, - UnicodeDecodeError("ascii", "\xff", 0, 1, "ouch") - ) - self.assertRaises( - TypeError, - codecs.backslashreplace_errors, - UnicodeTranslateError(u"\u3042", 0, 1, "ouch") - ) def test_badhandlerresults(self): --- 444,447 ---- From jvr@users.sourceforge.net Mon Jan 20 09:02:27 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Mon, 20 Jan 2003 01:02:27 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE PyConsole.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv4133 Modified Files: PyConsole.py Log Message: Fix bug #670845: cut & clear in the output window now work, in that - clear clears the entire buffer - cut doesn't cut, but copies. Index: PyConsole.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyConsole.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** PyConsole.py 30 Nov 2002 00:01:25 -0000 1.12 --- PyConsole.py 20 Jan 2003 09:02:23 -0000 1.13 *************** *** 250,253 **** --- 250,259 ---- fss.SetCreatorType(W._signature, 'TEXT') + def domenu_cut(self, *args): + self.domenu_copy(*args) + + def domenu_clear(self, *args): + self.set('') + class PyOutput: From jackjansen@users.sourceforge.net Mon Jan 20 10:47:52 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 20 Jan 2003 02:47:52 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.110,1.111 configure.in,1.385,1.386 configure,1.374,1.375 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv26667 Modified Files: Makefile.pre.in configure.in configure Log Message: On MacOSX, added -prebind option to link phase for executable (and framework, if applicable). This speeds up startup time by up to 50%. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** Makefile.pre.in 20 Jan 2003 01:13:21 -0000 1.110 --- Makefile.pre.in 20 Jan 2003 10:47:47 -0000 1.111 *************** *** 108,111 **** --- 108,113 ---- PYTHONFRAMEWORKPREFIX= @PYTHONFRAMEWORKPREFIX@ PYTHONFRAMEWORKINSTALLDIR= @PYTHONFRAMEWORKINSTALLDIR@ + # Options to enable prebinding (for fast startup) + OTHER_LIBTOOL_OPT = -prebind -seg1addr 0x10000000 # Environment to run shared python without installed libraries Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.385 retrieving revision 1.386 diff -C2 -d -r1.385 -r1.386 *** configure.in 7 Jan 2003 22:42:45 -0000 1.385 --- configure.in 20 Jan 2003 10:47:47 -0000 1.386 *************** *** 1165,1169 **** # not used by the core itself but which needs to be in the core so # that dynamically loaded extension modules have access to it. ! LINKFORSHARED="$extra_undefs -framework System" if test "$enable_framework" then --- 1165,1173 ---- # not used by the core itself but which needs to be in the core so # that dynamically loaded extension modules have access to it. ! # -prebind causes the executable to assume dynamic libraries are at their ! # preferred address, which speeds up startup. We specify it here ! # in stead of in LDFLAGS because it does not seem to work for bundle ! # plugins (as of OSX 10.2). ! LINKFORSHARED="$extra_undefs -framework System -prebind" if test "$enable_framework" then Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.374 retrieving revision 1.375 diff -C2 -d -r1.374 -r1.375 *** configure 7 Jan 2003 22:42:04 -0000 1.374 --- configure 20 Jan 2003 10:47:48 -0000 1.375 *************** *** 1,4 **** #! /bin/sh ! # From configure.in Revision: 1.384 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. --- 1,4 ---- #! /bin/sh ! # From configure.in Revision: 1.385 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. *************** *** 9444,9448 **** # not used by the core itself but which needs to be in the core so # that dynamically loaded extension modules have access to it. ! LINKFORSHARED="$extra_undefs -framework System" if test "$enable_framework" then --- 9444,9452 ---- # not used by the core itself but which needs to be in the core so # that dynamically loaded extension modules have access to it. ! # -prebind causes the executable to assume dynamic libraries are at their ! # preferred address, which speeds up startup. We specify it here ! # in stead of in LDFLAGS because it does not seem to work for bundle ! # plugins (as of OSX 10.2). ! LINKFORSHARED="$extra_undefs -framework System -prebind" if test "$enable_framework" then From tim_one@users.sourceforge.net Mon Jan 20 16:55:04 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 20 Jan 2003 08:55:04 -0800 Subject: [Python-checkins] python/dist/src/Objects object.c,2.195,2.196 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv19080/python/Objects Modified Files: object.c Log Message: Recursive compare machinery: The code that intended to exempt tuples was broken because new-in-2.3 code added a tp_as_mapping slot to tuples. Repaired that. Added basic docs to check_recursion(). The code that intended to exempt tuples and strings was also broken here, and in 2.2: these should use PyXYZ_CheckExact(), not PyXYZ_Check() -- we can't know whether subclass instances are immutable. This part (and this part alone) is a bugfix candidate. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.195 retrieving revision 2.196 diff -C2 -d -r2.195 -r2.196 *** object.c 13 Jan 2003 20:13:04 -0000 2.195 --- object.c 20 Jan 2003 16:54:59 -0000 2.196 *************** *** 743,746 **** --- 743,754 ---- } + /* If the comparison "v op w" is already in progress in this thread, returns + * a borrowed reference to Py_None (the caller must not decref). + * If it's not already in progress, returns "a token" which must eventually + * be passed to delete_token(). The caller must not decref this either + * (delete_token decrefs it). The token must not survive beyond any point + * where v or w may die. + * If an error occurs (out-of-memory), returns NULL. + */ static PyObject * check_recursion(PyObject *v, PyObject *w, int op) *************** *** 831,838 **** compare_nesting++; if (compare_nesting > NESTING_LIMIT && ! (vtp->tp_as_mapping ! || (vtp->tp_as_sequence ! && !PyString_Check(v) ! && !PyTuple_Check(v)))) { /* try to detect circular data structures */ PyObject *token = check_recursion(v, w, -1); --- 839,845 ---- compare_nesting++; if (compare_nesting > NESTING_LIMIT && ! (vtp->tp_as_mapping || vtp->tp_as_sequence) && ! !PyString_CheckExact(v) && ! !PyTuple_CheckExact(v)) { /* try to detect circular data structures */ PyObject *token = check_recursion(v, w, -1); *************** *** 928,936 **** compare_nesting++; if (compare_nesting > NESTING_LIMIT && ! (v->ob_type->tp_as_mapping ! || (v->ob_type->tp_as_sequence ! && !PyString_Check(v) ! && !PyTuple_Check(v)))) { ! /* try to detect circular data structures */ PyObject *token = check_recursion(v, w, op); --- 935,941 ---- compare_nesting++; if (compare_nesting > NESTING_LIMIT && ! (v->ob_type->tp_as_mapping || v->ob_type->tp_as_sequence) && ! !PyString_CheckExact(v) && ! !PyTuple_CheckExact(v)) { /* try to detect circular data structures */ PyObject *token = check_recursion(v, w, op); From tim_one@users.sourceforge.net Mon Jan 20 22:06:55 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 20 Jan 2003 14:06:55 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime EU.py,1.4,1.5 US.py,1.17,1.18 datetime.py,1.145,1.146 test_datetime.py,1.98,1.99 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv30918 Modified Files: EU.py US.py datetime.py test_datetime.py Log Message: New rule for tzinfo subclasses handling both standard and daylight time: When daylight time ends, an hour repeats on the local clock (for example, in US Eastern, the clock jumps from 1:59 back to 1:00 again). Times in the repeated hour are ambiguous. A tzinfo subclass that wants to play with astimezone() needs to treat times in the repeated hour as being standard time. astimezone() previously required that such times be treated as daylight time. There seems no killer argument either way, but Guido wants the standard-time version, and it does seem easier the new way to code both American (local-time based) and European (UTC-based) switch rules, and the astimezone() implementation is simpler. Index: EU.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/EU.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** EU.py 8 Jan 2003 19:43:44 -0000 1.4 --- EU.py 20 Jan 2003 22:06:37 -0000 1.5 *************** *** 164,167 **** --- 164,193 ---- calendar in Thomas Pynchon's Mason & Dixon.) + + 1. Amsterdam standard time is UTC + 1:00; Amsterdam DST is UTC + 2:00. + + 2. The DST switch in Amsterdam happens at 1:00:00 UTC == 2:00:00 + standard time == 3:00:00 DST. + + 3. The unspellable hour is the last hour of DST. + + 4. So the unspellable hour is 0:HH:MM UTC. + + 5. Expressed in local time, the unspellable hour is 2:HH:MM DST, which + is indeed the last hour of DST. + + 5. This is indeed unspellable; the Amsterdam tzinfo object calls + 2:HH:MM standard time. + + 6. So at 0:HH:MM UTC, clocks in Amsterdam show 2:HH:MM DST. + + >>> print datetime(2002, 10, 26, 23, 0, 0, tzinfo=UTC).astimezone(Amsterdam) + 2002-10-27 01:00:00+02:00 + >>> print datetime(2002, 10, 27, 0, 0, 0, tzinfo=UTC).astimezone(Amsterdam) + 2002-10-27 02:00:00+01:00 + >>> print datetime(2002, 10, 27, 1, 0, 0, tzinfo=UTC).astimezone(Amsterdam) + 2002-10-27 02:00:00+01:00 + >>> + """ __test__ = {'demo': demo} Index: US.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/US.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** US.py 8 Jan 2003 19:43:45 -0000 1.17 --- US.py 20 Jan 2003 22:06:38 -0000 1.18 *************** *** 32,40 **** # one-hour gap between those in UTC. # ! # The implementation can't win, so this one arbitrarily decides to call ! # 1:MM:SS DST (I expect that's what most people would expect). A ! # consequence of the "missing hour" (under either choice) is that ! # UTC -> this timezone -> UTC can't always be an identity (some one-hour ! # range of UTC times simply can't be spelled in this timezone). # # On the other end, when DST starts at 2am on the first Sunday in April, --- 32,39 ---- # one-hour gap between those in UTC. # ! # The implementation can't win, so we decided to call 1:MM:SS standard ! # time. A# consequence of the "missing hour" (under either choice) is ! # that UTC -> this timezone -> UTC can't always be an identity (some ! # one-hour range of UTC times simply can't be spelled in this timezone). # # On the other end, when DST starts at 2am on the first Sunday in April, *************** *** 51,55 **** start = datetime(1, APRIL, 1, 2) # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct. ! end = datetime(1, OCTOBER, 1, 2) def __init__(self, stdhours, stdname, dstname): --- 50,54 ---- start = datetime(1, APRIL, 1, 2) # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct. ! end = datetime(1, OCTOBER, 1, 1) def __init__(self, stdhours, stdname, dstname): *************** *** 170,193 **** Now right before DST ends. ! >>> before = datetime(2002, 10, 27, 1, 59, 59, tzinfo=Eastern) >>> printstuff(before) ! 2002-10-27 01:59:59-04:00 EDT ! (2002, 10, 27, 1, 59, 59, 6, 300, 1) ! Sun Oct 27 01:59:59 2002 And right when DST ends. >>> after = before + timedelta(seconds=1) >>> printstuff(after) ! 2002-10-27 02:00:00-05:00 EST ! (2002, 10, 27, 2, 0, 0, 6, 300, 0) ! Sun Oct 27 02:00:00 2002 ! The naive clock repeats the times in 1:HH:MM, so 1:59:59 was actually ! ambiguous, and resolved arbitrarily as being in DST. 2:00:00 is in standard ! time, and is actually about an hour later. Again, because these have the ! same tzinfo member, the utcoffsets are ignored by straight subtraction, ! but revealed by converting to UTC first: >>> print after - before --- 169,191 ---- Now right before DST ends. ! >>> before = datetime(2002, 10, 27, 0, 59, 59, tzinfo=Eastern) >>> printstuff(before) ! 2002-10-27 00:59:59-04:00 EDT ! (2002, 10, 27, 0, 59, 59, 6, 300, 1) ! Sun Oct 27 00:59:59 2002 And right when DST ends. >>> after = before + timedelta(seconds=1) >>> printstuff(after) ! 2002-10-27 01:00:00-05:00 EST ! (2002, 10, 27, 1, 0, 0, 6, 300, 0) ! Sun Oct 27 01:00:00 2002 ! The naive clock repeats the times in 1:HH:MM, so 1:00:00 was actually ! ambiguous, and resolved as being in EST, and is actually about an hour later. ! Again, because these have the same tzinfo member, the utcoffsets are ignored ! by straight subtraction, but revealed by converting to UTC first: >>> print after - before *************** *** 197,209 **** One more glitch: that one-hour gap contains times that can't be represented ! in Eastern (all times of the form 6:MM:SS UTC on this day). Here's one of them: >>> phantom = before.astimezone(utc) + timedelta(seconds=1) >>> printstuff(phantom) ! 2002-10-27 06:00:00+00:00 utc ! (2002, 10, 27, 6, 0, 0, 6, 300, 0) ! Sun Oct 27 06:00:00 2002 What happens when we convert that to Eastern? astimezone detects the --- 195,207 ---- One more glitch: that one-hour gap contains times that can't be represented ! in Eastern (all times of the form 5:MM:SS UTC on this day). Here's one of them: >>> phantom = before.astimezone(utc) + timedelta(seconds=1) >>> printstuff(phantom) ! 2002-10-27 05:00:00+00:00 utc ! (2002, 10, 27, 5, 0, 0, 6, 300, 0) ! Sun Oct 27 05:00:00 2002 What happens when we convert that to Eastern? astimezone detects the *************** *** 213,224 **** >>> paradox = phantom.astimezone(Eastern) >>> printstuff(paradox) ! 2002-10-27 01:00:00-04:00 ! EDT ! (2002, 10, 27, 1, 0, 0, 6, 300, 1) Sun Oct 27 01:00:00 2002 ! That isn't a UTC equivalent, although it would be if 1:00 were taken as being ! in EST. ! """ __test__ = {'brainbuster': brainbuster_test} --- 211,235 ---- >>> paradox = phantom.astimezone(Eastern) >>> printstuff(paradox) ! 2002-10-27 01:00:00-05:00 ! EST ! (2002, 10, 27, 1, 0, 0, 6, 300, 0) Sun Oct 27 01:00:00 2002 ! The UTC hour after also converts to 1:00 Eastern. The one above is really ! 1:00 EDT, and the one below really 1:00 EST, but Eastern can't tell the ! difference: ! ! >>> phantom += timedelta(hours=1) ! >>> printstuff(phantom) ! 2002-10-27 06:00:00+00:00 ! utc ! (2002, 10, 27, 6, 0, 0, 6, 300, 0) ! Sun Oct 27 06:00:00 2002 ! >>> printstuff(phantom.astimezone(Eastern)) ! 2002-10-27 01:00:00-05:00 ! EST ! (2002, 10, 27, 1, 0, 0, 6, 300, 0) ! Sun Oct 27 01:00:00 2002 ! """ __test__ = {'brainbuster': brainbuster_test} Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.145 retrieving revision 1.146 diff -C2 -d -r1.145 -r1.146 *** datetime.py 8 Jan 2003 19:43:45 -0000 1.145 --- datetime.py 20 Jan 2003 22:06:39 -0000 1.146 *************** *** 1317,1320 **** --- 1317,1324 ---- another = other + otdst + return another + + # XXX Leaving this unreachable code here for a while. It may be + # XXX needed again real soon . anotherdst = another.dst() if anotherdst is None: Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -d -r1.98 -r1.99 *** test_datetime.py 11 Jan 2003 03:44:14 -0000 1.98 --- test_datetime.py 20 Jan 2003 22:06:41 -0000 1.99 *************** *** 2560,2565 **** DSTSTART = datetime(1, 4, 1, 2) # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct, ! # which is the first Sunday on or after Oct 25. ! DSTEND = datetime(1, 10, 25, 2) class USTimeZone(tzinfo): --- 2560,2567 ---- DSTSTART = datetime(1, 4, 1, 2) # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct, ! # which is the first Sunday on or after Oct 25. Because we view 1:MM as ! # being standard time on that day, there is no spelling in local time of ! # the last hour of DST (that's 1:MM DST, but 1:MM is taken as standard time). ! DSTEND = datetime(1, 10, 25, 1) class USTimeZone(tzinfo): *************** *** 2615,2621 **** class TestTimezoneConversions(unittest.TestCase): ! # The DST switch times for 2002, in local time. dston = datetime(2002, 4, 7, 2) ! dstoff = datetime(2002, 10, 27, 2) theclass = datetime --- 2617,2623 ---- class TestTimezoneConversions(unittest.TestCase): ! # The DST switch times for 2002, in std time. dston = datetime(2002, 4, 7, 2) ! dstoff = datetime(2002, 10, 27, 1) theclass = datetime *************** *** 2655,2677 **** self.assertEqual(dt, there_and_back) ! # Because we have a redundant spelling when DST begins, ! # there is (unforunately) an hour when DST ends that can't ! # be spelled at all in local time. When DST ends, the ! # clock jumps from 1:59:59 back to 1:00:00 again. The ! # hour beginning then has no spelling in local time: ! # 1:MM:SS is taken to be daylight time, and 2:MM:SS as ! # standard time. The hour 1:MM:SS standard time == ! # 2:MM:SS daylight time can't be expressed in local time. ! # Nevertheless, we want conversion back from UTC to mimic ! # the local clock's "repeat an hour" behavior. nexthour_utc = asutc + HOUR nexthour_tz = nexthour_utc.astimezone(tz) ! if dt.date() == dstoff.date() and dt.hour == 1: ! # We're in the hour before DST ends. The hour after # is ineffable. We want the conversion back to repeat 1:MM. ! expected_diff = ZERO else: ! expected_diff = HOUR ! self.assertEqual(nexthour_tz - dt, expected_diff) # Check a time that's outside DST. --- 2657,2679 ---- self.assertEqual(dt, there_and_back) ! # Because we have a redundant spelling when DST begins, there is ! # (unforunately) an hour when DST ends that can't be spelled at all in ! # local time. When DST ends, the clock jumps from 1:59 back to 1:00 ! # again. The hour 1:MM DST has no spelling then: 1:MM is taken to be ! # standard time. 1:MM DST == 0:MM EST, but 0:MM is taken to be ! # daylight time. The hour 1:MM daylight == 0:MM standard can't be ! # expressed in local time. Nevertheless, we want conversion back ! # from UTC to mimic the local clock's "repeat an hour" behavior. nexthour_utc = asutc + HOUR nexthour_tz = nexthour_utc.astimezone(tz) ! if dt.date() == dstoff.date() and dt.hour == 0: ! # We're in the hour before the last DST hour. The last DST hour # is ineffable. We want the conversion back to repeat 1:MM. ! self.assertEqual(nexthour_tz, dt.replace(hour=1)) ! nexthour_utc += HOUR ! nexthour_tz = nexthour_utc.astimezone(tz) ! self.assertEqual(nexthour_tz, dt.replace(hour=1)) else: ! self.assertEqual(nexthour_tz - dt, HOUR) # Check a time that's outside DST. *************** *** 2686,2689 **** --- 2688,2696 ---- def convert_between_tz_and_utc(self, tz, utc): dston = self.dston.replace(tzinfo=tz) + # Because 1:MM on the day DST ends is taken as being standard time, + # there is no spelling in tz for the last hour of daylight time. + # For purposes of the test, the last hour of DST is 0:MM, which is + # taken as being daylight time (and 1:MM is taken as being standard + # time). dstoff = self.dstoff.replace(tzinfo=tz) for delta in (timedelta(weeks=13), *************** *** 2758,2762 **** for utc in utc_real, utc_fake: for tz in Eastern, Pacific: ! first_std_hour = self.dstoff - timedelta(hours=3) # 23:MM # Convert that to UTC. first_std_hour -= tz.utcoffset(None) --- 2765,2769 ---- for utc in utc_real, utc_fake: for tz in Eastern, Pacific: ! first_std_hour = self.dstoff - timedelta(hours=2) # 23:MM # Convert that to UTC. first_std_hour -= tz.utcoffset(None) From tim_one@users.sourceforge.net Mon Jan 20 22:54:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 20 Jan 2003 14:54:40 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv20501/python/Modules Modified Files: datetimemodule.c Log Message: New rule for tzinfo subclasses handling both standard and daylight time: When daylight time ends, an hour repeats on the local clock (for example, in US Eastern, the clock jumps from 1:59 back to 1:00 again). Times in the repeated hour are ambiguous. A tzinfo subclass that wants to play with astimezone() needs to treat times in the repeated hour as being standard time. astimezone() previously required that such times be treated as daylight time. There seems no killer argument either way, but Guido wants the standard-time version, and it does seem easier the new way to code both American (local-time based) and European (UTC-based) switch rules, and the astimezone() implementation is simpler. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** datetimemodule.c 11 Jan 2003 03:39:11 -0000 1.40 --- datetimemodule.c 20 Jan 2003 22:54:38 -0000 1.41 *************** *** 4047,4051 **** PyObject *result; PyObject *temp; ! int selfoff, resoff, dst1, dst2; int none; int delta; --- 4047,4051 ---- PyObject *result; PyObject *temp; ! int selfoff, resoff, dst1; int none; int delta; *************** *** 4129,4152 **** if (temp == NULL) goto Fail; ! ! dst2 = call_dst(tzinfo, temp, &none); ! if (dst2 == -1 && PyErr_Occurred()) { ! Py_DECREF(temp); ! goto Fail; ! } ! if (none) { ! Py_DECREF(temp); ! goto Inconsistent; ! } ! ! if (dst1 == dst2) { ! /* The normal case: we want temp, not result. */ ! Py_DECREF(result); ! result = temp; ! } ! else { ! /* The "unspellable hour" at the end of DST. */ ! Py_DECREF(temp); ! } return result; --- 4129,4134 ---- if (temp == NULL) goto Fail; ! Py_DECREF(result); ! result = temp; return result; From tim_one@users.sourceforge.net Mon Jan 20 22:54:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 20 Jan 2003 14:54:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv20501/python/Lib/test Modified Files: test_datetime.py Log Message: New rule for tzinfo subclasses handling both standard and daylight time: When daylight time ends, an hour repeats on the local clock (for example, in US Eastern, the clock jumps from 1:59 back to 1:00 again). Times in the repeated hour are ambiguous. A tzinfo subclass that wants to play with astimezone() needs to treat times in the repeated hour as being standard time. astimezone() previously required that such times be treated as daylight time. There seems no killer argument either way, but Guido wants the standard-time version, and it does seem easier the new way to code both American (local-time based) and European (UTC-based) switch rules, and the astimezone() implementation is simpler. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** test_datetime.py 11 Jan 2003 03:39:11 -0000 1.25 --- test_datetime.py 20 Jan 2003 22:54:38 -0000 1.26 *************** *** 2562,2567 **** DSTSTART = datetime(1, 4, 1, 2) # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct, ! # which is the first Sunday on or after Oct 25. ! DSTEND = datetime(1, 10, 25, 2) class USTimeZone(tzinfo): --- 2562,2569 ---- DSTSTART = datetime(1, 4, 1, 2) # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct, ! # which is the first Sunday on or after Oct 25. Because we view 1:MM as ! # being standard time on that day, there is no spelling in local time of ! # the last hour of DST (that's 1:MM DST, but 1:MM is taken as standard time). ! DSTEND = datetime(1, 10, 25, 1) class USTimeZone(tzinfo): *************** *** 2617,2623 **** class TestTimezoneConversions(unittest.TestCase): ! # The DST switch times for 2002, in local time. dston = datetime(2002, 4, 7, 2) ! dstoff = datetime(2002, 10, 27, 2) theclass = datetime --- 2619,2625 ---- class TestTimezoneConversions(unittest.TestCase): ! # The DST switch times for 2002, in std time. dston = datetime(2002, 4, 7, 2) ! dstoff = datetime(2002, 10, 27, 1) theclass = datetime *************** *** 2657,2679 **** self.assertEqual(dt, there_and_back) ! # Because we have a redundant spelling when DST begins, ! # there is (unforunately) an hour when DST ends that can't ! # be spelled at all in local time. When DST ends, the ! # clock jumps from 1:59:59 back to 1:00:00 again. The ! # hour beginning then has no spelling in local time: ! # 1:MM:SS is taken to be daylight time, and 2:MM:SS as ! # standard time. The hour 1:MM:SS standard time == ! # 2:MM:SS daylight time can't be expressed in local time. ! # Nevertheless, we want conversion back from UTC to mimic ! # the local clock's "repeat an hour" behavior. nexthour_utc = asutc + HOUR nexthour_tz = nexthour_utc.astimezone(tz) ! if dt.date() == dstoff.date() and dt.hour == 1: ! # We're in the hour before DST ends. The hour after # is ineffable. We want the conversion back to repeat 1:MM. ! expected_diff = ZERO else: ! expected_diff = HOUR ! self.assertEqual(nexthour_tz - dt, expected_diff) # Check a time that's outside DST. --- 2659,2681 ---- self.assertEqual(dt, there_and_back) ! # Because we have a redundant spelling when DST begins, there is ! # (unforunately) an hour when DST ends that can't be spelled at all in ! # local time. When DST ends, the clock jumps from 1:59 back to 1:00 ! # again. The hour 1:MM DST has no spelling then: 1:MM is taken to be ! # standard time. 1:MM DST == 0:MM EST, but 0:MM is taken to be ! # daylight time. The hour 1:MM daylight == 0:MM standard can't be ! # expressed in local time. Nevertheless, we want conversion back ! # from UTC to mimic the local clock's "repeat an hour" behavior. nexthour_utc = asutc + HOUR nexthour_tz = nexthour_utc.astimezone(tz) ! if dt.date() == dstoff.date() and dt.hour == 0: ! # We're in the hour before the last DST hour. The last DST hour # is ineffable. We want the conversion back to repeat 1:MM. ! self.assertEqual(nexthour_tz, dt.replace(hour=1)) ! nexthour_utc += HOUR ! nexthour_tz = nexthour_utc.astimezone(tz) ! self.assertEqual(nexthour_tz, dt.replace(hour=1)) else: ! self.assertEqual(nexthour_tz - dt, HOUR) # Check a time that's outside DST. *************** *** 2688,2691 **** --- 2690,2698 ---- def convert_between_tz_and_utc(self, tz, utc): dston = self.dston.replace(tzinfo=tz) + # Because 1:MM on the day DST ends is taken as being standard time, + # there is no spelling in tz for the last hour of daylight time. + # For purposes of the test, the last hour of DST is 0:MM, which is + # taken as being daylight time (and 1:MM is taken as being standard + # time). dstoff = self.dstoff.replace(tzinfo=tz) for delta in (timedelta(weeks=13), *************** *** 2760,2764 **** for utc in utc_real, utc_fake: for tz in Eastern, Pacific: ! first_std_hour = self.dstoff - timedelta(hours=3) # 23:MM # Convert that to UTC. first_std_hour -= tz.utcoffset(None) --- 2767,2771 ---- for utc in utc_real, utc_fake: for tz in Eastern, Pacific: ! first_std_hour = self.dstoff - timedelta(hours=2) # 23:MM # Convert that to UTC. first_std_hour -= tz.utcoffset(None) From tim_one@users.sourceforge.net Mon Jan 20 22:54:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 20 Jan 2003 14:54:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.34,1.35 tzinfo-examples.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv20501/python/Doc/lib Modified Files: libdatetime.tex tzinfo-examples.py Log Message: New rule for tzinfo subclasses handling both standard and daylight time: When daylight time ends, an hour repeats on the local clock (for example, in US Eastern, the clock jumps from 1:59 back to 1:00 again). Times in the repeated hour are ambiguous. A tzinfo subclass that wants to play with astimezone() needs to treat times in the repeated hour as being standard time. astimezone() previously required that such times be treated as daylight time. There seems no killer argument either way, but Guido wants the standard-time version, and it does seem easier the new way to code both American (local-time based) and European (UTC-based) switch rules, and the astimezone() implementation is simpler. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** libdatetime.tex 9 Jan 2003 13:46:30 -0000 1.34 --- libdatetime.tex 20 Jan 2003 22:54:38 -0000 1.35 *************** *** 31,35 **** For applications requiring more, \class{datetime} and \class{time} objects have an optional time zone information member, ! \member{tzinfo}, that can contain an instance of a subclass of the abstract \class{tzinfo} class. These \class{tzinfo} objects capture information about the offset from UTC time, the time zone --- 31,35 ---- For applications requiring more, \class{datetime} and \class{time} objects have an optional time zone information member, ! \member{tzinfo}, that can contain an instance of a subclass of the abstract \class{tzinfo} class. These \class{tzinfo} objects capture information about the offset from UTC time, the time zone *************** *** 1049,1054 **** If \method{utcoffset()} does not return \code{None}, \method{dst()} should not return \code{None} either. - \end{methoddesc} \begin{methoddesc}{dst}{self, dt} --- 1049,1056 ---- If \method{utcoffset()} does not return \code{None}, \method{dst()} should not return \code{None} either. + The default implementation of \method{utcoffset()} raises + \exception{NotImplementedError}. + \end{methoddesc} \begin{methoddesc}{dst}{self, dt} *************** *** 1061,1065 **** already been added to the UTC offset returned by \method{utcoffset()}, so there's no need to consult \method{dst()} ! unless you're interested in displaying DST info separately. For example, \method{datetime.timetuple()} calls its \member{tzinfo} member's \method{dst()} method to determine how the --- 1063,1067 ---- already been added to the UTC offset returned by \method{utcoffset()}, so there's no need to consult \method{dst()} ! unless you're interested in obtaining DST info separately. For example, \method{datetime.timetuple()} calls its \member{tzinfo} member's \method{dst()} method to determine how the *************** *** 1081,1084 **** --- 1083,1090 ---- ensure it. + The default implementation of \method{dst()} raises + \exception{NotImplementedError}. + \end{methoddesc} + \begin{methoddesc}{tzname}{self, dt} Return the timezone name corresponding to the \class{datetime} *************** *** 1093,1098 **** of \var{dt} passed, especially if the \class{tzinfo} class is accounting for daylight time. - \end{methoddesc} \end{methoddesc} --- 1099,1105 ---- of \var{dt} passed, especially if the \class{tzinfo} class is accounting for daylight time. + The default implementation of \method{tzname()} raises + \exception{NotImplementedError}. \end{methoddesc} *************** *** 1107,1112 **** best response. For example, returning \code{None} is appropriate if the class wishes to say that time objects don't participate in the ! \class{tzinfo} protocol. In other applications, it may be more useful ! for \code{utcoffset(None)} to return the standard UTC offset. When a \class{datetime} object is passed in response to a --- 1114,1120 ---- best response. For example, returning \code{None} is appropriate if the class wishes to say that time objects don't participate in the ! \class{tzinfo} protocol. It may be more useful for \code{utcoffset(None)} ! to return the standard UTC offset, as there is no other convention for ! discovering the standard offset. When a \class{datetime} object is passed in response to a *************** *** 1115,1119 **** user code calls \class{tzinfo} methods directly. The intent is that the \class{tzinfo} methods interpret \var{dt} as being in local time, ! and not need to worry about objects in other timezones. Example \class{tzinfo} classes: --- 1123,1127 ---- user code calls \class{tzinfo} methods directly. The intent is that the \class{tzinfo} methods interpret \var{dt} as being in local time, ! and not need worry about objects in other timezones. Example \class{tzinfo} classes: *************** *** 1121,1125 **** \verbatiminput{tzinfo-examples.py} ! Note that there are unavoidable subtleties twice per year in a tzinfo subclass accounting for both standard and daylight time, at the DST transition points. For concreteness, consider US Eastern (UTC -0500), --- 1129,1134 ---- \verbatiminput{tzinfo-examples.py} ! Note that there are unavoidable subtleties twice per year in a ! \class{tzinfo} subclass accounting for both standard and daylight time, at the DST transition points. For concreteness, consider US Eastern (UTC -0500), *************** *** 1141,1170 **** day, so \code{astimezone(Eastern)} won't deliver a result with \code{hour==2} on the ! day DST begins. How an Eastern instance chooses to interpret 2:MM on ! that day is its business. The example Eastern implementation above ! chose to ! consider it as a time in EDT, simply because it "looks like it's ! after 2:00", and so synonymous with the EST 1:MM times on that day. ! Your Eastern class may wish, for example, to raise an exception instead ! when it sees a 2:MM time on the day EDT begins. When DST ends (the "end" line), there's a potentially worse problem: ! there's an hour that can't be spelled unambiguously in local wall time, the ! hour beginning at the moment DST ends. In this example, that's times of ! the form 6:MM UTC on the day daylight time ends. The local wall clock leaps from 1:59 (daylight time) back to 1:00 (standard time) again. ! 1:MM is taken as daylight time (it's "before 2:00"), so maps to 5:MM UTC. ! 2:MM is taken as standard time (it's "after 2:00"), so maps to 7:MM UTC. ! There is no local time that maps to 6:MM UTC on this day. ! Just as the wall clock does, \code{astimezone(Eastern)} maps both UTC ! hours 5:MM ! and 6:MM to Eastern hour 1:MM on this day. However, this result is ! ambiguous (there's no way for Eastern to know which repetition of 1:MM ! is intended). Applications that can't bear such ambiguity ! should avoid using hybrid tzinfo classes; there are no ! ambiguities when using UTC, or any other fixed-offset tzinfo subclass ! (such as a class representing only EST (fixed offset -5 hours), or only ! EDT (fixed offset -4 hours)). --- 1150,1176 ---- day, so \code{astimezone(Eastern)} won't deliver a result with \code{hour==2} on the ! day DST begins. In order for \method{astimezone()} to make this ! guarantee, the \class{tzinfo} \method{dst()} method must consider times ! in the "missing hour" (2:MM for Eastern) to be in daylight time. When DST ends (the "end" line), there's a potentially worse problem: ! there's an hour that can't be spelled unambiguously in local wall time: ! the last hour of daylight time. In Eastern, that's times of ! the form 5:MM UTC on the day daylight time ends. The local wall clock leaps from 1:59 (daylight time) back to 1:00 (standard time) again. ! Local times of the form 1:MM are ambiguous. \method{astimezone()} mimics ! the local clock's behavior by mapping two adjacent UTC hours into the ! same local hour then. In the Eastern example, UTC times of the form ! 5:MM and 6:MM both map to 1:MM when converted to Eastern. In order for ! \method{astimezone()} to make this guarantee, the \class{tzinfo} ! \method{dst()} method must consider times in the "repeated hour" to be in ! standard time. This is easily arranged, as in the example, by expressing ! DST switch times in the time zone's standard local time. ! Applications that can't bear such ambiguities should avoid using hybrid ! \class{tzinfo} subclasses; there are no ambiguities when using UTC, or ! any other fixed-offset \class{tzinfo} subclass (such as a class ! representing only EST (fixed offset -5 hours), or only EDT (fixed offset ! -4 hours)). Index: tzinfo-examples.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/tzinfo-examples.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** tzinfo-examples.py 9 Jan 2003 19:52:17 -0000 1.5 --- tzinfo-examples.py 20 Jan 2003 22:54:38 -0000 1.6 *************** *** 92,96 **** # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct. # which is the first Sunday on or after Oct 25. ! DSTEND = datetime(1, 10, 25, 2) class USTimeZone(tzinfo): --- 92,96 ---- # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct. # which is the first Sunday on or after Oct 25. ! DSTEND = datetime(1, 10, 25, 1) class USTimeZone(tzinfo): From montanaro@users.sourceforge.net Tue Jan 21 01:38:49 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 20 Jan 2003 17:38:49 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libshelve.tex,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv27131 Modified Files: libshelve.tex Log Message: * document open() function * promote the example and the documented restrictions to \subsection status * document the flag parameter of the DbfilenameShelf class Index: libshelve.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libshelve.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** libshelve.tex 4 Jan 2003 01:53:38 -0000 1.17 --- libshelve.tex 21 Jan 2003 01:38:47 -0000 1.18 *************** *** 14,43 **** \refstmodindex{pickle} ! To summarize the interface (\code{key} is a string, \code{data} is an ! arbitrary object): ! ! \begin{verbatim} ! import shelve ! ! d = shelve.open(filename) # open -- file may get suffix added by low-level ! # library ! ! d[key] = data # store data at key (overwrites old data if ! # using an existing key) ! data = d[key] # retrieve data at key (raise KeyError if no ! # such key) ! del d[key] # delete data stored at key (raises KeyError ! # if no such key) ! flag = d.has_key(key) # true if the key exists ! list = d.keys() # a list of all existing keys (slow!) ! ! d.close() # close it ! \end{verbatim} ! In addition to the above, shelve supports all methods that are ! supported by dictionaries. This eases the transition from dictionary ! based scripts to those requiring persistent storage. ! Restrictions: \begin{itemize} --- 14,31 ---- \refstmodindex{pickle} ! \begin{funcdesc}{open}{filename\optional{,flag='c'\optional{,binary=\code{False}}}} ! Open a persistent dictionary. By default, the underlying database file is ! opened for reading and writing. The optional \var{flag} pararameter, if set ! to \code{'r'}, can be used to force the file to be opened in read-only mode. ! By default, ASCII pickles are used to serialize values. If the optional ! {}\var{binary} parameter is set to \var{True}, binary pickles will be used ! instead. ! \end{funcdesc} ! Shelve objects support all methods supported by dictionaries. This eases ! the transition from dictionary based scripts to those requiring persistent ! storage. ! \subsection{Restrictions} \begin{itemize} *************** *** 45,51 **** \item The choice of which database package will be used ! (such as \refmodule{dbm} or \refmodule{gdbm}) depends on which interface ! is available. Therefore it is not safe to open the database directly ! using \refmodule{dbm}. The database is also (unfortunately) subject to the limitations of \refmodule{dbm}, if it is used --- this means that (the pickled representation of) the objects stored in the --- 33,39 ---- \item The choice of which database package will be used ! (such as \refmodule{dbm}, \refmodule{gdbm} or \refmodule{bsddb}) depends on ! which interface is available. Therefore it is not safe to open the database ! directly using \refmodule{dbm}. The database is also (unfortunately) subject to the limitations of \refmodule{dbm}, if it is used --- this means that (the pickled representation of) the objects stored in the *************** *** 54,57 **** --- 42,46 ---- \refbimodindex{dbm} \refbimodindex{gdbm} + \refbimodindex{bsddb} \item *************** *** 93,99 **** --- 82,113 ---- object. The underlying file will be opened using \function{anydbm.open}. By default, the file will be created and opened for both read and write. + The optional \var{flag} parameter has the same interpretation as for the + \function{open} function. The optional \var{binary} parameter has the same interpretation as for the \class{Shelf} class. \end{classdesc} + + \subsection{Example} + + To summarize the interface (\code{key} is a string, \code{data} is an + arbitrary object): + + \begin{verbatim} + import shelve + + d = shelve.open(filename) # open -- file may get suffix added by low-level + # library + + d[key] = data # store data at key (overwrites old data if + # using an existing key) + data = d[key] # retrieve data at key (raise KeyError if no + # such key) + del d[key] # delete data stored at key (raises KeyError + # if no such key) + flag = d.has_key(key) # true if the key exists + list = d.keys() # a list of all existing keys (slow!) + + d.close() # close it + \end{verbatim} \begin{seealso} From montanaro@users.sourceforge.net Tue Jan 21 01:52:41 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 20 Jan 2003 17:52:41 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libshelve.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv32123 Modified Files: libshelve.tex Log Message: more tweaks Index: libshelve.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libshelve.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** libshelve.tex 21 Jan 2003 01:38:47 -0000 1.18 --- libshelve.tex 21 Jan 2003 01:52:39 -0000 1.19 *************** *** 15,24 **** \begin{funcdesc}{open}{filename\optional{,flag='c'\optional{,binary=\code{False}}}} ! Open a persistent dictionary. By default, the underlying database file is ! opened for reading and writing. The optional \var{flag} pararameter, if set ! to \code{'r'}, can be used to force the file to be opened in read-only mode. ! By default, ASCII pickles are used to serialize values. If the optional ! {}\var{binary} parameter is set to \var{True}, binary pickles will be used ! instead. \end{funcdesc} --- 15,26 ---- \begin{funcdesc}{open}{filename\optional{,flag='c'\optional{,binary=\code{False}}}} ! Open a persistent dictionary. The filename specified is the base filename ! for the underlying database. As a side-effect, an extension may be added to ! the filename and more than one file may be created. By default, the ! underlying database file is opened for reading and writing. The optional ! {}\var{flag} pararameter has the same interpretation as the \var{flag} ! parameter of \function{anydbm.open}. By default, ASCII pickles are used to ! serialize values. If the optional \var{binary} parameter is set to ! {}\var{True}, binary pickles will be used instead. \end{funcdesc} *************** *** 79,89 **** \begin{classdesc}{DbfilenameShelf}{filename\optional{, flag='c'\optional{, binary=False}}} ! A subclass of \class{Shelf} which accepts a \var{filename} instead of a dict-like ! object. The underlying file will be opened using \function{anydbm.open}. ! By default, the file will be created and opened for both read and write. ! The optional \var{flag} parameter has the same interpretation as for the ! \function{open} function. ! The optional \var{binary} parameter has the same interpretation as for the ! \class{Shelf} class. \end{classdesc} --- 81,92 ---- \begin{classdesc}{DbfilenameShelf}{filename\optional{, flag='c'\optional{, binary=False}}} ! ! A subclass of \class{Shelf} which accepts a \var{filename} instead of a ! dict-like object. The underlying file will be opened using ! {}\function{anydbm.open}. By default, the file will be created and opened ! for both read and write. The optional \var{flag} parameter has the same ! interpretation as for the \function{open} function. The optional ! \var{binary} parameter has the same interpretation as for the ! {}\class{Shelf} class. \end{classdesc} From montanaro@users.sourceforge.net Tue Jan 21 01:53:11 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 20 Jan 2003 17:53:11 -0800 Subject: [Python-checkins] python/dist/src/Lib shelve.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv32277 Modified Files: shelve.py Log Message: flesh out open() docstring Index: shelve.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/shelve.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** shelve.py 8 Dec 2002 21:25:00 -0000 1.19 --- shelve.py 21 Jan 2003 01:53:09 -0000 1.20 *************** *** 158,162 **** """Open a persistent dictionary for reading and writing. ! Argument is the filename for the dbm database. See the module's __doc__ string for an overview of the interface. """ --- 158,168 ---- """Open a persistent dictionary for reading and writing. ! The filename parameter is the base filename for the underlying database. ! As a side-effect, an extension may be added to the filename and more ! than one file may be created. The optional flag parameter has the ! same interpretation as the flag parameter of anydbm.open(). The ! optional binary parameter may be set to True to force the use of binary ! pickles for serializing data values. ! See the module's __doc__ string for an overview of the interface. """ From loewis@users.sourceforge.net Tue Jan 21 10:14:43 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue, 21 Jan 2003 02:14:43 -0800 Subject: [Python-checkins] python/dist/src configure,1.375,1.376 configure.in,1.386,1.387 pyconfig.h.in,1.69,1.70 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv25008 Modified Files: configure configure.in pyconfig.h.in Log Message: Don't use Posix semaphores on Solaris 8. Fixes #662787. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.375 retrieving revision 1.376 diff -C2 -d -r1.375 -r1.376 *** configure 20 Jan 2003 10:47:48 -0000 1.375 --- configure 21 Jan 2003 10:14:39 -0000 1.376 *************** *** 1,4 **** #! /bin/sh ! # From configure.in Revision: 1.385 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. --- 1,4 ---- #! /bin/sh ! # From configure.in Revision: 1.386 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. *************** *** 11132,11135 **** --- 11132,11144 ---- fi + + # Bug 662787: Using semaphores causes unexplicable hangs on Solaris 8. + case $ac_sys_system/$ac_sys_release in + SunOS/5.8) + cat >>confdefs.h <<\_ACEOF + #define HAVE_BROKEN_POSIX_SEMAPHORES 1 + _ACEOF + ;; + esac echo "$as_me:$LINENO: checking if PTHREAD_SCOPE_SYSTEM is supported" >&5 Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.386 retrieving revision 1.387 diff -C2 -d -r1.386 -r1.387 *** configure.in 20 Jan 2003 10:47:47 -0000 1.386 --- configure.in 21 Jan 2003 10:14:40 -0000 1.387 *************** *** 1448,1451 **** --- 1448,1457 ---- fi + # Bug 662787: Using semaphores causes unexplicable hangs on Solaris 8. + case $ac_sys_system/$ac_sys_release in + SunOS/5.8) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, + Define if the Posix semaphores do not work on your system);; + esac + AC_MSG_CHECKING(if PTHREAD_SCOPE_SYSTEM is supported) AC_CACHE_VAL(ac_cv_pthread_system_supported, Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** pyconfig.h.in 7 Jan 2003 22:42:49 -0000 1.69 --- pyconfig.h.in 21 Jan 2003 10:14:40 -0000 1.70 *************** *** 45,48 **** --- 45,51 ---- #undef HAVE_BROKEN_NICE + /* Define if the Posix semaphores do not work on your system */ + #undef HAVE_BROKEN_POSIX_SEMAPHORES + /* Define to 1 if you have the `chown' function. */ #undef HAVE_CHOWN From loewis@users.sourceforge.net Tue Jan 21 10:14:43 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue, 21 Jan 2003 02:14:43 -0800 Subject: [Python-checkins] python/dist/src/Python thread_pthread.h,2.43,2.44 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv25008/Python Modified Files: thread_pthread.h Log Message: Don't use Posix semaphores on Solaris 8. Fixes #662787. Index: thread_pthread.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_pthread.h,v retrieving revision 2.43 retrieving revision 2.44 diff -C2 -d -r2.43 -r2.44 *** thread_pthread.h 11 Dec 2002 13:12:30 -0000 2.43 --- thread_pthread.h 21 Jan 2003 10:14:41 -0000 2.44 *************** *** 105,109 **** * mutexes and condition variables: */ ! #ifdef _POSIX_SEMAPHORES # define USE_SEMAPHORES #else --- 105,109 ---- * mutexes and condition variables: */ ! #if defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) # define USE_SEMAPHORES #else From loewis@users.sourceforge.net Tue Jan 21 10:58:22 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue, 21 Jan 2003 02:58:22 -0800 Subject: [Python-checkins] python/dist/src/Modules pyexpat.c,2.77,2.78 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv21858 Modified Files: pyexpat.c Log Message: Merge with PyXML 1.71: 60: Added support for the SkippedEntityHandler, new in Expat 1.95.4. 61: Added support for namespace prefixes, which can be enabled by setting the "namespace_prefixes" attribute on the parser object. 65: Disable profiling changes for Python 2.0 and 2.1. 66: Update pyexpat to export the Expat 1.95.5 XML_GetFeatureList() information, and tighten up a type declaration now that Expat is using an incomplete type rather than a void * for the XML_Parser type. 67: Clarified a comment. Added support for XML_UseForeignDTD(), new in Expat 1.95.5. 68: Refactor to avoid partial duplication of the code to construct an ExpatError instance, and actually conform to the API for the exception instance as well. 69: Remove some spurious trailing whitespace. Add a special external-entity-ref handler that gets installed once a handler has raised a Python exception; this can cancel actual parsing earlier if there's an external entity reference in the input data after the the Python excpetion has been raised. 70: Untabify APPEND. 71: Backport PyMODINIT_FUNC for 2.2 and earlier. Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.77 retrieving revision 2.78 diff -C2 -d -r2.77 -r2.78 *** pyexpat.c 19 Jan 2003 15:40:09 -0000 2.77 --- pyexpat.c 21 Jan 2003 10:58:18 -0000 2.78 *************** *** 7,10 **** --- 7,18 ---- #ifndef PyDoc_STRVAR + + /* + * fdrake says: + * Don't change the PyDoc_STR macro definition to (str), because + * '''the parentheses cause compile failures + * ("non-constant static initializer" or something like that) + * on some platforms (Irix?)''' + */ #define PyDoc_STR(str) str #define PyDoc_VAR(name) static char name[] *************** *** 15,18 **** --- 23,27 ---- /* In Python 2.0 and 2.1, disabling Unicode was not possible. */ #define Py_USING_UNICODE + #define NOFIX_TRACE #endif *************** *** 39,42 **** --- 48,52 ---- ElementDecl, AttlistDecl, + SkippedEntity, _DummyDecl }; *************** *** 57,60 **** --- 67,71 ---- int specified_attributes; /* Report only specified attributes. */ int in_callback; /* Is a callback active? */ + int ns_prefixes; /* Namespace-triplets mode? */ XML_Char *buffer; /* Buffer used when accumulating characters */ /* NULL if not enabled */ *************** *** 101,105 **** */ static PyObject * ! set_error(xmlparseobject *self) { PyObject *err; --- 112,116 ---- */ static PyObject * ! set_error(xmlparseobject *self, enum XML_Error code) { PyObject *err; *************** *** 108,112 **** int lineno = XML_GetErrorLineNumber(parser); int column = XML_GetErrorColumnNumber(parser); - enum XML_Error code = XML_GetErrorCode(parser); /* There is no risk of overflowing this buffer, since --- 119,122 ---- *************** *** 208,215 **** --- 218,240 ---- static void clear_handlers(xmlparseobject *self, int initial); + /* This handler is used when an error has been detected, in the hope + that actual parsing can be terminated early. This will only help + if an external entity reference is encountered. */ + static int + error_external_entity_ref_handler(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) + { + return 0; + } + static void flag_error(xmlparseobject *self) { clear_handlers(self, 0); + XML_SetExternalEntityRefHandler(self->itself, + error_external_entity_ref_handler); } *************** *** 265,268 **** --- 290,294 ---- } + #ifndef NOFIX_TRACE static int trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val) *************** *** 291,294 **** --- 317,321 ---- return result; } + #endif static PyObject* *************** *** 311,321 **** --- 338,351 ---- return NULL; tstate->frame = f; + #ifndef NOFIX_TRACE if (trace_frame(tstate, f, PyTrace_CALL, Py_None)) { Py_DECREF(f); return NULL; } + #endif res = PyEval_CallObject(func, args); if (res == NULL && tstate->curexc_traceback == NULL) PyTraceBack_Here(f); + #ifndef NOFIX_TRACE else { if (trace_frame(tstate, f, PyTrace_RETURN, res)) { *************** *** 324,327 **** --- 354,358 ---- } } + #endif tstate->frame = f->f_back; Py_DECREF(f); *************** *** 332,336 **** #define STRING_CONV_FUNC conv_string_to_utf8 #else ! /* Python 2.0 and later versions */ #define STRING_CONV_FUNC (self->returns_unicode \ ? conv_string_to_unicode : conv_string_to_utf8) --- 363,367 ---- #define STRING_CONV_FUNC conv_string_to_utf8 #else ! /* Python 2.0 and later versions, when built with Unicode support */ #define STRING_CONV_FUNC (self->returns_unicode \ ? conv_string_to_unicode : conv_string_to_utf8) *************** *** 691,694 **** --- 722,732 ---- isrequired)) + VOID_HANDLER(SkippedEntity, + (void *userData, + const XML_Char *entityName, + int is_parameter_entity), + ("Ni", + string_intern(self, entityName), is_parameter_entity)) + VOID_HANDLER(NotationDecl, (void *userData, *************** *** 785,789 **** } if (rv == 0) { ! return set_error(self); } if (flush_character_buffer(self) < 0) { --- 823,827 ---- } if (rv == 0) { ! return set_error(self, XML_GetErrorCode(self->itself)); } if (flush_character_buffer(self) < 0) { *************** *** 1024,1027 **** --- 1062,1066 ---- new_parser->specified_attributes = self->specified_attributes; new_parser->in_callback = 0; + new_parser->ns_prefixes = self->ns_prefixes; new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context, encoding); *************** *** 1084,1087 **** --- 1123,1152 ---- } + PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__, + "UseForeignDTD([flag])\n\ + Allows the application to provide an artificial external subset if one is\n\ + not specified as part of the document instance. This readily allows the\n\ + use of a 'default' document type controlled by the application, while still\n\ + getting the advantage of providing document type information to the parser.\n\ + 'flag' defaults to True if not provided."); + + static PyObject * + xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args) + { + PyObject *flagobj = NULL; + XML_Bool flag = XML_TRUE; + enum XML_Error rc; + if (!PyArg_ParseTuple(args, "|O:UseForeignDTD", &flagobj)) + return NULL; + if (flagobj != NULL) + flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE; + rc = XML_UseForeignDTD(self->itself, flag); + if (rc != XML_ERROR_NONE) { + return set_error(self, rc); + } + Py_INCREF(Py_None); + return Py_None; + } + static struct PyMethodDef xmlparse_methods[] = { {"Parse", (PyCFunction)xmlparse_Parse, *************** *** 1090,1103 **** METH_VARARGS, xmlparse_ParseFile__doc__}, {"SetBase", (PyCFunction)xmlparse_SetBase, ! METH_VARARGS, xmlparse_SetBase__doc__}, {"GetBase", (PyCFunction)xmlparse_GetBase, ! METH_VARARGS, xmlparse_GetBase__doc__}, {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate, ! METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__}, {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing, METH_VARARGS, xmlparse_SetParamEntityParsing__doc__}, {"GetInputContext", (PyCFunction)xmlparse_GetInputContext, METH_VARARGS, xmlparse_GetInputContext__doc__}, ! {NULL, NULL} /* sentinel */ }; --- 1155,1170 ---- METH_VARARGS, xmlparse_ParseFile__doc__}, {"SetBase", (PyCFunction)xmlparse_SetBase, ! METH_VARARGS, xmlparse_SetBase__doc__}, {"GetBase", (PyCFunction)xmlparse_GetBase, ! METH_VARARGS, xmlparse_GetBase__doc__}, {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate, ! METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__}, {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing, METH_VARARGS, xmlparse_SetParamEntityParsing__doc__}, {"GetInputContext", (PyCFunction)xmlparse_GetInputContext, METH_VARARGS, xmlparse_GetInputContext__doc__}, ! {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD, ! METH_VARARGS, xmlparse_UseForeignDTD__doc__}, ! {NULL, NULL} /* sentinel */ }; *************** *** 1185,1188 **** --- 1252,1256 ---- self->specified_attributes = 0; self->in_callback = 0; + self->ns_prefixes = 0; self->handlers = NULL; if (namespace_separator != NULL) { *************** *** 1316,1319 **** --- 1384,1389 ---- return PyInt_FromLong((long) self->buffer_used); } + if (strcmp(name, "namespace_prefixes") == 0) + return get_pybool(self->ns_prefixes); if (strcmp(name, "ordered_attributes") == 0) return get_pybool(self->ordered_attributes); *************** *** 1334,1343 **** #define APPEND(list, str) \ ! do { \ ! PyObject *o = PyString_FromString(str); \ ! if (o != NULL) \ ! PyList_Append(list, o); \ ! Py_XDECREF(o); \ ! } while (0) if (strcmp(name, "__members__") == 0) { --- 1404,1413 ---- #define APPEND(list, str) \ ! do { \ ! PyObject *o = PyString_FromString(str); \ ! if (o != NULL) \ ! PyList_Append(list, o); \ ! Py_XDECREF(o); \ ! } while (0) if (strcmp(name, "__members__") == 0) { *************** *** 1357,1360 **** --- 1427,1431 ---- APPEND(rc, "buffer_text"); APPEND(rc, "buffer_used"); + APPEND(rc, "namespace_prefixes"); APPEND(rc, "ordered_attributes"); APPEND(rc, "returns_unicode"); *************** *** 1417,1420 **** --- 1488,1499 ---- return 0; } + if (strcmp(name, "namespace_prefixes") == 0) { + if (PyObject_IsTrue(v)) + self->ns_prefixes = 1; + else + self->ns_prefixes = 0; + XML_SetReturnNSTriplet(self->itself, self->ns_prefixes); + return 0; + } if (strcmp(name, "ordered_attributes") == 0) { if (PyObject_IsTrue(v)) *************** *** 1515,1519 **** Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/ #endif ! Xmlparsetype__doc__, /* Documentation string */ #ifdef WITH_CYCLE_GC (traverseproc)xmlparse_traverse, /* tp_traverse */ --- 1594,1598 ---- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/ #endif ! Xmlparsetype__doc__, /* tp_doc - Documentation string */ #ifdef WITH_CYCLE_GC (traverseproc)xmlparse_traverse, /* tp_traverse */ *************** *** 1634,1640 **** #endif PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */ ! PyMODINIT_FUNC MODULE_INITFUNC(void) { PyObject *m, *d; --- 1713,1728 ---- #endif + #ifndef PyMODINIT_FUNC + # ifdef MS_WINDOWS + # define PyMODINIT_FUNC __declspec(dllexport) void + # else + # define PyMODINIT_FUNC void + # endif + #endif + PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */ ! PyMODINIT_FUNC ! MODULE_INITFUNC(void) { PyObject *m, *d; *************** *** 1714,1717 **** --- 1802,1834 ---- /* Don't core dump later! */ return; + + { + const XML_Feature *features = XML_GetFeatureList(); + PyObject *list = PyList_New(0); + if (list == NULL) + /* just ignore it */ + PyErr_Clear(); + else { + int i = 0; + for (; features[i].feature != XML_FEATURE_END; ++i) { + int ok; + PyObject *item = Py_BuildValue("si", features[i].name, + features[i].value); + if (item == NULL) { + Py_DECREF(list); + list = NULL; + break; + } + ok = PyList_Append(list, item); + Py_DECREF(item); + if (ok < 0) { + PyErr_Clear(); + break; + } + } + if (list != NULL) + PyModule_AddObject(m, "features", list); + } + } #define MYCONST(name) \ *************** *** 1853,1856 **** --- 1970,1976 ---- (xmlhandlersetter)XML_SetAttlistDeclHandler, (xmlhandler)my_AttlistDeclHandler}, + {"SkippedEntityHandler", + (xmlhandlersetter)XML_SetSkippedEntityHandler, + (xmlhandler)my_SkippedEntityHandler}, {NULL, NULL, NULL} /* sentinel */ From loewis@users.sourceforge.net Tue Jan 21 11:09:24 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue, 21 Jan 2003 03:09:24 -0800 Subject: [Python-checkins] python/dist/src/Modules pyexpat.c,2.78,2.79 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv30388 Modified Files: pyexpat.c Log Message: Conditionalize features not found in PyXML 1.95.2. Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.78 retrieving revision 2.79 diff -C2 -d -r2.78 -r2.79 *** pyexpat.c 21 Jan 2003 10:58:18 -0000 2.78 --- pyexpat.c 21 Jan 2003 11:09:21 -0000 2.79 *************** *** 6,9 **** --- 6,11 ---- #include "expat.h" + #define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION) + #ifndef PyDoc_STRVAR *************** *** 48,52 **** --- 50,56 ---- ElementDecl, AttlistDecl, + #if XML_COMBINED_VERSION >= 19504 SkippedEntity, + #endif _DummyDecl }; *************** *** 722,725 **** --- 726,730 ---- isrequired)) + #if XML_COMBINED_VERSION >= 19504 VOID_HANDLER(SkippedEntity, (void *userData, *************** *** 728,731 **** --- 733,737 ---- ("Ni", string_intern(self, entityName), is_parameter_entity)) + #endif VOID_HANDLER(NotationDecl, *************** *** 1123,1126 **** --- 1129,1134 ---- } + + #if XML_COMBINED_VERSION >= 19505 PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__, "UseForeignDTD([flag])\n\ *************** *** 1148,1151 **** --- 1156,1160 ---- return Py_None; } + #endif static struct PyMethodDef xmlparse_methods[] = { *************** *** 1164,1169 **** --- 1173,1180 ---- {"GetInputContext", (PyCFunction)xmlparse_GetInputContext, METH_VARARGS, xmlparse_GetInputContext__doc__}, + #if XML_COMBINED_VERSION >= 19505 {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD, METH_VARARGS, xmlparse_UseForeignDTD__doc__}, + #endif {NULL, NULL} /* sentinel */ }; *************** *** 1803,1806 **** --- 1814,1818 ---- return; + #if XML_COMBINED_VERSION > 19505 { const XML_Feature *features = XML_GetFeatureList(); *************** *** 1831,1834 **** --- 1843,1847 ---- } } + #endif #define MYCONST(name) \ *************** *** 1970,1976 **** --- 1983,1991 ---- (xmlhandlersetter)XML_SetAttlistDeclHandler, (xmlhandler)my_AttlistDeclHandler}, + #if XML_COMBINED_VERSION >= 19504 {"SkippedEntityHandler", (xmlhandlersetter)XML_SetSkippedEntityHandler, (xmlhandler)my_SkippedEntityHandler}, + #endif {NULL, NULL, NULL} /* sentinel */ From jackjansen@users.sourceforge.net Tue Jan 21 13:50:37 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 21 Jan 2003 05:50:37 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.111,1.112 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv8475 Modified Files: Makefile.pre.in Log Message: Compile site-packages with -t, not -tt. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.111 retrieving revision 1.112 diff -C2 -d -r1.111 -r1.112 *** Makefile.pre.in 20 Jan 2003 10:47:47 -0000 1.111 --- Makefile.pre.in 21 Jan 2003 13:50:34 -0000 1.112 *************** *** 684,691 **** PYTHONPATH=$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt $(LIBDEST)/compileall.py \ ! -x badsyntax $(LIBDEST) PYTHONPATH=$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt -O $(LIBDEST)/compileall.py \ ! -x badsyntax $(LIBDEST) # Create the PLATDIR source directory, if one wasn't distributed.. --- 684,697 ---- PYTHONPATH=$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt $(LIBDEST)/compileall.py \ ! -x 'badsyntax|site-packages' $(LIBDEST) PYTHONPATH=$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt -O $(LIBDEST)/compileall.py \ ! -x 'badsyntax|site-packages' $(LIBDEST) ! PYTHONPATH=$(LIBDEST) $(RUNSHARED) \ ! ./$(BUILDPYTHON) -Wi -t $(LIBDEST)/compileall.py \ ! -x badsyntax $(LIBDEST)/site-packages ! PYTHONPATH=$(LIBDEST) $(RUNSHARED) \ ! ./$(BUILDPYTHON) -Wi -t -O $(LIBDEST)/compileall.py \ ! -x badsyntax $(LIBDEST)/site-packages # Create the PLATDIR source directory, if one wasn't distributed.. From jackjansen@users.sourceforge.net Tue Jan 21 13:56:36 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 21 Jan 2003 05:56:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac EasyDialogs.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv10986 Modified Files: EasyDialogs.py Log Message: Use new file dialogs in GetArgv() Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/EasyDialogs.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** EasyDialogs.py 17 Jan 2003 23:13:02 -0000 1.3 --- EasyDialogs.py 21 Jan 2003 13:56:34 -0000 1.4 *************** *** 29,33 **** from Carbon.ControlAccessor import * # Also import Controls constants import Carbon.File - import macfs import macresource import os --- 29,32 ---- *************** *** 495,509 **** MacOS.SysBeep() elif n == ARGV_ADD_OLDFILE: ! fss, ok = macfs.StandardGetFile() ! if ok: ! stringstoadd = [fss.as_pathname()] elif n == ARGV_ADD_NEWFILE: ! fss, ok = macfs.StandardPutFile('') ! if ok: ! stringstoadd = [fss.as_pathname()] elif n == ARGV_ADD_FOLDER: ! fss, ok = macfs.GetDirectory() ! if ok: ! stringstoadd = [fss.as_pathname()] elif n == ARGV_CMDLINE_DATA: pass # Nothing to do --- 494,508 ---- MacOS.SysBeep() elif n == ARGV_ADD_OLDFILE: ! pathname = AskFileForOpen() ! if pathname: ! stringstoadd = [pathname] elif n == ARGV_ADD_NEWFILE: ! pathname = AskFileForSave() ! if pathname: ! stringstoadd = [pathname] elif n == ARGV_ADD_FOLDER: ! pathname = AskFolder() ! if pathname: ! stringstoadd = [pathname] elif n == ARGV_CMDLINE_DATA: pass # Nothing to do *************** *** 695,699 **** def test(): ! import time, sys Message("Testing EasyDialogs.") --- 694,698 ---- def test(): ! import time, sys, macfs Message("Testing EasyDialogs.") From akuchling@users.sourceforge.net Tue Jan 21 14:19:25 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Tue, 21 Jan 2003 06:19:25 -0800 Subject: [Python-checkins] python/dist/src/Lib/lib-tk FileDialog.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory sc8-pr-cvs1:/tmp/cvs-serv21304 Modified Files: FileDialog.py Log Message: Fix example in a docstring to not use 'file' as a variable name Index: FileDialog.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/FileDialog.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** FileDialog.py 16 Jul 2000 12:04:31 -0000 1.8 --- FileDialog.py 21 Jan 2003 14:19:21 -0000 1.9 *************** *** 26,31 **** d = FileDialog(master) ! file = d.go(dir_or_file, pattern, default, key) ! if file is None: ...canceled... else: ...open file... --- 26,31 ---- d = FileDialog(master) ! fname = d.go(dir_or_file, pattern, default, key) ! if fname is None: ...canceled... else: ...open file... From jackjansen@users.sourceforge.net Tue Jan 21 14:38:36 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 21 Jan 2003 06:38:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac EasyDialogs.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv30579 Modified Files: EasyDialogs.py Log Message: Spell out the arguments to AskFileForOpen and friends, so help() gives useful help. Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/EasyDialogs.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** EasyDialogs.py 21 Jan 2003 13:56:34 -0000 1.4 --- EasyDialogs.py 21 Jan 2003 14:38:32 -0000 1.5 *************** *** 5,8 **** --- 5,12 ---- AskPassword(prompt, default) -- like AskString(), but shows text as bullets. AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons. + GetArgv(optionlist, commandlist) -- fill a sys.argv-like list using a dialog + AskFileForOpen(...) -- Ask the user for an existing file + AskFileForSave(...) -- Ask the user for an output file + AskFolder(...) -- Ask the user to select a folder bar = Progress(label, maxvalue) -- Display a progress bar bar.set(value) -- Set value *************** *** 32,35 **** --- 36,43 ---- import os + __all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel', + 'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder', + 'Progress'] + _initialized = 0 *************** *** 550,596 **** del d ! def _mktypelist(typelist): ! # Workaround for OSX typeless files: ! if 'TEXT' in typelist and not '\0\0\0\0' in typelist: ! typelist = typelist + ('\0\0\0\0',) ! if not typelist: ! return None ! data = 'Pyth' + struct.pack("hh", 0, len(typelist)) ! for type in typelist: ! data = data+type ! return Carbon.Res.Handle(data) ! ! _ALLOWED_KEYS = { ! 'version':1, ! 'defaultLocation':1, ! 'dialogOptionFlags':1, ! 'location':1, ! 'clientName':1, ! 'windowTitle':1, ! 'actionButtonLabel':1, ! 'cancelButtonLabel':1, ! 'savedFileName':1, ! 'message':1, ! 'preferenceKey':1, ! 'popupExtension':1, ! 'eventProc':1, ! 'previewProc':1, ! 'filterProc':1, ! 'typeList':1, ! 'fileType':1, ! 'fileCreator':1, ! # Our extension: ! 'wanted':1, ! 'multiple':1, ! } ! ! def _process_Nav_args(argsargs, allowed, dftflags): import aepack import Carbon.AE import Carbon.File - args = argsargs.copy() for k in args.keys(): ! if not allowed.has_key(k): ! raise TypeError, "Unknown keyword argument: %s" % repr(k) # Set some defaults, and modify some arguments if not args.has_key('dialogOptionFlags'): --- 558,568 ---- del d ! def _process_Nav_args(dftflags, **args): import aepack import Carbon.AE import Carbon.File for k in args.keys(): ! if args[k] is None: ! del args[k] # Set some defaults, and modify some arguments if not args.has_key('dialogOptionFlags'): *************** *** 619,625 **** return args, tpwanted ! def AskFileForOpen(**args): default_flags = 0x56 # Or 0xe4? ! args, tpwanted = _process_Nav_args(args, _ALLOWED_KEYS, default_flags) try: rr = Nav.NavChooseFile(args) --- 591,625 ---- return args, tpwanted ! def AskFileForOpen( ! version=None, ! defaultLocation=None, ! dialogOptionFlags=None, ! location=None, ! clientName=None, ! windowTitle=None, ! actionButtonLabel=None, ! cancelButtonLabel=None, ! message=None, ! preferenceKey=None, ! popupExtension=None, ! eventProc=None, ! previewProc=None, ! filterProc=None, ! typeList=None, ! wanted=None, ! multiple=None): ! """Display a dialog asking the user for a file to open. ! ! wanted is the return type wanted: FSSpec, FSRef, unicode or string (default) ! the other arguments can be looked up in Apple's Navigation Services documentation""" ! default_flags = 0x56 # Or 0xe4? ! args, tpwanted = _process_Nav_args(default_flags, version=version, ! defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags, ! location=location,clientName=clientName,windowTitle=windowTitle, ! actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel, ! message=message,preferenceKey=preferenceKey, ! popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc, ! filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple) try: rr = Nav.NavChooseFile(args) *************** *** 641,647 **** raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) ! def AskFileForSave(**args): default_flags = 0x07 ! args, tpwanted = _process_Nav_args(args, _ALLOWED_KEYS, default_flags) try: rr = Nav.NavPutFile(args) --- 641,676 ---- raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) ! def AskFileForSave( ! version=None, ! defaultLocation=None, ! dialogOptionFlags=None, ! location=None, ! clientName=None, ! windowTitle=None, ! actionButtonLabel=None, ! cancelButtonLabel=None, ! savedFileName=None, ! message=None, ! preferenceKey=None, ! popupExtension=None, ! eventProc=None, ! fileType=None, ! fileCreator=None, ! wanted=None, ! multiple=None): ! """Display a dialog asking the user for a filename to save to. ! ! wanted is the return type wanted: FSSpec, FSRef, unicode or string (default) ! the other arguments can be looked up in Apple's Navigation Services documentation""" ! ! default_flags = 0x07 ! args, tpwanted = _process_Nav_args(default_flags, version=version, ! defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags, ! location=location,clientName=clientName,windowTitle=windowTitle, ! actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel, ! savedFileName=savedFileName,message=message,preferenceKey=preferenceKey, ! popupExtension=popupExtension,fileType=fileType,fileCreator=fileCreator, ! wanted=wanted,multiple=multiple) try: rr = Nav.NavPutFile(args) *************** *** 670,676 **** raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) ! def AskFolder(**args): default_flags = 0x17 ! args, tpwanted = _process_Nav_args(args, _ALLOWED_KEYS, default_flags) try: rr = Nav.NavChooseFolder(args) --- 699,731 ---- raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) ! def AskFolder( ! version=None, ! defaultLocation=None, ! dialogOptionFlags=None, ! location=None, ! clientName=None, ! windowTitle=None, ! actionButtonLabel=None, ! cancelButtonLabel=None, ! message=None, ! preferenceKey=None, ! popupExtension=None, ! eventProc=None, ! filterProc=None, ! wanted=None, ! multiple=None): ! """Display a dialog asking the user for select a folder. ! ! wanted is the return type wanted: FSSpec, FSRef, unicode or string (default) ! the other arguments can be looked up in Apple's Navigation Services documentation""" ! default_flags = 0x17 ! args, tpwanted = _process_Nav_args(default_flags, version=version, ! defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags, ! location=location,clientName=clientName,windowTitle=windowTitle, ! actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel, ! message=message,preferenceKey=preferenceKey, ! popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc, ! wanted=wanted,multiple=multiple) try: rr = Nav.NavChooseFolder(args) From jackjansen@users.sourceforge.net Tue Jan 21 15:05:06 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 21 Jan 2003 07:05:06 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.112,1.113 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv16479 Modified Files: Makefile.pre.in Log Message: Fixed typo in package name that went unnoticed because of MacOSX's case-insensitive filenames. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.112 retrieving revision 1.113 diff -C2 -d -r1.112 -r1.113 *** Makefile.pre.in 21 Jan 2003 13:50:34 -0000 1.112 --- Makefile.pre.in 21 Jan 2003 15:05:02 -0000 1.113 *************** *** 616,620 **** XMLLIBSUBDIRS= xml xml/dom xml/parsers xml/sax PLATMACDIRS= plat-mac plat-mac/Carbon plat-mac/lib-scriptpackages \ ! plat-mac/lib-scriptpackages/_BuiltinSuites \ plat-mac/lib-scriptpackages/CodeWarrior \ plat-mac/lib-scriptpackages/Explorer \ --- 616,620 ---- XMLLIBSUBDIRS= xml xml/dom xml/parsers xml/sax PLATMACDIRS= plat-mac plat-mac/Carbon plat-mac/lib-scriptpackages \ ! plat-mac/lib-scriptpackages/_builtinSuites \ plat-mac/lib-scriptpackages/CodeWarrior \ plat-mac/lib-scriptpackages/Explorer \ From jackjansen@users.sourceforge.net Tue Jan 21 15:30:24 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 21 Jan 2003 07:30:24 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac findertools.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv29315 Modified Files: findertools.py Log Message: Oops, this file wasn't 8-bit-clean yet. Fixed. Index: findertools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/findertools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** findertools.py 30 Dec 2002 22:04:20 -0000 1.1 --- findertools.py 21 Jan 2003 15:30:21 -0000 1.2 *************** *** 122,126 **** def comment(object, comment=None): ! """comment: get or set the Finder-comment of the item, displayed in the –Get Info” window.""" object = macfs.FSSpec(object) fss = macfs.FSSpec(object) --- 122,126 ---- def comment(object, comment=None): ! """comment: get or set the Finder-comment of the item, displayed in the 'Get Info' window.""" object = macfs.FSSpec(object) fss = macfs.FSSpec(object) *************** *** 757,761 **** def _test2(): ! print '\nmorefindertools version %s\nTests coming upƒ' %__version__ import os import random --- 757,761 ---- def _test2(): ! print '\nmorefindertools version %s\nTests coming up...' %__version__ import os import random *************** *** 801,805 **** windowposition(base, pos) print '\twindow position', pos ! windowposition(base, orgpos) # park it where it was beforeƒ print 'Put a comment in file', f, ':' --- 801,805 ---- windowposition(base, pos) print '\twindow position', pos ! windowposition(base, orgpos) # park it where it was before print 'Put a comment in file', f, ':' From jackjansen@users.sourceforge.net Tue Jan 21 15:31:25 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 21 Jan 2003 07:31:25 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macfs.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv29678 Modified Files: macfs.py Log Message: Implemented StandardGetFile and friends with the new EasyDialogs file dialogs. Index: macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macfs.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** macfs.py 15 Jan 2003 22:36:16 -0000 1.3 --- macfs.py 21 Jan 2003 15:31:16 -0000 1.4 *************** *** 133,256 **** # - _movablemodal = 0 _curfolder = None - def _mktypelist(typelist): - # Workaround for OSX typeless files: - if 'TEXT' in typelist and not '\0\0\0\0' in typelist: - typelist = typelist + ('\0\0\0\0',) - if not typelist: - return None - data = 'Pyth' + struct.pack("hh", 0, len(typelist)) - for type in typelist: - data = data+type - return Carbon.Res.Handle(data) - def StandardGetFile(*typelist): """Ask for an input file, optionally specifying 4-char file types that are allowable""" ! return apply(PromptGetFile, (None,)+typelist) def PromptGetFile(prompt, *typelist): """Ask for an input file giving the user a prompt message. Optionally you can specifying 4-char file types that are allowable""" ! args = {} ! flags = 0x56 ! typehandle = _mktypelist(typelist) ! if typehandle: ! args['typeList'] = typehandle ! else: ! flags = flags | 0x01 ! if prompt: ! args['message'] = prompt ! args['preferenceKey'] = 'PyMC' ! if _movablemodal: ! args['eventProc'] = None ! args['dialogOptionFlags'] = flags ! _handleSetFolder(args) ! try: ! rr = Nav.NavChooseFile(args) ! good = 1 ! except Nav.error, arg: ! if arg[0] != -128: # userCancelledErr ! raise Nav.error, arg ! good = 0 ! fss = None ! else: ! if rr.selection: ! fss = FSSpec(rr.selection[0]) ! else: ! fss = None ! good = 0 ! ## if typehandle: ! ## typehandle.DisposeHandle() ! return fss, good def StandardPutFile(prompt, default=None): """Ask the user for an output file, with a prompt. Optionally you cn supply a default output filename""" ! args = {} ! flags = 0x07 ! if prompt: ! args['message'] = prompt ! args['preferenceKey'] = 'PyMC' ! if _movablemodal: ! args['eventProc'] = None ! if default: ! args['savedFileName'] = default ! args['dialogOptionFlags'] = flags ! _handleSetFolder(args) ! try: ! rr = Nav.NavPutFile(args) ! good = 1 ! except Nav.error, arg: ! if arg[0] != -128: # userCancelledErr ! raise Nav.error, arg ! good = 0 ! fss = None ! else: ! fss = FSSpec(rr.selection[0]) ! return fss, good def SetFolder(folder): global _curfolder if _curfolder: ! rv = _curfolder else: rv = None ! _curfolder = FSSpec(folder) return rv ! def _handleSetFolder(args): global _curfolder ! if not _curfolder: ! return ! import aepack ! fss = _curfolder ! aedesc = aepack.pack(fss) ! args['defaultLocation'] = aedesc _curfolder = None def GetDirectory(prompt=None): """Ask the user to select a folder. Optionally you can give a prompt.""" ! args = {} ! flags = 0x17 ! if prompt: ! args['message'] = prompt ! args['preferenceKey'] = 'PyMC' ! if _movablemodal: ! args['eventProc'] = None ! args['dialogOptionFlags'] = flags ! _handleSetFolder(args) ! try: ! rr = Nav.NavChooseFolder(args) ! good = 1 ! except Nav.error, arg: ! if arg[0] != -128: # userCancelledErr ! raise Nav.error, arg ! good = 0 ! fss = None ! else: ! fss = FSSpec(rr.selection[0]) ! return fss, good ! --- 133,180 ---- # _curfolder = None def StandardGetFile(*typelist): """Ask for an input file, optionally specifying 4-char file types that are allowable""" ! return PromptGetFile('', *typelist) def PromptGetFile(prompt, *typelist): """Ask for an input file giving the user a prompt message. Optionally you can specifying 4-char file types that are allowable""" ! import EasyDialogs ! if not typelist: ! typelist = None ! fss = EasyDialogs.AskFileForOpen(message=prompt, wanted=FSSpec, ! typeList=typelist, defaultLocation=_handleSetFolder()) ! return fss, not fss is None def StandardPutFile(prompt, default=None): """Ask the user for an output file, with a prompt. Optionally you cn supply a default output filename""" ! import EasyDialogs ! fss = EasyDialogs.AskFileForSave(wanted=FSSpec, message=prompt, ! savedFileName=default, defaultLocation=_handleSetFolder()) ! return fss, not fss is None def SetFolder(folder): global _curfolder if _curfolder: ! rv = FSSpec(_curfolder) else: rv = None ! _curfolder = folder return rv ! def _handleSetFolder(): global _curfolder ! rv = _curfolder _curfolder = None + return rv def GetDirectory(prompt=None): """Ask the user to select a folder. Optionally you can give a prompt.""" ! import EasyDialogs ! fss = EasyDialogs.AskFolder(message=prompt, wanted=FSSpec, ! defaultLocation=_handleSetFolder()) ! return fss, not fss is None From tim_one@users.sourceforge.net Tue Jan 21 16:44:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 21 Jan 2003 08:44:36 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv2416/python/Doc/lib Modified Files: libdatetime.tex Log Message: SF bug 671779: Error in tzinfo.dst() docs tzinfo dst() should return timedelta(0) if DST is not effect, not 0. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** libdatetime.tex 20 Jan 2003 22:54:38 -0000 1.35 --- libdatetime.tex 21 Jan 2003 16:44:27 -0000 1.36 *************** *** 1056,1061 **** \begin{methoddesc}{dst}{self, dt} Return the daylight saving time (DST) adjustment, in minutes east of ! UTC, or \code{None} if DST information isn't known. Return \code{0} if ! DST is not in effect. If DST is in effect, return the offset as a \class{timedelta} object (see \method{utcoffset()} for details). --- 1056,1061 ---- \begin{methoddesc}{dst}{self, dt} Return the daylight saving time (DST) adjustment, in minutes east of ! UTC, or \code{None} if DST information isn't known. Return ! \code{timedelta(0)} if DST is not in effect. If DST is in effect, return the offset as a \class{timedelta} object (see \method{utcoffset()} for details). From gvanrossum@users.sourceforge.net Tue Jan 21 21:01:44 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 21 Jan 2003 13:01:44 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.135,1.136 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv2983 Modified Files: setup.py Log Message: ossaudiodev.c currently gives compilation errors, and Greg doesn't fix it, so disable the build for now. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.135 retrieving revision 1.136 diff -C2 -d -r1.135 -r1.136 *** setup.py 8 Jan 2003 01:37:41 -0000 1.135 --- setup.py 21 Jan 2003 21:01:37 -0000 1.136 *************** *** 724,729 **** exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) ) ! # XXX should also build this on FreeBSD! ! exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) ) if platform == 'sunos5': --- 724,730 ---- exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) ) ! # ossaudiodev currently doesn't work, so don't build. ! ## # XXX should also build this on FreeBSD! ! ## exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) ) if platform == 'sunos5': From gvanrossum@users.sourceforge.net Tue Jan 21 21:05:25 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 21 Jan 2003 13:05:25 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_logging.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv5076 Modified Files: test_logging.py Log Message: Fix from Vinaj for the "writing to closed file" errors. SF 670390. Index: test_logging.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_logging.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_logging.py 15 Jan 2003 23:43:02 -0000 1.3 --- test_logging.py 21 Jan 2003 21:05:20 -0000 1.4 *************** *** 25,29 **** """ ! from select import select import os, sys, string, struct, types, cPickle, cStringIO import socket, threading, time, locale --- 25,29 ---- """ ! import select import os, sys, string, struct, types, cPickle, cStringIO import socket, threading, time, locale *************** *** 65,69 **** break slen = struct.unpack(">L", chunk)[0] - #print slen chunk = self.connection.recv(slen) while len(chunk) < slen: --- 65,68 ---- *************** *** 103,107 **** abort = 0 while not abort: ! rd, wr, ex = select([self.socket.fileno()], [], [], self.timeout) --- 102,106 ---- abort = 0 while not abort: ! rd, wr, ex = select.select([self.socket.fileno()], [], [], self.timeout) *************** *** 110,113 **** --- 109,118 ---- abort = self.abort + def process_request(self, request, client_address): + #import threading + t = threading.Thread(target = self.finish_request, + args = (request, client_address)) + t.start() + def runTCP(tcpserver): tcpserver.serve_until_stopped() *************** *** 422,426 **** threads = [] tcpserver = LogRecordSocketReceiver() ! sys.stdout.write("About to start TCP server...\n") threads.append(threading.Thread(target=runTCP, args=(tcpserver,))) --- 427,431 ---- threads = [] tcpserver = LogRecordSocketReceiver() ! #sys.stdout.write("About to start TCP server...\n") threads.append(threading.Thread(target=runTCP, args=(tcpserver,))) *************** *** 448,456 **** banner("log_test3", "end") - banner("logrecv output", "begin") - sys.stdout.write(sockOut.getvalue()) - sockOut.close() - banner("logrecv output", "end") - finally: #shut down server --- 453,456 ---- *************** *** 458,464 **** for thread in threads: thread.join() if __name__ == "__main__": sys.stdout.write("test_logging\n") test_main() - sys.stdout.flush() --- 458,468 ---- for thread in threads: thread.join() + banner("logrecv output", "begin") + sys.stdout.write(sockOut.getvalue()) + sockOut.close() + banner("logrecv output", "end") + sys.stdout.flush() if __name__ == "__main__": sys.stdout.write("test_logging\n") test_main() From gvanrossum@users.sourceforge.net Tue Jan 21 21:05:26 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 21 Jan 2003 13:05:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_logging,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv5076/output Modified Files: test_logging Log Message: Fix from Vinaj for the "writing to closed file" errors. SF 670390. Index: test_logging =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_logging,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_logging 2 Jan 2003 14:56:39 -0000 1.1 --- test_logging 21 Jan 2003 21:05:22 -0000 1.2 *************** *** 1,4 **** test_logging - About to start TCP server... -- log_test0 begin --------------------------------------------------- CRITICAL:ERR:Message 0 --- 1,3 ---- From tim_one@users.sourceforge.net Tue Jan 21 21:19:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 21 Jan 2003 13:19:56 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime EU.py,1.5,1.6 US.py,1.18,1.19 datetime.py,1.146,1.147 test_datetime.py,1.99,1.100 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv13847 Modified Files: EU.py US.py datetime.py test_datetime.py Log Message: Refactoring of, and new rules for, dt.astimezone(tz). dt must be aware now, and tz.utcoffset() and tz.dst() must not return None. The old dt.astimezone(None) no longer works to change an aware datetime into a naive datetime; use dt.replace(tzinfo=None) instead. The tzinfo base class now supplies a new fromutc(self, dt) method, and datetime.astimezone(tz) invokes tz.fromutc(). The default implementation of fromutc() reproduces the same results as the old astimezone() implementation, but tzinfo subclasses can override fromutc() if the default implementation isn't strong enough to get the correct results in all cases (for example, this may be necessary if a tzinfo subclass models a time zone whose "standard offset" (wrt UTC) changed in some year(s), or in some variations of double-daylight time -- the creativity of time zone politics can't be captured in a single default implementation). Index: EU.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/EU.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** EU.py 20 Jan 2003 22:06:37 -0000 1.5 --- EU.py 21 Jan 2003 21:19:44 -0000 1.6 *************** *** 70,74 **** # in order to compare to the naive dston and dstoff). dt -= self.offset ! if dston <= dt.astimezone(None) < dstoff: return HOUR else: --- 70,74 ---- # in order to compare to the naive dston and dstoff). dt -= self.offset ! if dston <= dt.replace(tzinfo=None) < dstoff: return HOUR else: Index: US.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/US.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** US.py 20 Jan 2003 22:06:38 -0000 1.18 --- US.py 21 Jan 2003 21:19:45 -0000 1.19 *************** *** 84,88 **** # Can't compare naive to aware objects, so strip the timezone from # dt first. ! if start <= dt.astimezone(None) < end: return self.dstoff else: --- 84,88 ---- # Can't compare naive to aware objects, so strip the timezone from # dt first. ! if start <= dt.replace(tzinfo=None) < end: return self.dstoff else: Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.146 retrieving revision 1.147 diff -C2 -d -r1.146 -r1.147 *** datetime.py 20 Jan 2003 22:06:39 -0000 1.146 --- datetime.py 21 Jan 2003 21:19:45 -0000 1.147 *************** *** 878,881 **** --- 878,913 ---- raise NotImplementedError("tzinfo subclass must override dst()") + def _inconsistent_dst(self): + raise ValueError("astimezone(): tz.dst() gave " + "inconsistent results; cannot convert") + + def fromutc(self, dt): + "datetime in UTC -> datetime in local time." + + if dt.tzinfo is not self: + raise ValueError("dt.tzinfo is not self") + + dtoff = dt.utcoffset() + if dtoff is None: + raise ValueError("fromutc() requires a non-None utcoffset() " + "result") + + # See the long comment block at the end of this file for an + # explanation of this algorithm. + dtdst = dt.dst() + if dtdst is None: + raise ValueError("fromutc() requires a non_none dst() result") + delta = dtoff - dtdst + if delta: + dt += delta + dtdst = dt.dst() + if dtdst is None: + raise ValueError("fromutc(): dt.dst gave inconsistent " + "results; cannot convert") + if dtdst: + return dt + dtdst + else: + return dt + # pickle support *************** *** 1274,1335 **** microsecond, tzinfo) - def _inconsistent_dst(self): - raise ValueError("astimezone(): tz.dst() gave " - "inconsistent results; cannot convert") - def astimezone(self, tz): ! _check_tzinfo_arg(tz) ! other = self.replace(tzinfo=tz) ! ! # Don't call utcoffset unless necessary. First check trivial cases. ! if tz is None or self._tzinfo is None or self._tzinfo is tz: ! return other ! ! # Get the offsets. If either object turns out to be naive, again ! # there's no conversion of date or time fields. ! myoff = self.utcoffset() ! if myoff is None: ! return other ! otoff = other.utcoffset() ! if otoff is None: ! return other ! # See the long comment block at the end of this file for an ! # explanation of this algorithm. That it always works requires a ! # pretty intricate proof. There are many equivalent ways to code ! # up the proof as an algorithm. This way favors calling dst() over ! # calling utcoffset(), because "the usual" utcoffset() calls dst() ! # itself, and calling the latter instead saves a Python-level ! # function call. This way of coding it also follow the proof ! # closely, w/ x=self, y=other, z=other, and z'=another. ! otdst = other.dst() ! if otdst is None: ! raise ValueError("astimezone(): utcoffset() returned a duration " ! "but dst() returned None") ! delta = otoff - otdst - myoff ! if delta: ! other += delta ! otdst = other.dst() ! if otdst is None: ! self._inconsistent_dst() ! if not otdst: ! return other ! another = other + otdst ! return another ! # XXX Leaving this unreachable code here for a while. It may be ! # XXX needed again real soon . ! anotherdst = another.dst() ! if anotherdst is None: ! self._inconsistent_dst() ! if otdst == anotherdst: ! other = another ! else: ! # This is the "unspellable hour" case, and we *don't* want ! # the DST spelling here. ! pass ! return other # Ways to produce a string. --- 1306,1328 ---- microsecond, tzinfo) def astimezone(self, tz): ! if not isinstance(tz, tzinfo): ! raise TypeError("tz argument must be an instance of tzinfo") ! mytz = self.tzinfo ! if mytz is None: ! raise ValueError("astimezone() requires an aware datetime") ! if tz is mytz: ! return self ! # Convert self to UTC, and attach the new time zone object. ! myoffset = self.utcoffset() ! if myoffset is None: ! raise ValuError("astimezone() requires an aware datetime") ! utc = (self - myoffset).replace(tzinfo=tz) ! # Convert from UTC to tz's local time. ! return tz.fromutc(utc) # Ways to produce a string. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.99 retrieving revision 1.100 diff -C2 -d -r1.99 -r1.100 *** test_datetime.py 20 Jan 2003 22:06:41 -0000 1.99 --- test_datetime.py 21 Jan 2003 21:19:46 -0000 1.100 *************** *** 1312,1329 **** def test_astimezone(self): ! # Pretty boring! The TZ test is more interesting here. dt = self.theclass.now() f = FixedOffset(44, "") - for dtz in dt.astimezone(f), dt.astimezone(tz=f): - self.failUnless(isinstance(dtz, datetime)) - self.assertEqual(dt.date(), dtz.date()) - self.assertEqual(dt.time(), dtz.time()) - self.failUnless(dtz.tzinfo is f) - self.assertEqual(dtz.utcoffset(), timedelta(minutes=44)) - self.assertRaises(TypeError, dt.astimezone) # not enough args self.assertRaises(TypeError, dt.astimezone, f, f) # too many args self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type class TestTime(unittest.TestCase): --- 1312,1336 ---- def test_astimezone(self): ! # Pretty boring! The TZ test is more interesting here. astimezone() ! # simply can't be applied to a naive object. dt = self.theclass.now() f = FixedOffset(44, "") self.assertRaises(TypeError, dt.astimezone) # not enough args self.assertRaises(TypeError, dt.astimezone, f, f) # too many args self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type + self.assertRaises(ValueError, dt.astimezone, f) # naive + self.assertRaises(ValueError, dt.astimezone, tz=f) # naive + class Bogus(tzinfo): + def utcoffset(self, dt): return None + def dst(self, dt): return timedelta(0) + bog = Bogus() + self.assertRaises(ValueError, dt.astimezone, bog) # naive + + class AlsoBogus(tzinfo): + def utcoffset(self, dt): return timedelta(0) + def dst(self, dt): return None + alsobog = AlsoBogus() + self.assertRaises(ValueError, dt.astimezone, alsobog) # also naive class TestTime(unittest.TestCase): *************** *** 2442,2456 **** dt = self.theclass.now(tzinfo=f44m) self.failUnless(dt.tzinfo is f44m) ! # Replacing with degenerate tzinfo doesn't do any adjustment. ! for x in dt.astimezone(fnone), dt.astimezone(tz=fnone): ! self.failUnless(x.tzinfo is fnone) ! self.assertEqual(x.date(), dt.date()) ! self.assertEqual(x.time(), dt.time()) ! # Ditt with None tz. ! x = dt.astimezone(tz=None) ! self.failUnless(x.tzinfo is None) ! self.assertEqual(x.date(), dt.date()) ! self.assertEqual(x.time(), dt.time()) ! # Ditto replacing with same tzinfo. x = dt.astimezone(dt.tzinfo) self.failUnless(x.tzinfo is f44m) --- 2449,2457 ---- dt = self.theclass.now(tzinfo=f44m) self.failUnless(dt.tzinfo is f44m) ! # Replacing with degenerate tzinfo raises an exception. ! self.assertRaises(ValueError, dt.astimezone, fnone) ! # Ditto with None tz. ! self.assertRaises(TypeError, dt.astimezone, None) ! # Replacing with same tzinfo makes no change. x = dt.astimezone(dt.tzinfo) self.failUnless(x.tzinfo is f44m) *************** *** 2602,2606 **** # Can't compare naive to aware objects, so strip the timezone from # dt first. ! if start <= dt.astimezone(None) < end: return HOUR else: --- 2603,2607 ---- # Can't compare naive to aware objects, so strip the timezone from # dt first. ! if start <= dt.replace(tzinfo=None) < end: return HOUR else: *************** *** 2629,2634 **** # Conversion to our own timezone is always an identity. self.assertEqual(dt.astimezone(tz), dt) - # Conversion to None is always the same as stripping tzinfo. - self.assertEqual(dt.astimezone(None), dt.replace(tzinfo=None)) asutc = dt.astimezone(utc) --- 2630,2633 ---- *************** *** 2683,2688 **** # Conversion to our own timezone is always an identity. self.assertEqual(dt.astimezone(tz), dt) ! # Conversion to None is always the same as stripping tzinfo. ! self.assertEqual(dt.astimezone(None), dt.replace(tzinfo=None)) def convert_between_tz_and_utc(self, tz, utc): --- 2682,2690 ---- # Conversion to our own timezone is always an identity. self.assertEqual(dt.astimezone(tz), dt) ! ! # Converting to UTC and back is an identity too. ! asutc = dt.astimezone(utc) ! there_and_back = asutc.astimezone(tz) ! self.assertEqual(dt, there_and_back) def convert_between_tz_and_utc(self, tz, utc): *************** *** 2736,2740 **** fourback = self.dston - timedelta(hours=4) ninewest = FixedOffset(-9*60, "-0900", 0) ! fourback = fourback.astimezone(ninewest) # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST. Since it's "after # 2", we should get the 3 spelling. --- 2738,2742 ---- fourback = self.dston - timedelta(hours=4) ninewest = FixedOffset(-9*60, "-0900", 0) ! fourback = fourback.replace(tzinfo=ninewest) # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST. Since it's "after # 2", we should get the 3 spelling. *************** *** 2745,2759 **** # get the 3 spelling. expected = self.dston.replace(hour=3) ! got = fourback.astimezone(Eastern).astimezone(None) self.assertEqual(expected, got) # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST. In that # case we want the 1:00 spelling. ! sixutc = self.dston.replace(hour=6).astimezone(utc_real) # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4, # and adding -4-0 == -4 gives the 2:00 spelling. We want the 1:00 EST # spelling. expected = self.dston.replace(hour=1) ! got = sixutc.astimezone(Eastern).astimezone(None) self.assertEqual(expected, got) --- 2747,2761 ---- # get the 3 spelling. expected = self.dston.replace(hour=3) ! got = fourback.astimezone(Eastern).replace(tzinfo=None) self.assertEqual(expected, got) # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST. In that # case we want the 1:00 spelling. ! sixutc = self.dston.replace(hour=6, tzinfo=utc_real) # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4, # and adding -4-0 == -4 gives the 2:00 spelling. We want the 1:00 EST # spelling. expected = self.dston.replace(hour=1) ! got = sixutc.astimezone(Eastern).replace(tzinfo=None) self.assertEqual(expected, got) From tim_one@users.sourceforge.net Tue Jan 21 21:46:18 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 21 Jan 2003 13:46:18 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.147,1.148 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv27820 Modified Files: datetime.py Log Message: Removed unreachable code. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.147 retrieving revision 1.148 diff -C2 -d -r1.147 -r1.148 *** datetime.py 21 Jan 2003 21:19:45 -0000 1.147 --- datetime.py 21 Jan 2003 21:46:13 -0000 1.148 *************** *** 878,885 **** raise NotImplementedError("tzinfo subclass must override dst()") - def _inconsistent_dst(self): - raise ValueError("astimezone(): tz.dst() gave " - "inconsistent results; cannot convert") - def fromutc(self, dt): "datetime in UTC -> datetime in local time." --- 878,881 ---- From loewis@users.sourceforge.net Tue Jan 21 21:53:01 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Tue, 21 Jan 2003 13:53:01 -0800 Subject: [Python-checkins] python/dist/src/Modules _tkinter.c,1.146,1.147 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv32016 Modified Files: _tkinter.c Log Message: Avoid usage of PyDoc_STR in 2.2 compatibility code. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.146 retrieving revision 1.147 diff -C2 -d -r1.146 -r1.147 *** _tkinter.c 6 Jan 2003 12:41:25 -0000 1.146 --- _tkinter.c 21 Jan 2003 21:52:57 -0000 1.147 *************** *** 40,44 **** /* Allow using this code in Python 2.[12] */ #ifndef PyDoc_STRVAR ! #define PyDoc_STRVAR(name,str) static char name[] = PyDoc_STR(str) #endif --- 40,44 ---- /* Allow using this code in Python 2.[12] */ #ifndef PyDoc_STRVAR ! #define PyDoc_STRVAR(name,str) static char name[] = str #endif From jackjansen@users.sourceforge.net Tue Jan 21 22:57:56 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 21 Jan 2003 14:57:56 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac EasyDialogs.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv2505 Modified Files: EasyDialogs.py Log Message: Tuples and lists don't have a copy() method (yet?). Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/EasyDialogs.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** EasyDialogs.py 21 Jan 2003 14:38:32 -0000 1.5 --- EasyDialogs.py 21 Jan 2003 22:57:53 -0000 1.6 *************** *** 577,581 **** args['defaultLocation'] = aepack.pack(defaultLocation) if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType): ! typeList = args['typeList'].copy() # Workaround for OSX typeless files: if 'TEXT' in typeList and not '\0\0\0\0' in typeList: --- 577,581 ---- args['defaultLocation'] = aepack.pack(defaultLocation) if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType): ! typeList = args['typeList'][:] # Workaround for OSX typeless files: if 'TEXT' in typeList and not '\0\0\0\0' in typeList: From jackjansen@users.sourceforge.net Tue Jan 21 22:58:41 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 21 Jan 2003 14:58:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macfs.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv2921 Modified Files: macfs.py Log Message: Added DepracationWarnings to the old Standard File calls. Index: macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macfs.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** macfs.py 21 Jan 2003 15:31:16 -0000 1.4 --- macfs.py 21 Jan 2003 22:58:39 -0000 1.5 *************** *** 7,10 **** --- 7,11 ---- import Carbon.File import Nav + import warnings # First step: ensure we also emulate the MACFS module, which contained *************** *** 144,147 **** --- 145,150 ---- specifying 4-char file types that are allowable""" import EasyDialogs + warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen", + DeprecationWarning, stacklevel=2) if not typelist: typelist = None *************** *** 154,157 **** --- 157,162 ---- default output filename""" import EasyDialogs + warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen", + DeprecationWarning, stacklevel=2) fss = EasyDialogs.AskFileForSave(wanted=FSSpec, message=prompt, savedFileName=default, defaultLocation=_handleSetFolder()) *************** *** 160,163 **** --- 165,170 ---- def SetFolder(folder): global _curfolder + warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen", + DeprecationWarning, stacklevel=2) if _curfolder: rv = FSSpec(_curfolder) *************** *** 176,179 **** --- 183,188 ---- """Ask the user to select a folder. Optionally you can give a prompt.""" import EasyDialogs + warnings.warn("macfs.StandardGetFile and friends are deprecated, use EasyDialogs.AskFileForOpen", + DeprecationWarning, stacklevel=2) fss = EasyDialogs.AskFolder(message=prompt, wanted=FSSpec, defaultLocation=_handleSetFolder()) From rhettinger@users.sourceforge.net Wed Jan 22 01:39:09 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 21 Jan 2003 17:39:09 -0800 Subject: [Python-checkins] python/dist/src/Lib UserDict.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14494 Modified Files: UserDict.py Log Message: SF patch #667730: More DictMixin Sebastien Keim pointed out that iterkeys and __contains__ require their own definitions so their behavior will update when the underlying method is subclassed. Index: UserDict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/UserDict.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** UserDict.py 27 Nov 2002 08:29:10 -0000 1.21 --- UserDict.py 22 Jan 2003 01:39:06 -0000 1.22 *************** *** 91,95 **** return False return True ! __contains__ = has_key # third level takes advantage of second level definitions --- 91,96 ---- return False return True ! def __contains__(self, key): ! return self.has_key(key) # third level takes advantage of second level definitions *************** *** 97,101 **** for k in self: yield (k, self[k]) ! iterkeys = __iter__ # fourth level uses definitions from lower levels --- 98,103 ---- for k in self: yield (k, self[k]) ! def iterkeys(self): ! return self.__iter__() # fourth level uses definitions from lower levels From tim_one@users.sourceforge.net Wed Jan 22 04:45:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 21 Jan 2003 20:45:53 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.617,1.618 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv2341/python/Misc Modified Files: NEWS Log Message: "Premature" doc changes, for new astimezone() rules, and the new tzinfo.fromutc() method. The C code doesn't implement any of this yet (well, not the C code on the machine I'm using now), nor does the test suite reflect it. The Python datetime.py implementation and test suite in the sandbox do match these doc changes. The C implementation probably won't catch up before Thursday (Wednesday is a scheduled "black hole" day this week <0.4 wink>). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.617 retrieving revision 1.618 diff -C2 -d -r1.617 -r1.618 *** NEWS 18 Jan 2003 23:22:19 -0000 1.617 --- NEWS 22 Jan 2003 04:45:50 -0000 1.618 *************** *** 46,50 **** irritation most likely seen on Windows systems. ! In dt.asdatetime(tz), if tz.utcoffset(dt) returns a duration, ValueError is raised if tz.dst(dt) returns None (2.3a1 treated it as 0 instead, but a tzinfo subclass wishing to participate in --- 46,50 ---- irritation most likely seen on Windows systems. ! In dt.astimezone(tz), if tz.utcoffset(dt) returns a duration, ValueError is raised if tz.dst(dt) returns None (2.3a1 treated it as 0 instead, but a tzinfo subclass wishing to participate in *************** *** 61,69 **** by a later example coded by Guido. ! datetimetz.astimezone(tz) no longer raises an exception when the input datetime has no UTC equivalent in tz. For typical "hybrid" time zones (a single tzinfo subclass modeling both standard and daylight time), this case can arise one hour per year, at the hour daylight time ! ends. See new docs for details. The constructors building a datetime from a timestamp could raise --- 61,85 ---- by a later example coded by Guido. ! datetime.astimezone(tz) no longer raises an exception when the input datetime has no UTC equivalent in tz. For typical "hybrid" time zones (a single tzinfo subclass modeling both standard and daylight time), this case can arise one hour per year, at the hour daylight time ! ends. See new docs for details. In short, the new behavior mimics ! the local wall clock's behavior of repeating an hour in local time. ! ! dt.astimezone() can no longer be used to convert between naive and aware ! datetime objects. If you merely want to attach, or remove, a tzinfo ! object, without any conversion of date and time members, use ! dt.replace(tzinfo=whatever) instead, where "whatever" is None or a ! tzinfo subclass instance. ! ! A new method tzinfo.fromutc(dt) can be overridden in tzinfo subclasses ! to give complete control over how a UTC time is to be converted to ! a local time. The default astimezone() implementation calls fromutc() ! as its last step, so a tzinfo subclass can affect that too by overriding ! fromutc(). It's expected that the default fromutc() implementation will ! be suitable as-is for "almost all" time zone subclasses, but the ! creativity of political time zone fiddling appears unbounded -- fromutc() ! allows the highly motivated to emulate any scheme expressible in Python. The constructors building a datetime from a timestamp could raise From tim_one@users.sourceforge.net Wed Jan 22 04:45:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 21 Jan 2003 20:45:53 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.36,1.37 tzinfo-examples.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv2341/python/Doc/lib Modified Files: libdatetime.tex tzinfo-examples.py Log Message: "Premature" doc changes, for new astimezone() rules, and the new tzinfo.fromutc() method. The C code doesn't implement any of this yet (well, not the C code on the machine I'm using now), nor does the test suite reflect it. The Python datetime.py implementation and test suite in the sandbox do match these doc changes. The C implementation probably won't catch up before Thursday (Wednesday is a scheduled "black hole" day this week <0.4 wink>). Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** libdatetime.tex 21 Jan 2003 16:44:27 -0000 1.36 --- libdatetime.tex 22 Jan 2003 04:45:50 -0000 1.37 *************** *** 735,764 **** \begin{methoddesc}{astimezone}{tz} Return a \class{datetime} object with new \member{tzinfo} member ! \var{tz}. ! \var{tz} must be \code{None}, or an instance of a \class{tzinfo} subclass. ! If \var{tz} is \code{None}, \var{self} is naive, ! or \code{self.tzinfo}\ is \var{tz}, ! \code{self.astimezone(tz)} is equivalent to ! \code{self.replace(tzinfo=tz)}: a new time zone object is attached ! without any conversion of date or time members. Else \code{self.tzinfo} ! and \var{tz} must implement the \method{utcoffset()} and \method{dst()} ! \class{tzinfo} methods, and the date and time members are adjusted so ! that the result is local time in time zone \var{tz}, representing the ! same UTC time as \var{self}: after \code{astz = dt.astimezone(tz)}, ! \code{astz - astz.utcoffset()} will usually have the same date and time ! members as \code{dt - dt.utcoffset()}. The discussion of class ! \class{tzinfo} explains the cases at Daylight Saving Time ! transition boundaries where this cannot be achieved (an issue only if ! \var{tz} models both standard and daylight time). \end{methoddesc} \begin{methoddesc}{utcoffset}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{tzinfo.utcoffset(self)}. \end{methoddesc} \begin{methoddesc}{tzname}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{tzinfo.tzname(self)}. \end{methoddesc} --- 735,803 ---- \begin{methoddesc}{astimezone}{tz} Return a \class{datetime} object with new \member{tzinfo} member ! \var{tz}, adjusting the date and time members so the result is the ! same UTC time as \var{self}, but in \var{tz}'s local time. ! ! \var{tz} must be an instance of a \class{tzinfo} subclass, and its ! \method{utcoffset()} and \method{dst()} methods must not return ! \code{None}. \var{self} must be aware (\code{\var{self}.tzinfo} must ! not be \code{None}, and \code{\var{self}.utcoffset()} must not return ! \code{None}). ! ! If code{\var{self}.tzinfo} is \var{tz}, ! \code{\var{self}.astimezone(\var{tz})} is equal to \var{self}: no ! adjustment of date or time members is performed. ! Else the result is local time in time zone \var{tz}, representing the ! same UTC time as \var{self}: after \code{\var{astz} = ! \var{dt}.astimezone(\var{tz})}, ! \code{\var{astz} - \var{astz}.utcoffset()} will usually have the same ! date and time members as \code{\var{dt} - \var{dt}.utcoffset()}. ! The discussion of class \class{tzinfo} explains the cases at Daylight ! Saving Time transition boundaries where this cannot be achieved (an issue ! only if \var{tz} models both standard and daylight time). ! ! If you merely want to attach a time zone object \var{tz} to a ! datetime \var{dt} without adjustment of date and time members, ! use \code{\var{dt}.replace(tzinfo=\var{tz})}. If ! you merely want to remove the time zone object from an aware datetime ! \var{dt} without conversion of date and time members, use ! \code{\var{dt}.replace(tzinfo=None)}. ! ! Note that the default \method{tzinfo.fromutc()} method can be overridden ! in a \class{tzinfo} subclass to effect the result returned by ! \method{astimezone()}. Ignoring error cases, \method{astimezone()} ! acts like: ! ! \begin{verbatim} ! def astimezone(self, tz): ! if self.tzinfo is tz: ! return self ! # Convert self to UTC, and attach the new time zone object. ! utc = (self - self.utcoffset()).replace(tzinfo=tz) ! # Convert from UTC to tz's local time. ! return tz.fromutc(utc) ! \end{verbatim} \end{methoddesc} \begin{methoddesc}{utcoffset}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{\var{self}.tzinfo.utcoffset(\var{self})}, and ! raises an exception if the latter doesn't return \code{None}, or ! a \class{timedelta} object representing a whole number of minutes ! with magnitude less than one day. ! \end{methoddesc} ! ! \begin{methoddesc}{dst}{} ! If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{\var{self}.tzinfo.dst(\var{self})}, and ! raises an exception if the latter doesn't return \code{None}, or ! a \class{timedelta} object representing a whole number of minutes ! with magnitude less than one day. \end{methoddesc} \begin{methoddesc}{tzname}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{\var{self}.tzinfo.tzname(\var{self})}, ! raises an exception if the latter doesn't return \code{None} or ! a string object, \end{methoddesc} *************** *** 990,1004 **** \begin{methoddesc}{utcoffset}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{tzinfo.utcoffset(self)}. \end{methoddesc} \begin{methoddesc}{dst}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{tzinfo.dst(self)}. \end{methoddesc} \begin{methoddesc}{tzname}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{tzinfo.tzname(self)}. \end{methoddesc} --- 1029,1051 ---- \begin{methoddesc}{utcoffset}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{\var{self}.tzinfo.utcoffset(None)}, and ! raises an exception if the latter doesn't return \code{None} or ! a \class{timedelta} object representing a whole number of minutes ! with magnitude less than one day. \end{methoddesc} \begin{methoddesc}{dst}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{\var{self}.tzinfo.dst(None)}, and ! raises an exception if the latter doesn't return \code{None}, or ! a \class{timedelta} object representing a whole number of minutes ! with magnitude less than one day. \end{methoddesc} \begin{methoddesc}{tzname}{} If \member{tzinfo} is \code{None}, returns \code{None}, else ! returns \code{\var{self}.tzinfo.tzname(None)}, or ! raises an exception if the latter doesn't return \code{None} or ! a string object. \end{methoddesc} *************** *** 1067,1071 **** member's \method{dst()} method to determine how the \member{tm_isdst} flag should be set, and ! \method{datetime.astimezone()} calls \method{dst()} to account for DST changes when crossing time zones. --- 1114,1118 ---- member's \method{dst()} method to determine how the \member{tm_isdst} flag should be set, and ! \method{tzinfo.fromutc()} calls \method{dst()} to account for DST changes when crossing time zones. *************** *** 1073,1085 **** standard and daylight times must be consistent in this sense: ! \code{tz.utcoffset(dt) - tz.dst(dt)} must return the same result for every \class{datetime} \var{dt} ! with \code{dt.tzinfo==tz} For sane \class{tzinfo} subclasses, this ! expression yields the time zone's "standard offset", which should not ! depend on the date or the time, but only on geographic location. The ! implementation of \method{datetime.astimezone()} relies on this, but ! cannot detect violations; it's the programmer's responsibility to ! ensure it. The default implementation of \method{dst()} raises --- 1120,1153 ---- standard and daylight times must be consistent in this sense: ! \code{\var{tz}.utcoffset(\var{dt}) - \var{tz}.dst(\var{dt})} must return the same result for every \class{datetime} \var{dt} ! with \code{\var{dt}.tzinfo==\var{tz}} For sane \class{tzinfo} ! subclasses, this expression yields the time zone's "standard offset", ! which should not depend on the date or the time, but only on geographic ! location. The implementation of \method{datetime.astimezone()} relies ! on this, but cannot detect violations; it's the programmer's ! responsibility to ensure it. If a \class{tzinfo} subclass cannot ! guarantee this, it may be able to override the default implementation ! of \method{tzinfo.fromutc()} to work correctly with \method{astimezone()} ! regardless. ! ! Most implementations of \method{dst()} will probably look like one ! of these two: ! ! \begin{verbatim} ! return timedelta(0) # a fixed-offset class: doesn't account for DST ! ! or ! ! # Code to set dston and dstoff to the time zone's DST transition ! # times based on the input dt.year, and expressed in standard local ! # time. Then ! ! if dston <= dt.replace(tzinfo=None) < dstoff: ! return timedelta(hours=1) ! else: ! return timedelta(0) ! \end{verbatim} The default implementation of \method{dst()} raises *************** *** 1088,1101 **** \begin{methoddesc}{tzname}{self, dt} ! Return the timezone name corresponding to the \class{datetime} ! object represented ! by \var{dt}, as a string. Nothing about string names is defined by the ! \module{datetime} module, and there's no requirement that it mean anything ! in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", ! "US/Eastern", "America/New York" are all valid replies. Return \code{None} if a string name isn't known. Note that this is a method ! rather than a fixed string primarily because some \class{tzinfo} objects ! will wish to return different names depending on the specific value ! of \var{dt} passed, especially if the \class{tzinfo} class is accounting for daylight time. --- 1156,1169 ---- \begin{methoddesc}{tzname}{self, dt} ! Return the time zone name corresponding to the \class{datetime} ! object \var{dt}, as a string. ! Nothing about string names is defined by the ! \module{datetime} module, and there's no requirement that it mean ! anything in particular. For example, "GMT", "UTC", "-500", "-5:00", ! "EDT", "US/Eastern", "America/New York" are all valid replies. Return \code{None} if a string name isn't known. Note that this is a method ! rather than a fixed string primarily because some \class{tzinfo} ! subclasses will wish to return different names depending on the specific ! value of \var{dt} passed, especially if the \class{tzinfo} class is accounting for daylight time. *************** *** 1114,1118 **** best response. For example, returning \code{None} is appropriate if the class wishes to say that time objects don't participate in the ! \class{tzinfo} protocol. It may be more useful for \code{utcoffset(None)} to return the standard UTC offset, as there is no other convention for discovering the standard offset. --- 1182,1186 ---- best response. For example, returning \code{None} is appropriate if the class wishes to say that time objects don't participate in the ! \class{tzinfo} protocols. It may be more useful for \code{utcoffset(None)} to return the standard UTC offset, as there is no other convention for discovering the standard offset. *************** *** 1125,1128 **** --- 1193,1240 ---- and not need worry about objects in other timezones. + There is one more \class{tzinfo} method that a subclass may wish to + override: + + \begin{methoddesc}{fromutc}{self, dt} + This is called from the default \class{datetime.astimezone()} + implementation. When called from that, \code{\var{dt}.tzinfo} is + \var{self}, and \var{dt}'s date and time members are to be viewed as + expressing a UTC time. The purpose of \method{fromutc()} is to + adjust the date and time members, returning an equivalent datetime in + \var{self}'s local time. + + Most \class{tzinfo} subclasses should be able to inherit the default + \method{fromutc()} implementation without problems. It's strong enough + to handle fixed-offset time zones, and time zones accounting for both + standard and daylight time, and the latter even if the DST transition + times differ in different years. An example of a time zone the default + \method{fromutc()} implementation may not handle correctly in all cases + is one where the standard offset (from UTC) depends on the specific date + and time passed, which can happen for political reasons. + The default implementations of \method{astimezone()} and + \method{fromutc()} may not produce the result you want if the result is + one of the hours straddling the moment the standard offset changes. + + Skipping code for error cases, the default \method{fromutc()} + implementation acts like: + + \begin{verbatim} + def fromutc(self, dt): + # raise ValueError error if dt.tzinfo is not self + dtoff = dt.utcoffset() + dtdst = dt.dst() + # raise ValueError if dtoff is None or dtdst is None + delta = dtoff - dtdst # this is self's standard offset + if delta: + dt += delta # convert to standard local time + dtdst = dt.dst() + # raise ValueError if dtdst is None + if dtdst: + return dt + dtdst + else: + return dt + \end{verbatim} + \end{methoddesc} + Example \class{tzinfo} classes: *************** *** 1151,1155 **** \code{hour==2} on the day DST begins. In order for \method{astimezone()} to make this ! guarantee, the \class{tzinfo} \method{dst()} method must consider times in the "missing hour" (2:MM for Eastern) to be in daylight time. --- 1263,1267 ---- \code{hour==2} on the day DST begins. In order for \method{astimezone()} to make this ! guarantee, the \method{rzinfo.dst()} method must consider times in the "missing hour" (2:MM for Eastern) to be in daylight time. *************** *** 1163,1168 **** same local hour then. In the Eastern example, UTC times of the form 5:MM and 6:MM both map to 1:MM when converted to Eastern. In order for ! \method{astimezone()} to make this guarantee, the \class{tzinfo} ! \method{dst()} method must consider times in the "repeated hour" to be in standard time. This is easily arranged, as in the example, by expressing DST switch times in the time zone's standard local time. --- 1275,1280 ---- same local hour then. In the Eastern example, UTC times of the form 5:MM and 6:MM both map to 1:MM when converted to Eastern. In order for ! \method{astimezone()} to make this guarantee, the \method{tzinfo.dst()} ! method must consider times in the "repeated hour" to be in standard time. This is easily arranged, as in the example, by expressing DST switch times in the time zone's standard local time. *************** *** 1236,1242 **** PyDateTime_Date PyDateTime_DateTime - PyDateTime_DateTimeTZ PyDateTime_Time - PyDateTime_TimeTZ PyDateTime_Delta PyDateTime_TZInfo --- 1348,1352 ---- *************** *** 1250,1262 **** PyDateTime_CheckExact(op) - PyDateTimeTZ_Check(op) - PyDateTimeTZ_CheckExact(op) - PyTime_Check(op) PyTime_CheckExact(op) - PyTimeTZ_Check(op) - PyTimeTZ_CheckExact(op) - PyDelta_Check(op) PyDelta_CheckExact(op) --- 1360,1366 ---- *************** *** 1270,1279 **** return ints: ! For \class{date}, \class{datetime}, and \class{datetimetz} instances: PyDateTime_GET_YEAR(o) PyDateTime_GET_MONTH(o) PyDateTime_GET_DAY(o) ! For \class{datetime} and \class{datetimetz} instances: PyDateTime_DATE_GET_HOUR(o) PyDateTime_DATE_GET_MINUTE(o) --- 1374,1383 ---- return ints: ! For \class{date} and \class{datetime} instances: PyDateTime_GET_YEAR(o) PyDateTime_GET_MONTH(o) PyDateTime_GET_DAY(o) ! For \class{datetime} instances: PyDateTime_DATE_GET_HOUR(o) PyDateTime_DATE_GET_MINUTE(o) *************** *** 1281,1285 **** PyDateTime_DATE_GET_MICROSECOND(o) ! For \class{time} and \class{timetz} instances: PyDateTime_TIME_GET_HOUR(o) PyDateTime_TIME_GET_MINUTE(o) --- 1385,1389 ---- PyDateTime_DATE_GET_MICROSECOND(o) ! For \class{time} instances: PyDateTime_TIME_GET_HOUR(o) PyDateTime_TIME_GET_MINUTE(o) Index: tzinfo-examples.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/tzinfo-examples.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** tzinfo-examples.py 20 Jan 2003 22:54:38 -0000 1.6 --- tzinfo-examples.py 22 Jan 2003 04:45:50 -0000 1.7 *************** *** 28,32 **** def __init__(self, offset, name): ! self.__offset = timdelta(minutes = offset) self.__name = name --- 28,32 ---- def __init__(self, offset, name): ! self.__offset = timedelta(minutes = offset) self.__name = name *************** *** 117,123 **** if dt is None or dt.tzinfo is None: # An exception may be sensible here, in one or both cases. ! # It depends on how you want to treat them. The astimezone() ! # implementation always passes a datetime with ! # dt.tzinfo == self. return ZERO assert dt.tzinfo is self --- 117,123 ---- if dt is None or dt.tzinfo is None: # An exception may be sensible here, in one or both cases. ! # It depends on how you want to treat them. The default ! # fromutc() implementation (called by the default astimezone() ! # implementation) passes a datetime with dt.tzinfo is self. return ZERO assert dt.tzinfo is self From loewis@users.sourceforge.net Wed Jan 22 09:00:48 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 22 Jan 2003 01:00:48 -0800 Subject: [Python-checkins] python/dist/src/Python pythonrun.c,2.174,2.175 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv23735 Modified Files: pythonrun.c Log Message: Patch #671459: Invoke import hooks in Py_NewInterpreter. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.174 retrieving revision 2.175 diff -C2 -d -r2.174 -r2.175 *** pythonrun.c 31 Dec 2002 03:42:12 -0000 2.174 --- pythonrun.c 22 Jan 2003 09:00:38 -0000 2.175 *************** *** 339,342 **** --- 339,343 ---- PyDict_SetItemString(interp->sysdict, "modules", interp->modules); + _PyImportHooks_Init(); initmain(); if (!Py_NoSiteFlag) From loewis@users.sourceforge.net Wed Jan 22 09:17:41 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 22 Jan 2003 01:17:41 -0800 Subject: [Python-checkins] python/dist/src/Modules _tkinter.c,1.147,1.148 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv31154/Modules Modified Files: _tkinter.c Log Message: Convert booleans to integers in IntVar.set. Fixes #671741. Return booleans from _tkinter.getboolean. Convert booleans to Tcl booleans in AsObj. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.147 retrieving revision 1.148 diff -C2 -d -r1.147 -r1.148 *** _tkinter.c 21 Jan 2003 21:52:57 -0000 1.147 --- _tkinter.c 22 Jan 2003 09:17:38 -0000 1.148 *************** *** 869,872 **** --- 869,874 ---- return Tcl_NewStringObj(PyString_AS_STRING(value), PyString_GET_SIZE(value)); + else if (PyBool_Check(value)) + return Tcl_NewBooleanObj(PyObject_IsTrue(value)); else if (PyInt_Check(value)) return Tcl_NewLongObj(PyInt_AS_LONG(value)); *************** *** 1740,1744 **** if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) return Tkinter_Error(self); ! return Py_BuildValue("i", v); } --- 1742,1746 ---- if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) return Tkinter_Error(self); ! return PyBool_FromLong(v); } From loewis@users.sourceforge.net Wed Jan 22 09:17:40 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 22 Jan 2003 01:17:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/lib-tk Tkinter.py,1.168,1.169 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory sc8-pr-cvs1:/tmp/cvs-serv31154/Lib/lib-tk Modified Files: Tkinter.py Log Message: Convert booleans to integers in IntVar.set. Fixes #671741. Return booleans from _tkinter.getboolean. Convert booleans to Tcl booleans in AsObj. Index: Tkinter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Tkinter.py,v retrieving revision 1.168 retrieving revision 1.169 diff -C2 -d -r1.168 -r1.169 *** Tkinter.py 10 Jan 2003 23:24:32 -0000 1.168 --- Tkinter.py 22 Jan 2003 09:17:36 -0000 1.169 *************** *** 235,238 **** --- 235,244 ---- Variable.__init__(self, master) + def set(self, value): + """Set the variable to value, converting booleans to integers.""" + if isinstance(value, bool): + value = int(value) + return Variable.set(self, value) + def get(self): """Return the value of the variable as an integer.""" From rhettinger@users.sourceforge.net Wed Jan 22 13:29:02 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 22 Jan 2003 05:29:02 -0800 Subject: [Python-checkins] python/dist/src/Tools/idle ClassBrowser.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory sc8-pr-cvs1:/tmp/cvs-serv31010 Modified Files: ClassBrowser.py Log Message: Kurt pointed out another method affected by the changes to pyclbr.py. Index: ClassBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/ClassBrowser.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** ClassBrowser.py 18 Jan 2003 22:53:36 -0000 1.15 --- ClassBrowser.py 22 Jan 2003 13:29:00 -0000 1.16 *************** *** 143,148 **** def IsExpandable(self): ! if self.cl: ! return not not self.cl.methods def GetSubList(self): --- 143,150 ---- def IsExpandable(self): ! try: ! return bool(self.cl.methods) ! except AttributeError: ! return False def GetSubList(self): From jackjansen@users.sourceforge.net Wed Jan 22 14:03:15 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 22 Jan 2003 06:03:15 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts BuildApplet.py,1.16,1.17 BuildApplication.py,1.9,1.10 MkDistr_ui.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv22883 Modified Files: BuildApplet.py BuildApplication.py MkDistr_ui.py Log Message: Getting rid of StandardGetFile Index: BuildApplet.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplet.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** BuildApplet.py 15 Nov 2002 00:08:29 -0000 1.16 --- BuildApplet.py 22 Jan 2003 14:03:11 -0000 1.17 *************** *** 36,43 **** if not sys.argv[1:]: ! srcfss, ok = macfs.PromptGetFile('Select Python source or applet:', 'TEXT', 'APPL') ! if not ok: return - filename = srcfss.as_pathname() tp, tf = os.path.split(filename) if tf[-3:] == '.py': --- 36,43 ---- if not sys.argv[1:]: ! filename = EasyDialogs.AskFileForOpen(message='Select Python source or applet:', ! fileTypes=('TEXT', 'APPL')) ! if not filename: return tp, tf = os.path.split(filename) if tf[-3:] == '.py': *************** *** 45,51 **** else: tf = tf + '.applet' ! dstfss, ok = macfs.StandardPutFile('Save application as:', tf) ! if not ok: return ! dstfilename = dstfss.as_pathname() cr, tp = MacOS.GetCreatorAndType(filename) if tp == 'APPL': --- 45,51 ---- else: tf = tf + '.applet' ! dstfilename = EasyDialogs.AskFileForSave(message='Save application as:', ! savedFileName=tf) ! if not dstfilename: return cr, tp = MacOS.GetCreatorAndType(filename) if tp == 'APPL': Index: BuildApplication.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplication.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** BuildApplication.py 27 Aug 2001 21:40:27 -0000 1.9 --- BuildApplication.py 22 Jan 2003 14:03:11 -0000 1.10 *************** *** 13,17 **** import string import os - import macfs import MacOS from Carbon import Res --- 13,16 ---- *************** *** 55,62 **** if not sys.argv[1:]: ! srcfss, ok = macfs.PromptGetFile('Select Python source:', 'TEXT') ! if not ok: return - filename = srcfss.as_pathname() else: if sys.argv[2:]: --- 54,61 ---- if not sys.argv[1:]: ! filename = EasyDialogs.AskFileForOpen(message='Select Python source:', ! fileTypes=('TEXT',)) ! if not filename: return else: if sys.argv[2:]: *************** *** 74,81 **** tf = tf + '.app' ! dstfss, ok = macfs.StandardPutFile('Save application as:', tf) if not ok: return - dstfilename = dstfss.as_pathname() macgen_bin.generate(filename, dstfilename, None, architecture, 1) --- 73,80 ---- tf = tf + '.app' ! dstfilename = EasyDialogs.AskFileForSate(message='Save application as:', ! savedFileName=tf) if not ok: return macgen_bin.generate(filename, dstfilename, None, architecture, 1) Index: MkDistr_ui.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/MkDistr_ui.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** MkDistr_ui.py 27 Aug 2001 21:39:29 -0000 1.14 --- MkDistr_ui.py 22 Jan 2003 14:03:12 -0000 1.15 *************** *** 21,25 **** from FrameWork import * import EasyDialogs - import macfs import os import sys --- 21,24 ---- *************** *** 305,313 **** sys.exit(0) if rv == DTYPE_EXIST: ! ## macfs.SetFolder(':(MkDistr)') ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: sys.exit(0) - path = fss.as_pathname() basename = os.path.split(path)[-1] if basename[-8:] <> '.include': --- 304,310 ---- sys.exit(0) if rv == DTYPE_EXIST: ! path = EasyDialogs.AskFileForOpen() ! if not path: sys.exit(0) basename = os.path.split(path)[-1] if basename[-8:] <> '.include': From jackjansen@users.sourceforge.net Wed Jan 22 14:04:20 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 22 Jan 2003 06:04:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macfs.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv23734 Modified Files: macfs.py Log Message: Tweaked time conversion to work in MacPython-OS9. Index: macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macfs.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** macfs.py 21 Jan 2003 22:58:39 -0000 1.5 --- macfs.py 22 Jan 2003 14:04:18 -0000 1.6 *************** *** 32,36 **** return int(t) def _time2utc(t): ! t = t - _EPOCHCONVERT if t < -0x7fffffff: t = t + 0x10000000L --- 32,36 ---- return int(t) def _time2utc(t): ! t = int(t) - _EPOCHCONVERT if t < -0x7fffffff: t = t + 0x10000000L *************** *** 38,42 **** else: def _utc2time(utc): return utc[1] ! def _time2utc(t): return (0, t, 0) # The old name of the error object: --- 38,45 ---- else: def _utc2time(utc): return utc[1] ! def _time2utc(t): ! if t > 0x7fffffff: ! t = t - 0x100000000L ! return (0, int(t), 0) # The old name of the error object: From montanaro@users.sourceforge.net Wed Jan 22 18:17:43 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 22 Jan 2003 10:17:43 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.618,1.619 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv15874/Misc Modified Files: NEWS Log Message: add support for Python's bool type to xmlrpclib - patch # 559288 Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.618 retrieving revision 1.619 diff -C2 -d -r1.618 -r1.619 *** NEWS 22 Jan 2003 04:45:50 -0000 1.618 --- NEWS 22 Jan 2003 18:17:25 -0000 1.619 *************** *** 95,98 **** --- 95,100 ---- ------- + - Xmlrpclib.py now supports the builtin boolean type. + - py_compile has a new 'doraise' flag and a new PyCompileError exception. From montanaro@users.sourceforge.net Wed Jan 22 18:17:59 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 22 Jan 2003 10:17:59 -0800 Subject: [Python-checkins] python/dist/src/Lib xmlrpclib.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv15874/Lib Modified Files: xmlrpclib.py Log Message: add support for Python's bool type to xmlrpclib - patch # 559288 Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** xmlrpclib.py 1 Nov 2002 17:14:16 -0000 1.22 --- xmlrpclib.py 22 Jan 2003 18:17:23 -0000 1.23 *************** *** 143,146 **** --- 143,151 ---- unicode = None # unicode support not available + try: + _bool_is_builtin = False.__class__.__name__ == "bool" + except NameError: + _bool_is_builtin = 0 + def _decode(data, encoding, is8bit=re.compile("[\x80-\xff]").search): # decode non-ascii string (if possible) *************** *** 267,315 **** # all other values are interpreted as False. ! class Boolean: ! """Boolean-value wrapper. ! Use True or False to generate a "boolean" XML-RPC value. ! """ ! def __init__(self, value = 0): ! self.value = operator.truth(value) ! def encode(self, out): ! out.write("%d\n" % self.value) ! def __cmp__(self, other): ! if isinstance(other, Boolean): ! other = other.value ! return cmp(self.value, other) ! def __repr__(self): ! if self.value: ! return "" % id(self) ! else: ! return "" % id(self) ! def __int__(self): ! return self.value ! def __nonzero__(self): ! return self.value ! True, False = Boolean(1), Boolean(0) ! ## ! # Map true or false value to XML-RPC boolean values. ! # ! # @def boolean(value) ! # @param value A boolean value. Any true value is mapped to True, ! # all other values are mapped to False. ! # @return xmlrpclib.True or xmlrpclib.False. ! # @see Boolean ! # @see True ! # @see False ! def boolean(value, _truefalse=(False, True)): ! """Convert any Python value to XML-RPC 'boolean'.""" ! return _truefalse[operator.truth(value)] ## --- 272,325 ---- # all other values are interpreted as False. ! if _bool_is_builtin: ! boolean = Boolean = bool ! # to avoid breaking code which references xmlrpclib.{True,False} ! True, False = True, False ! else: ! class Boolean: ! """Boolean-value wrapper. ! Use True or False to generate a "boolean" XML-RPC value. ! """ ! def __init__(self, value = 0): ! self.value = operator.truth(value) ! def encode(self, out): ! out.write("%d\n" % self.value) ! def __cmp__(self, other): ! if isinstance(other, Boolean): ! other = other.value ! return cmp(self.value, other) ! def __repr__(self): ! if self.value: ! return "" % id(self) ! else: ! return "" % id(self) ! def __int__(self): ! return self.value ! def __nonzero__(self): ! return self.value ! True, False = Boolean(1), Boolean(0) ! ## ! # Map true or false value to XML-RPC boolean values. ! # ! # @def boolean(value) ! # @param value A boolean value. Any true value is mapped to True, ! # all other values are mapped to False. ! # @return xmlrpclib.True or xmlrpclib.False. ! # @see Boolean ! # @see True ! # @see False ! def boolean(value, _truefalse=(False, True)): ! """Convert any Python value to XML-RPC 'boolean'.""" ! return _truefalse[operator.truth(value)] ## *************** *** 412,416 **** return value ! WRAPPERS = DateTime, Binary, Boolean # -------------------------------------------------------------------- --- 422,428 ---- return value ! WRAPPERS = (DateTime, Binary) ! if not _bool_is_builtin: ! WRAPPERS = WRAPPERS + (Boolean,) # -------------------------------------------------------------------- *************** *** 599,602 **** --- 611,621 ---- write("\n") dispatch[IntType] = dump_int + + if _bool_is_builtin: + def dump_bool(self, value, write): + write("") + write(value and "1" or "0") + write("\n") + dispatch[bool] = dump_bool def dump_long(self, value, write): From tim_one@users.sourceforge.net Wed Jan 22 20:22:27 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 22 Jan 2003 12:22:27 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.148,1.149 test_datetime.py,1.100,1.101 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv12630 Modified Files: datetime.py test_datetime.py Log Message: Added new test for fromutc(), and repaired a type-checking hole this uncovered. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.148 retrieving revision 1.149 diff -C2 -d -r1.148 -r1.149 *** datetime.py 21 Jan 2003 21:46:13 -0000 1.148 --- datetime.py 22 Jan 2003 20:22:23 -0000 1.149 *************** *** 881,884 **** --- 881,886 ---- "datetime in UTC -> datetime in local time." + if not isinstance(dt, datetime): + raise TypeError("fromutc() requires a datetime argument") if dt.tzinfo is not self: raise ValueError("dt.tzinfo is not self") *************** *** 893,897 **** dtdst = dt.dst() if dtdst is None: ! raise ValueError("fromutc() requires a non_none dst() result") delta = dtoff - dtdst if delta: --- 895,899 ---- dtdst = dt.dst() if dtdst is None: ! raise ValueError("fromutc() requires a non-None dst() result") delta = dtoff - dtdst if delta: Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -d -r1.100 -r1.101 *** test_datetime.py 21 Jan 2003 21:19:46 -0000 1.100 --- test_datetime.py 22 Jan 2003 20:22:24 -0000 1.101 *************** *** 2799,2802 **** --- 2799,2853 ---- self.assertRaises(ValueError, now.astimezone, notok()) + def test_fromutc(self): + self.assertRaises(TypeError, Eastern.fromutc) # not enough args + now = datetime.utcnow().replace(tzinfo=utc_real) + self.assertRaises(ValueError, Eastern.fromutc, now) # wrong tzinfo + now = now.replace(tzinfo=Eastern) # insert correct tzinfo + enow = Eastern.fromutc(now) # doesn't blow up + self.assertEqual(enow.tzinfo, Eastern) # has right tzinfo member + self.assertRaises(TypeError, Eastern.fromutc, now, now) # too many args + self.assertRaises(TypeError, Eastern.fromutc, date.today()) # wrong type + + # Always converts UTC to standard time. + class FauxUSTimeZone(USTimeZone): + def fromutc(self, dt): + return dt + self.stdoffset + FEastern = FauxUSTimeZone(-5, "FEastern", "FEST", "FEDT") + + # UTC 4:MM 5:MM 6:MM 7:MM 8:MM 9:MM + # EST 23:MM 0:MM 1:MM 2:MM 3:MM 4:MM + # EDT 0:MM 1:MM 2:MM 3:MM 4:MM 5:MM + + # Check around DST start. + start = self.dston.replace(hour=4, tzinfo=Eastern) + fstart = start.replace(tzinfo=FEastern) + for wall in 23, 0, 1, 3, 4, 5: + expected = start.replace(hour=wall) + if wall == 23: + expected -= timedelta(days=1) + got = Eastern.fromutc(start) + self.assertEqual(expected, got) + + expected = fstart + FEastern.stdoffset + got = FEastern.fromutc(fstart) + self.assertEqual(expected, got) + + start += HOUR + fstart += HOUR + + # Check around DST end. + start = self.dstoff.replace(hour=4, tzinfo=Eastern) + fstart = start.replace(tzinfo=FEastern) + for wall in 0, 1, 1, 2, 3, 4: + expected = start.replace(hour=wall) + got = Eastern.fromutc(start) + self.assertEqual(expected, got) + + expected = fstart + FEastern.stdoffset + got = FEastern.fromutc(fstart) + self.assertEqual(expected, got) + + start += HOUR + fstart += HOUR def test_suite(): From tim_one@users.sourceforge.net Wed Jan 22 20:49:25 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 22 Jan 2003 12:49:25 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.101,1.102 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv23607 Modified Files: test_datetime.py Log Message: Ensure astimezone() calls user-defined fromutc() (if any). Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -d -r1.101 -r1.102 *** test_datetime.py 22 Jan 2003 20:22:24 -0000 1.101 --- test_datetime.py 22 Jan 2003 20:49:21 -0000 1.102 *************** *** 2833,2836 **** --- 2833,2840 ---- self.assertEqual(expected, got) + # Ensure astimezone() calls fromutc() too. + got = fstart.replace(tzinfo=utc_real).astimezone(FEastern) + self.assertEqual(expected, got) + start += HOUR fstart += HOUR *************** *** 2846,2849 **** --- 2850,2857 ---- expected = fstart + FEastern.stdoffset got = FEastern.fromutc(fstart) + self.assertEqual(expected, got) + + # Ensure astimezone() calls fromutc() too. + got = fstart.replace(tzinfo=utc_real).astimezone(FEastern) self.assertEqual(expected, got) From tim_one@users.sourceforge.net Thu Jan 23 16:36:14 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 08:36:14 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv29897/python/Modules Modified Files: datetimemodule.c Log Message: Bringing the code and test suite into line with doc and NEWS changes checked in two days agao: Refactoring of, and new rules for, dt.astimezone(tz). dt must be aware now, and tz.utcoffset() and tz.dst() must not return None. The old dt.astimezone(None) no longer works to change an aware datetime into a naive datetime; use dt.replace(tzinfo=None) instead. The tzinfo base class now supplies a new fromutc(self, dt) method, and datetime.astimezone(tz) invokes tz.fromutc(). The default implementation of fromutc() reproduces the same results as the old astimezone() implementation, but tzinfo subclasses can override fromutc() if the default implementation isn't strong enough to get the correct results in all cases (for example, this may be necessary if a tzinfo subclass models a time zone whose "standard offset" (wrt UTC) changed in some year(s), or in some variations of double-daylight time -- the creativity of time zone politics can't be captured in a single default implementation). Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** datetimemodule.c 20 Jan 2003 22:54:38 -0000 1.41 --- datetimemodule.c 23 Jan 2003 16:36:11 -0000 1.42 *************** *** 2726,2730 **** /* Methods. A subclass must implement these. */ ! static PyObject* tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt) { --- 2726,2730 ---- /* Methods. A subclass must implement these. */ ! static PyObject * tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt) { *************** *** 2732,2736 **** } ! static PyObject* tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt) { --- 2732,2736 ---- } ! static PyObject * tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt) { *************** *** 2738,2742 **** } ! static PyObject* tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt) { --- 2738,2742 ---- } ! static PyObject * tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt) { *************** *** 2744,2747 **** --- 2744,2829 ---- } + static PyObject * + tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt) + { + int y, m, d, hh, mm, ss, us; + + PyObject *result; + int off, dst; + int none; + int delta; + + if (! PyDateTime_Check(dt)) { + PyErr_SetString(PyExc_TypeError, + "fromutc: argument must be a datetime"); + return NULL; + } + if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) { + PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " + "is not self"); + return NULL; + } + + off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none); + if (off == -1 && PyErr_Occurred()) + return NULL; + if (none) { + PyErr_SetString(PyExc_ValueError, "fromutc: non-None " + "utcoffset() result required"); + return NULL; + } + + dst = call_dst(dt->tzinfo, (PyObject *)dt, &none); + if (dst == -1 && PyErr_Occurred()) + return NULL; + if (none) { + PyErr_SetString(PyExc_ValueError, "fromutc: non-None " + "dst() result required"); + return NULL; + } + + y = GET_YEAR(dt); + m = GET_MONTH(dt); + d = GET_DAY(dt); + hh = DATE_GET_HOUR(dt); + mm = DATE_GET_MINUTE(dt); + ss = DATE_GET_SECOND(dt); + us = DATE_GET_MICROSECOND(dt); + + delta = off - dst; + mm += delta; + if ((mm < 0 || mm >= 60) && + normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) + goto Fail; + result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo); + if (result == NULL) + return result; + + dst = call_dst(dt->tzinfo, result, &none); + if (dst == -1 && PyErr_Occurred()) + goto Fail; + if (none) + goto Inconsistent; + if (dst == 0) + return result; + + mm += dst; + if ((mm < 0 || mm >= 60) && + normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) + goto Fail; + Py_DECREF(result); + result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo); + return result; + + Inconsistent: + PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave" + "inconsistent results; cannot convert"); + + /* fall thru to failure */ + Fail: + Py_DECREF(result); + return NULL; + } + /* * Pickle support. This is solely so that tzinfo subclasses can use *************** *** 2773,2776 **** --- 2855,2861 ---- PyDoc_STR("datetime -> DST offset in minutes east of UTC.")}, + {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O, + PyDoc_STR("datetime in UTC -> datetime in local time.")}, + {NULL, NULL} }; *************** *** 4037,4143 **** datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) { ! int y = GET_YEAR(self); ! int m = GET_MONTH(self); ! int d = GET_DAY(self); ! int hh = DATE_GET_HOUR(self); ! int mm = DATE_GET_MINUTE(self); ! int ss = DATE_GET_SECOND(self); ! int us = DATE_GET_MICROSECOND(self); ! PyObject *result; ! PyObject *temp; ! int selfoff, resoff, dst1; ! int none; ! int delta; PyObject *tzinfo; static char *keywords[] = {"tz", NULL}; ! if (! PyArg_ParseTupleAndKeywords(args, kw, "O:astimezone", keywords, ! &tzinfo)) ! return NULL; ! if (check_tzinfo_subclass(tzinfo) < 0) return NULL; ! /* Don't call utcoffset unless necessary. */ ! result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo); ! if (result == NULL || ! tzinfo == Py_None || ! ! HASTZINFO(self) || ! self->tzinfo == Py_None || ! self->tzinfo == tzinfo) ! return result; ! ! /* Get the offsets. If either object turns out to be naive, again ! * there's no conversion of date or time fields. ! */ ! selfoff = call_utcoffset(self->tzinfo, (PyObject *)self, &none); ! if (selfoff == -1 && PyErr_Occurred()) ! goto Fail; ! if (none) ! return result; ! ! resoff = call_utcoffset(tzinfo, result, &none); ! if (resoff == -1 && PyErr_Occurred()) ! goto Fail; ! if (none) ! return result; ! /* See the long comment block at the end of this file for an ! * explanation of this algorithm. That it always works requires a ! * pretty intricate proof. There are many equivalent ways to code ! * up the proof as an algorithm. This way favors calling dst() over ! * calling utcoffset(), because "the usual" utcoffset() calls dst() ! * itself, and calling the latter instead saves a Python-level ! * function call. This way of coding it also follows the proof ! * closely, w/ x=self, y=result, z=result, and z'=temp. ! */ ! dst1 = call_dst(tzinfo, result, &none); ! if (dst1 == -1 && PyErr_Occurred()) ! goto Fail; ! if (none) { ! PyErr_SetString(PyExc_ValueError, "astimezone(): utcoffset() " ! "returned a duration but dst() returned None"); ! goto Fail; } - delta = resoff - dst1 - selfoff; - if (delta) { - mm += delta; - if ((mm < 0 || mm >= 60) && - normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) - goto Fail; - temp = new_datetime(y, m, d, hh, mm, ss, us, tzinfo); - if (temp == NULL) - goto Fail; - Py_DECREF(result); - result = temp; ! dst1 = call_dst(tzinfo, result, &none); ! if (dst1 == -1 && PyErr_Occurred()) ! goto Fail; ! if (none) ! goto Inconsistent; ! } ! if (dst1 == 0) ! return result; ! mm += dst1; if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) ! goto Fail; ! temp = new_datetime(y, m, d, hh, mm, ss, us, tzinfo); ! if (temp == NULL) ! goto Fail; ! Py_DECREF(result); ! result = temp; ! return result; ! Inconsistent: ! PyErr_SetString(PyExc_ValueError, "astimezone(): tz.dst() gave" ! "inconsistent results; cannot convert"); ! /* fall thru to failure */ ! Fail: ! Py_DECREF(result); return NULL; } --- 4122,4178 ---- datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) { ! int y, m, d, hh, mm, ss, us; PyObject *result; ! int offset, none; PyObject *tzinfo; static char *keywords[] = {"tz", NULL}; ! if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords, ! &PyDateTime_TZInfoType, &tzinfo)) return NULL; ! if (!HASTZINFO(self) || self->tzinfo == Py_None) ! goto NeedAware; ! /* Conversion to self's own time zone is a NOP. */ ! if (self->tzinfo == tzinfo) { ! Py_INCREF(self); ! return (PyObject *)self; } ! /* Convert self to UTC. */ ! offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none); ! if (offset == -1 && PyErr_Occurred()) ! return NULL; ! if (none) ! goto NeedAware; ! y = GET_YEAR(self); ! m = GET_MONTH(self); ! d = GET_DAY(self); ! hh = DATE_GET_HOUR(self); ! mm = DATE_GET_MINUTE(self); ! ss = DATE_GET_SECOND(self); ! us = DATE_GET_MICROSECOND(self); ! ! mm -= offset; if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) ! return NULL; ! /* Attach new tzinfo and let fromutc() do the rest. */ ! result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo); ! if (result != NULL) { ! PyObject *temp = result; ! result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp); ! Py_DECREF(temp); ! } ! return result; ! ! NeedAware: ! PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to " ! "a naive datetime"); return NULL; } From tim_one@users.sourceforge.net Thu Jan 23 16:36:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 08:36:13 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv29897/python/Lib/test Modified Files: test_datetime.py Log Message: Bringing the code and test suite into line with doc and NEWS changes checked in two days agao: Refactoring of, and new rules for, dt.astimezone(tz). dt must be aware now, and tz.utcoffset() and tz.dst() must not return None. The old dt.astimezone(None) no longer works to change an aware datetime into a naive datetime; use dt.replace(tzinfo=None) instead. The tzinfo base class now supplies a new fromutc(self, dt) method, and datetime.astimezone(tz) invokes tz.fromutc(). The default implementation of fromutc() reproduces the same results as the old astimezone() implementation, but tzinfo subclasses can override fromutc() if the default implementation isn't strong enough to get the correct results in all cases (for example, this may be necessary if a tzinfo subclass models a time zone whose "standard offset" (wrt UTC) changed in some year(s), or in some variations of double-daylight time -- the creativity of time zone politics can't be captured in a single default implementation). Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** test_datetime.py 20 Jan 2003 22:54:38 -0000 1.26 --- test_datetime.py 23 Jan 2003 16:36:10 -0000 1.27 *************** *** 1314,1331 **** def test_astimezone(self): ! # Pretty boring! The TZ test is more interesting here. dt = self.theclass.now() f = FixedOffset(44, "") - for dtz in dt.astimezone(f), dt.astimezone(tz=f): - self.failUnless(isinstance(dtz, datetime)) - self.assertEqual(dt.date(), dtz.date()) - self.assertEqual(dt.time(), dtz.time()) - self.failUnless(dtz.tzinfo is f) - self.assertEqual(dtz.utcoffset(), timedelta(minutes=44)) - self.assertRaises(TypeError, dt.astimezone) # not enough args self.assertRaises(TypeError, dt.astimezone, f, f) # too many args self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type class TestTime(unittest.TestCase): --- 1314,1338 ---- def test_astimezone(self): ! # Pretty boring! The TZ test is more interesting here. astimezone() ! # simply can't be applied to a naive object. dt = self.theclass.now() f = FixedOffset(44, "") self.assertRaises(TypeError, dt.astimezone) # not enough args self.assertRaises(TypeError, dt.astimezone, f, f) # too many args self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type + self.assertRaises(ValueError, dt.astimezone, f) # naive + self.assertRaises(ValueError, dt.astimezone, tz=f) # naive + + class Bogus(tzinfo): + def utcoffset(self, dt): return None + def dst(self, dt): return timedelta(0) + bog = Bogus() + self.assertRaises(ValueError, dt.astimezone, bog) # naive + class AlsoBogus(tzinfo): + def utcoffset(self, dt): return timedelta(0) + def dst(self, dt): return None + alsobog = AlsoBogus() + self.assertRaises(ValueError, dt.astimezone, alsobog) # also naive class TestTime(unittest.TestCase): *************** *** 2444,2458 **** dt = self.theclass.now(tzinfo=f44m) self.failUnless(dt.tzinfo is f44m) ! # Replacing with degenerate tzinfo doesn't do any adjustment. ! for x in dt.astimezone(fnone), dt.astimezone(tz=fnone): ! self.failUnless(x.tzinfo is fnone) ! self.assertEqual(x.date(), dt.date()) ! self.assertEqual(x.time(), dt.time()) ! # Ditt with None tz. ! x = dt.astimezone(tz=None) ! self.failUnless(x.tzinfo is None) ! self.assertEqual(x.date(), dt.date()) ! self.assertEqual(x.time(), dt.time()) ! # Ditto replacing with same tzinfo. x = dt.astimezone(dt.tzinfo) self.failUnless(x.tzinfo is f44m) --- 2451,2459 ---- dt = self.theclass.now(tzinfo=f44m) self.failUnless(dt.tzinfo is f44m) ! # Replacing with degenerate tzinfo raises an exception. ! self.assertRaises(ValueError, dt.astimezone, fnone) ! # Ditto with None tz. ! self.assertRaises(TypeError, dt.astimezone, None) ! # Replacing with same tzinfo makes no change. x = dt.astimezone(dt.tzinfo) self.failUnless(x.tzinfo is f44m) *************** *** 2604,2608 **** # Can't compare naive to aware objects, so strip the timezone from # dt first. ! if start <= dt.astimezone(None) < end: return HOUR else: --- 2605,2609 ---- # Can't compare naive to aware objects, so strip the timezone from # dt first. ! if start <= dt.replace(tzinfo=None) < end: return HOUR else: *************** *** 2631,2636 **** # Conversion to our own timezone is always an identity. self.assertEqual(dt.astimezone(tz), dt) - # Conversion to None is always the same as stripping tzinfo. - self.assertEqual(dt.astimezone(None), dt.replace(tzinfo=None)) asutc = dt.astimezone(utc) --- 2632,2635 ---- *************** *** 2685,2690 **** # Conversion to our own timezone is always an identity. self.assertEqual(dt.astimezone(tz), dt) ! # Conversion to None is always the same as stripping tzinfo. ! self.assertEqual(dt.astimezone(None), dt.replace(tzinfo=None)) def convert_between_tz_and_utc(self, tz, utc): --- 2684,2692 ---- # Conversion to our own timezone is always an identity. self.assertEqual(dt.astimezone(tz), dt) ! ! # Converting to UTC and back is an identity too. ! asutc = dt.astimezone(utc) ! there_and_back = asutc.astimezone(tz) ! self.assertEqual(dt, there_and_back) def convert_between_tz_and_utc(self, tz, utc): *************** *** 2738,2742 **** fourback = self.dston - timedelta(hours=4) ninewest = FixedOffset(-9*60, "-0900", 0) ! fourback = fourback.astimezone(ninewest) # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST. Since it's "after # 2", we should get the 3 spelling. --- 2740,2744 ---- fourback = self.dston - timedelta(hours=4) ninewest = FixedOffset(-9*60, "-0900", 0) ! fourback = fourback.replace(tzinfo=ninewest) # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST. Since it's "after # 2", we should get the 3 spelling. *************** *** 2747,2761 **** # get the 3 spelling. expected = self.dston.replace(hour=3) ! got = fourback.astimezone(Eastern).astimezone(None) self.assertEqual(expected, got) # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST. In that # case we want the 1:00 spelling. ! sixutc = self.dston.replace(hour=6).astimezone(utc_real) # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4, # and adding -4-0 == -4 gives the 2:00 spelling. We want the 1:00 EST # spelling. expected = self.dston.replace(hour=1) ! got = sixutc.astimezone(Eastern).astimezone(None) self.assertEqual(expected, got) --- 2749,2763 ---- # get the 3 spelling. expected = self.dston.replace(hour=3) ! got = fourback.astimezone(Eastern).replace(tzinfo=None) self.assertEqual(expected, got) # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST. In that # case we want the 1:00 spelling. ! sixutc = self.dston.replace(hour=6, tzinfo=utc_real) # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4, # and adding -4-0 == -4 gives the 2:00 spelling. We want the 1:00 EST # spelling. expected = self.dston.replace(hour=1) ! got = sixutc.astimezone(Eastern).replace(tzinfo=None) self.assertEqual(expected, got) *************** *** 2798,2801 **** --- 2800,2863 ---- def dst(self, dt): return None self.assertRaises(ValueError, now.astimezone, notok()) + + def test_fromutc(self): + self.assertRaises(TypeError, Eastern.fromutc) # not enough args + now = datetime.utcnow().replace(tzinfo=utc_real) + self.assertRaises(ValueError, Eastern.fromutc, now) # wrong tzinfo + now = now.replace(tzinfo=Eastern) # insert correct tzinfo + enow = Eastern.fromutc(now) # doesn't blow up + self.assertEqual(enow.tzinfo, Eastern) # has right tzinfo member + self.assertRaises(TypeError, Eastern.fromutc, now, now) # too many args + self.assertRaises(TypeError, Eastern.fromutc, date.today()) # wrong type + + # Always converts UTC to standard time. + class FauxUSTimeZone(USTimeZone): + def fromutc(self, dt): + return dt + self.stdoffset + FEastern = FauxUSTimeZone(-5, "FEastern", "FEST", "FEDT") + + # UTC 4:MM 5:MM 6:MM 7:MM 8:MM 9:MM + # EST 23:MM 0:MM 1:MM 2:MM 3:MM 4:MM + # EDT 0:MM 1:MM 2:MM 3:MM 4:MM 5:MM + + # Check around DST start. + start = self.dston.replace(hour=4, tzinfo=Eastern) + fstart = start.replace(tzinfo=FEastern) + for wall in 23, 0, 1, 3, 4, 5: + expected = start.replace(hour=wall) + if wall == 23: + expected -= timedelta(days=1) + got = Eastern.fromutc(start) + self.assertEqual(expected, got) + + expected = fstart + FEastern.stdoffset + got = FEastern.fromutc(fstart) + self.assertEqual(expected, got) + + # Ensure astimezone() calls fromutc() too. + got = fstart.replace(tzinfo=utc_real).astimezone(FEastern) + self.assertEqual(expected, got) + + start += HOUR + fstart += HOUR + + # Check around DST end. + start = self.dstoff.replace(hour=4, tzinfo=Eastern) + fstart = start.replace(tzinfo=FEastern) + for wall in 0, 1, 1, 2, 3, 4: + expected = start.replace(hour=wall) + got = Eastern.fromutc(start) + self.assertEqual(expected, got) + + expected = fstart + FEastern.stdoffset + got = FEastern.fromutc(fstart) + self.assertEqual(expected, got) + + # Ensure astimezone() calls fromutc() too. + got = fstart.replace(tzinfo=utc_real).astimezone(FEastern) + self.assertEqual(expected, got) + + start += HOUR + fstart += HOUR From neal@metaslash.com Thu Jan 23 16:56:40 2003 From: neal@metaslash.com (Neal Norwitz) Date: Thu, 23 Jan 2003 11:56:40 -0500 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.41,1.42 In-Reply-To: References: Message-ID: <20030123165640.GY28870@epoch.metaslash.com> > + delta = off - dst; > + mm += delta; > + if ((mm < 0 || mm >= 60) && > + normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) > + goto Fail; Shouldn't this be return NULL? result doesn't seem to be set yet. > + result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo); > + if (result == NULL) > + return result; > + > + dst = call_dst(dt->tzinfo, result, &none); > + if (dst == -1 && PyErr_Occurred()) > + goto Fail; > + if (none) > + goto Inconsistent; > + if (dst == 0) > + return result; > + > + mm += dst; > + if ((mm < 0 || mm >= 60) && > + normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) > + goto Fail; > + Py_DECREF(result); > + result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo); > + return result; > + > + Inconsistent: > + PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave" > + "inconsistent results; cannot convert"); > + > + /* fall thru to failure */ > + Fail: > + Py_DECREF(result); > + return NULL; > + } From montanaro@users.sourceforge.net Thu Jan 23 17:26:05 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 23 Jan 2003 09:26:05 -0800 Subject: [Python-checkins] python/nondist/peps pep-0000.txt,1.223,1.224 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv23505 Modified Files: pep-0000.txt Log Message: add pep 304 Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.223 retrieving revision 1.224 diff -C2 -d -r1.223 -r1.224 *** pep-0000.txt 31 Dec 2002 16:06:42 -0000 1.223 --- pep-0000.txt 23 Jan 2003 17:25:59 -0000 1.224 *************** *** 106,109 **** --- 106,110 ---- S 302 New Import Hooks JvR S 303 Extend divmod() for Multiple Divisors Bellman + S 304 Controlling generation of bytecode files Montanaro Finished PEPs (done, implemented in CVS) *************** *** 299,302 **** --- 300,304 ---- S 302 New Import Hooks JvR S 303 Extend divmod() for Multiple Divisors Bellman + S 304 Controlling generation of bytecode files Montanaro SR 666 Reject Foolish Indentation Creighton From montanaro@users.sourceforge.net Thu Jan 23 17:26:44 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 23 Jan 2003 09:26:44 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv23990 Added Files: pep-0304.txt Log Message: new pep - initial feedback from python-dev incorporated. --- NEW FILE: pep-0304.txt --- PEP: 304 Title: Controlling generation of bytecode files Version: $Revision: 1.1 $ Last-Modified: $Date: 2003/01/23 17:26:42 $ Author: Skip Montanaro Status: Active Type: Draft Content-Type: text/x-rst Created: 22-Jan-2003 Post-History: Abstract ======== This PEP outlines a mechanism for controlling the generation and location of compiled Python bytecode files. This idea originally arose as a patch request [1]_ and evolved into a discussion thread on the python-dev mailing list [2]_. The introduction of an environment variable will allow people installing Python or Python-based third-party packages to control whether or not bytecode files should be generated, and if so, where they should be written. Proposal ======== Add a new environment variable, PYTHONBYTECODEBASE, to the mix of environment variables which Python understands. Its interpretation is: - If not present Python bytecode is generated in exactly the same way as is currently done. sys.pythonbytecodebase is set to the root directory (either / on Unix or the root directory of the startup drive -- typically ``C:\`` -- on Windows). - If present and it refers to an existing directory, sys.pythonbytecodebase is set to that directory and bytecode files are written into a directory structure rooted at that location. - If present but empty, sys.pythonbytecodebase is set to None and generation of bytecode files is suppressed altogether. - If present and it does not refer to an existing directory, a warning is displayed, sys.pythonbytecodebase is set to None and generation of bytecode files is suppressed altogether. After startup, all runtime references are to sys.pythonbytecodebase, not the PYTHONBYTECODEBASE enbironment variable. sys.path is not modified. Glossary -------- - "bytecode base" refers to the current setting of sys.pythonbytecodebase. - "augmented directory" refers to the directory formed from the bytecode base and the directory name of the source file. - PYTHONBYTECODEBASE refers to the environment variable when necessary to distinguish it from "bytecode base". Locating bytecode files ----------------------- When the interpreter is searching for a module, it will use sys.path as usual. However, when a possible bytecode file is considered, an extra probe for a bytecode file may be made. First, a check is made for the bytecode file using the directory in sys.path which holds the source file (the current behavior). If a valid bytecode file is not found there (either one does not exist or exists but is out-of-date) and the bytecode base is not None, a second probe is made using the directory in sys.path prefixed appropriately by the bytecode base. Writing bytecode files ---------------------- When the bytecode base is not None, a new bytecode file is written to the appropriate augmented directory, never directly to a directory in sys.path. Defining augmented directories ------------------------------ Conceptually, the augmented directory for a bytecode file is the directory in which the source file exists prefixed by the bytecode base. In a Unix environment this would be: pcb = os.path.abspath(sys.pythonbytecodebase) if sourcefile[0] == os.sep: sourcefile = sourcefile[1:] augdir = os.path.join(pcb, os.path.dirname(sourcefile)) On Windows, which does not have a single-rooted directory tree, the drive letter of the directory containing the source file is treated as a directory component after removing the trailing colon. The augmented directory is thus derived as pcb = os.path.abspath(sys.pythonbytecodebase) drive, base = os.path.splitdrive(os.path.dirname(sourcefile)) drive = drive[:-1] if base[0] == "\\": base = base[1:] augdir = os.path.join(pcb, drive, base) Fixing the location of the bytecode base ---------------------------------------- During program startup, the value of the PYTHONBYTECODEBASE environment variable is made absolute, checked for validity and added to the sys module, effectively: pcb = os.path.abspath(os.environ["PYTHONBYTECODEBASE"]) try: probe = os.path.join(pcb, "foo") open(probe, "w") os.unlink(probe) sys.pythonbytecodebase = pcb except IOError: sys.pythonbytecodebase = None This allows the user to specify the bytecode base as a relative path, but not have it subject to changes to the current working directory. (I can't imagine you'd want it to move around during program execution.) There is nothing special about sys.pythonbytecodebase. The user may change it at runtime if she so chooses, but normally it will not be modified. Rationale ========= In many environments it is not possible for non-root users to write into directories containing Python source files. Most of the time, this is not a problem as Python source is generally byte compiled during installation. However, there are situations where bytecode files are either missing or need to be updated. If the directory containing the source file is not writable by the current user a performance penalty is incurred each time a program importing the module is run. [3]_ Warning messages may also be generated in certain circumstances. If the directory is writable, nearly simultaneous attempts attempts to write the bytecode file by two separate processes may occur, resulting in file corruption. [4]_ In environments with ramdisks available, it may be desirable for performance reasons to write bytecode files to a directory on such a disk. Similarly, in environments where Python source code resides on network file systems, it may be desirable to cache bytecode files on local disks. Alternatives ============ The only other alternative proposed so far [1]_ seems to be to add a -R flag to the interpreter to disable writing bytecode files altogether. This proposal subsumes that. Adding a command-line option is certainly possible, but is probably not sufficient, as the interpreter's command line is not readily available during installation. Issues ====== - Interpretation of a module's __file__ attribute. I believe the __file__ attribute of a module should reflect the true location of the bytecode file. If people want to locate a module's source code, they should use imp.find_module(module). - Security - What if root has PYTHONBYTECODEBASE set? Yes, this can present a security risk, but so can many other things the root user does. The root user should probably not set PYTHONBYTECODEBASE except during installation. Still, perhaps this problem can be minimized. When running as root the interpreter should check to see if PYTHONBYTECODEBASE refers to a directory which is writable by anyone other than root. If so, it could raise an exception or warning and set sys.pythonbytecodebase to None. Or, see the next item. - More security - What if PYTHONBYTECODEBASE refers to a general directory (say, /tmp)? In this case, perhaps loading of a preexisting bytecode file should occur only if the file is owned by the current user or root. (Does this matter on Windows?) Examples ======== In the examples which follow, the urllib source code resides in /usr/lib/python2.3/urllib.py and /usr/lib/python2.3 is in sys.path but is not writable by the current user. - The bytecode base is /tmp. /usr/lib/python2.3/urllib.pyc exists and is valid. When urllib is imported, the contents of /usr/lib/python2.3/urllib.pyc are used. The augmented directory is not consulted. No other bytecode file is generated. - The bytecode base is /tmp. /usr/lib/python2.3/urllib.pyc exists, but is out-of-date. When urllib is imported, the generated bytecode file is written to urllib.pyc in the augmented directory. Intermediate directories will be created as needed. - The bytecode base is None. No urllib.pyc file is found. When urllib is imported, no bytecode file is written. - The bytecode base is /tmp. No urllib.pyc file is found. When urllib is imported, the generated bytecode file is written to the augmented directory, creating intermediate directories as needed. - At startup, PYTHONBYTECODEBASE is /tmp/foobar, which does not exist. A warning is emitted, sys.pythonbytecodebase is set to None and no bytecode files are written during program execution unless sys.pythonbytecodebase is later changed to refer to a valid, writable directory. - At startup, PYTHONBYTECODEBASE is set to /, which exists, but is not writable by the current user. A warning is emitted, sys.pythonbytecodebase is set to None and no bytecode files are written during program execution unless sys.pythonbytecodebase is later changed to refer to a valid, writable directory. Note that even though the augmented directory constructed for a particular bytecode file may be writable by the current user, what counts is that the bytecode base directory itself is writable. - At startup PYTHONBYTECODEBASE is set to the empty string. sys.pythonbytecodebase is set to None. No warning is generated, however. If no urllib.pyc file is found when urllib is imported, no bytecode file is written. In the Windows examples which follow, the urllib source code resides in ``C:\PYTHON22\urllib.py``. ``C:\\PYTHON22`` is in sys.path but is not writable by the current user. - The bytecode base is set to ``C:\TEMP``. ``C:\PYTHON22\urllib.pyc`` exists and is valid. When urllib is imported, the contents of ``C:\PYTHON22\urllib.pyc`` are used. The augmented directory is not consulted. - The bytecode base is set to ``C:\TEMP``. ``C:\PYTHON22\urllib.pyc`` exists, but is out-of-date. When urllib is imported, a new bytecode file is written to the augmented directory. Intermediate directories will be created as needed. - At startuyp PYTHONBYTECODEBASE is set to ``TEMP`` and the current working directory at application startup is ``H:\NET``. The potential bytecode base is thus ``H:\NET\TEMP``. If this directory exists and is writable by the current user, sys.pythonbytecodebase will be set to that value. If not, a warning will be emitted and sys.pythonbytecodebase will be set to None. - The bytecode base is ``C:\TEMP``. No urllib.pyc file is found. When urllib is imported, the generated bytecode file is written to the augmented directory, creating intermediate directories as needed. References ========== .. [1] patch 602345, Option for not writing py.[co] files, Klose (http://www.python.org/sf/602345) .. [2] python-dev thread, Disable writing .py[co], Norwitz (http://mail.python.org/pipermail/python-dev/2003-January/032270.html) .. [3] Debian bug report, Mailman is writing to /usr in cron, Wegner (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=96111) .. [4] python-dev thread, Parallel pyc construction, Dubois (http://mail.python.org/pipermail/python-dev/2003-January/032060.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: From tim_one@users.sourceforge.net Thu Jan 23 17:20:42 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 09:20:42 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv20565/python/Modules Modified Files: datetimemodule.c Log Message: fromutc(): Repair incorrect failure return, as noted by NealN. Thanks! Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** datetimemodule.c 23 Jan 2003 16:36:11 -0000 1.42 --- datetimemodule.c 23 Jan 2003 17:20:36 -0000 1.43 *************** *** 2795,2799 **** if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) ! goto Fail; result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo); if (result == NULL) --- 2795,2799 ---- if ((mm < 0 || mm >= 60) && normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0) ! return NULL; result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo); if (result == NULL) From jhylton@users.sourceforge.net Thu Jan 23 18:02:24 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Thu, 23 Jan 2003 10:02:24 -0800 Subject: [Python-checkins] python/dist/src/Lib/test/output test_httplib,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory sc8-pr-cvs1:/tmp/cvs-serv15096/Lib/test/output Modified Files: test_httplib Log Message: Fix for SF bug 661340: test_httplib fails on the mac. The test no longer produces output with \r\n in it. Index: test_httplib =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_httplib,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_httplib 7 Jul 2002 16:51:37 -0000 1.3 --- test_httplib 23 Jan 2003 18:02:20 -0000 1.4 *************** *** 7,10 **** InvalidURL raised as expected reply: 'HTTP/1.1 200 OK\r\n' ! header: Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme" ! header: Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme" --- 7,11 ---- InvalidURL raised as expected reply: 'HTTP/1.1 200 OK\r\n' ! header: Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme" ! header: Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme" ! From jhylton@users.sourceforge.net Thu Jan 23 18:02:24 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Thu, 23 Jan 2003 10:02:24 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_httplib.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv15096/Lib/test Modified Files: test_httplib.py Log Message: Fix for SF bug 661340: test_httplib fails on the mac. The test no longer produces output with \r\n in it. Index: test_httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_httplib.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_httplib.py 30 Jul 2002 23:26:01 -0000 1.9 --- test_httplib.py 23 Jan 2003 18:02:18 -0000 1.10 *************** *** 12,58 **** return StringIO.StringIO(self.text) ! # Test HTTP status lines ! body = "HTTP/1.1 200 Ok\r\n\r\nText" ! sock = FakeSocket(body) ! resp = httplib.HTTPResponse(sock, 1) ! resp.begin() ! print resp.read() ! resp.close() ! body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText" ! sock = FakeSocket(body) ! resp = httplib.HTTPResponse(sock, 1) ! try: ! resp.begin() ! except httplib.BadStatusLine: ! print "BadStatusLine raised as expected" ! else: ! print "Expect BadStatusLine" ! # Check invalid host_port ! for hp in ("www.python.org:abc", "www.python.org:"): try: ! h = httplib.HTTP(hp) ! except httplib.InvalidURL: ! print "InvalidURL raised as expected" else: ! print "Expect InvalidURL" ! # 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' ! 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";' ! ' Path="/acme"\r\n' ! '\r\n' ! 'No body\r\n') ! hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"' ! ', ' ! 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"') ! s = FakeSocket(text) ! r = httplib.HTTPResponse(s, 1) ! r.begin() ! cookies = r.getheader("Set-Cookie") ! if cookies != hdr: ! raise AssertionError, "multiple headers not combined properly" --- 12,81 ---- return StringIO.StringIO(self.text) ! # Collect output to a buffer so that we don't have to cope with line-ending ! # issues across platforms. Specifically, the headers will have \r\n pairs ! # and some platforms will strip them from the output file. ! import sys ! def test(): ! buf = StringIO.StringIO() ! _stdout = sys.stdout ! try: ! sys.stdout = buf ! _test() ! finally: ! sys.stdout = _stdout ! # print individual lines with endings stripped ! s = buf.getvalue() ! for line in s.split("\n"): ! print line.strip() ! def _test(): ! # Test HTTP status lines ! ! body = "HTTP/1.1 200 Ok\r\n\r\nText" ! sock = FakeSocket(body) ! resp = httplib.HTTPResponse(sock, 1) ! resp.begin() ! print resp.read() ! resp.close() ! ! body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText" ! sock = FakeSocket(body) ! resp = httplib.HTTPResponse(sock, 1) try: ! resp.begin() ! except httplib.BadStatusLine: ! print "BadStatusLine raised as expected" else: ! print "Expect BadStatusLine" ! # Check invalid host_port ! ! for hp in ("www.python.org:abc", "www.python.org:"): ! try: ! h = httplib.HTTP(hp) ! except httplib.InvalidURL: ! print "InvalidURL raised as expected" ! else: ! print "Expect InvalidURL" ! ! # 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' ! 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";' ! ' Path="/acme"\r\n' ! '\r\n' ! 'No body\r\n') ! hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"' ! ', ' ! 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"') ! s = FakeSocket(text) ! r = httplib.HTTPResponse(s, 1) ! r.begin() ! cookies = r.getheader("Set-Cookie") ! if cookies != hdr: ! raise AssertionError, "multiple headers not combined properly" ! ! test() From jhylton@users.sourceforge.net Thu Jan 23 18:29:35 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Thu, 23 Jan 2003 10:29:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/logging __init__.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1:/tmp/cvs-serv30176 Modified Files: __init__.py Log Message: Use lightweight introspection instead of the inspect module hammer. Removing locking are findCaller() calls as the implementation using sys._getframe() is thread-safe. Changes reviewed by Vinay. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/__init__.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** __init__.py 15 Nov 2002 23:31:28 -0000 1.3 --- __init__.py 23 Jan 2003 18:29:29 -0000 1.4 *************** *** 20,24 **** Should work under Python versions >= 1.5.2, except that source line ! information is not available unless 'inspect' is. Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved. --- 20,24 ---- Should work under Python versions >= 1.5.2, except that source line ! information is not available unless 'sys._getframe()' is. Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved. *************** *** 34,41 **** except ImportError: thread = None - try: - import inspect - except ImportError: - inspect = None __author__ = "Vinay Sajip " --- 34,37 ---- *************** *** 57,60 **** --- 53,63 ---- _srcfile = os.path.normcase(_srcfile) + # _srcfile is only used in conjunction with sys._getframe(). + # To provide compatibility with older versions of Python, set _srcfile + # to None if _getframe() is not available; this value will prevent + # findCaller() from being called. + if not hasattr(sys, "_getframe"): + _srcfile = None + # #_startTime is used as the base when calculating the relative time of events *************** *** 928,944 **** file name and line number. """ ! rv = (None, None) ! frame = inspect.currentframe().f_back ! while frame: ! sfn = inspect.getsourcefile(frame) ! if sfn: ! sfn = os.path.normcase(sfn) ! if sfn != _srcfile: ! #print frame.f_code.co_code ! lineno = inspect.getlineno(frame) ! rv = (sfn, lineno) ! break ! frame = frame.f_back ! return rv def makeRecord(self, name, level, fn, lno, msg, args, exc_info): --- 931,942 ---- file name and line number. """ ! f = sys._getframe(1) ! while 1: ! co = f.f_code ! filename = os.path.normcase(co.co_filename) ! if filename == _srcfile: ! f = f.f_back ! continue ! return filename, f.f_lineno def makeRecord(self, name, level, fn, lno, msg, args, exc_info): *************** *** 954,963 **** all the handlers of this logger to handle the record. """ ! if inspect and _srcfile: ! _acquireLock() ! try: ! fn, lno = self.findCaller() ! finally: ! _releaseLock() else: fn, lno = "", 0 --- 952,957 ---- all the handlers of this logger to handle the record. """ ! if _srcfile: ! fn, lno = self.findCaller() else: fn, lno = "", 0 From goodger@users.sourceforge.net Thu Jan 23 18:45:16 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu, 23 Jan 2003 10:45:16 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv4118 Modified Files: pep-0304.txt Log Message: markup fixes Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep-0304.txt 23 Jan 2003 17:26:42 -0000 1.1 --- pep-0304.txt 23 Jan 2003 18:45:09 -0000 1.2 *************** *** 63,66 **** --- 63,67 ---- to distinguish it from "bytecode base". + Locating bytecode files ----------------------- *************** *** 75,78 **** --- 76,80 ---- directory in sys.path prefixed appropriately by the bytecode base. + Writing bytecode files ---------------------- *************** *** 88,92 **** Conceptually, the augmented directory for a bytecode file is the directory in which the source file exists prefixed by the bytecode ! base. In a Unix environment this would be: pcb = os.path.abspath(sys.pythonbytecodebase) --- 90,94 ---- Conceptually, the augmented directory for a bytecode file is the directory in which the source file exists prefixed by the bytecode ! base. In a Unix environment this would be:: pcb = os.path.abspath(sys.pythonbytecodebase) *************** *** 97,101 **** drive letter of the directory containing the source file is treated as a directory component after removing the trailing colon. The ! augmented directory is thus derived as pcb = os.path.abspath(sys.pythonbytecodebase) --- 99,103 ---- drive letter of the directory containing the source file is treated as a directory component after removing the trailing colon. The ! augmented directory is thus derived as :: pcb = os.path.abspath(sys.pythonbytecodebase) *************** *** 110,114 **** During program startup, the value of the PYTHONBYTECODEBASE environment variable is made absolute, checked for validity and added ! to the sys module, effectively: pcb = os.path.abspath(os.environ["PYTHONBYTECODEBASE"]) --- 112,116 ---- During program startup, the value of the PYTHONBYTECODEBASE environment variable is made absolute, checked for validity and added ! to the sys module, effectively:: pcb = os.path.abspath(os.environ["PYTHONBYTECODEBASE"]) *************** *** 233,237 **** In the Windows examples which follow, the urllib source code resides ! in ``C:\PYTHON22\urllib.py``. ``C:\\PYTHON22`` is in sys.path but is not writable by the current user. --- 235,239 ---- In the Windows examples which follow, the urllib source code resides ! in ``C:\PYTHON22\urllib.py``. ``C:\PYTHON22`` is in sys.path but is not writable by the current user. *************** *** 257,260 **** --- 259,263 ---- the augmented directory, creating intermediate directories as needed. + References From goodger@users.sourceforge.net Thu Jan 23 18:51:13 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Thu, 23 Jan 2003 10:51:13 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv7243 Modified Files: pep-0304.txt Log Message: spelling Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pep-0304.txt 23 Jan 2003 18:45:09 -0000 1.2 --- pep-0304.txt 23 Jan 2003 18:51:09 -0000 1.3 *************** *** 47,51 **** After startup, all runtime references are to sys.pythonbytecodebase, ! not the PYTHONBYTECODEBASE enbironment variable. sys.path is not modified. --- 47,51 ---- After startup, all runtime references are to sys.pythonbytecodebase, ! not the PYTHONBYTECODEBASE environment variable. sys.path is not modified. *************** *** 148,152 **** may occur, resulting in file corruption. [4]_ ! In environments with ramdisks available, it may be desirable for performance reasons to write bytecode files to a directory on such a disk. Similarly, in environments where Python source code resides on --- 148,152 ---- may occur, resulting in file corruption. [4]_ ! In environments with RAM disks available, it may be desirable for performance reasons to write bytecode files to a directory on such a disk. Similarly, in environments where Python source code resides on *************** *** 248,252 **** directories will be created as needed. ! - At startuyp PYTHONBYTECODEBASE is set to ``TEMP`` and the current working directory at application startup is ``H:\NET``. The potential bytecode base is thus ``H:\NET\TEMP``. If this directory --- 248,252 ---- directories will be created as needed. ! - At startup PYTHONBYTECODEBASE is set to ``TEMP`` and the current working directory at application startup is ``H:\NET``. The potential bytecode base is thus ``H:\NET\TEMP``. If this directory From tim_one@users.sourceforge.net Thu Jan 23 19:58:06 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 11:58:06 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6005/python/Modules Modified Files: datetimemodule.c Log Message: Reimplemented datetime.now() to be useful. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** datetimemodule.c 23 Jan 2003 17:20:36 -0000 1.43 --- datetimemodule.c 23 Jan 2003 19:58:02 -0000 1.44 *************** *** 3667,3679 **** datetime_now(PyObject *cls, PyObject *args, PyObject *kw) { ! PyObject *self = NULL; PyObject *tzinfo = Py_None; ! static char *keywords[] = {"tzinfo", NULL}; ! if (PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords, ! &tzinfo)) { ! if (check_tzinfo_subclass(tzinfo) < 0) ! return NULL; ! self = datetime_best_possible(cls, localtime, tzinfo); } return self; --- 3667,3689 ---- datetime_now(PyObject *cls, PyObject *args, PyObject *kw) { ! PyObject *self; PyObject *tzinfo = Py_None; ! static char *keywords[] = {"tz", NULL}; ! if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords, ! &tzinfo)) ! return NULL; ! if (check_tzinfo_subclass(tzinfo) < 0) ! return NULL; ! ! self = datetime_best_possible(cls, ! tzinfo == Py_None ? localtime : gmtime, ! tzinfo); ! if (self != NULL && tzinfo != Py_None) { ! /* Convert UTC to tzinfo's zone. */ ! PyObject *temp = self; ! self = PyObject_CallMethod(tzinfo, "fromutc", ! "O", self); ! Py_DECREF(temp); } return self; From tim_one@users.sourceforge.net Thu Jan 23 19:58:32 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 11:58:32 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv6005/python/Doc/lib Modified Files: libdatetime.tex Log Message: Reimplemented datetime.now() to be useful. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** libdatetime.tex 22 Jan 2003 04:45:50 -0000 1.37 --- libdatetime.tex 23 Jan 2003 19:57:59 -0000 1.38 *************** *** 526,542 **** \end{methoddesc} ! \begin{methoddesc}{now}{} ! Return the current local datetime. This is like \method{today()}, ! but, if possible, supplies more precision than can be gotten from ! going through a \function{time.time()} timestamp (for example, ! this may be possible on platforms that supply the C \cfunction{gettimeofday()} function). See also \method{today()}, \method{utcnow()}. \end{methoddesc} \begin{methoddesc}{utcnow}{} ! Return the current UTC datetime, with \member{tzinfo} \code{None}. ! This is like \method{now()}, but ! returns the current UTC date and time. See also \method{now()}. \end{methoddesc} --- 526,548 ---- \end{methoddesc} ! \begin{methoddesc}{now(tz=None)}{} ! Return the current local date and time. If optional argument ! \var{tz} is \code{None} or not specified, this is like ! \method{today()}, but, if possible, supplies more precision than can ! be gotten from going through a \function{time.time()} timestamp (for ! example, this may be possible on platforms supplying the C \cfunction{gettimeofday()} function). + + Else \var{tz} must be an instance of a class \class{tzinfo} subclass, + and the current date and time are translated to \var{tz}'s time + zone. In this case the result is equivalent to + \code{\var{tz}.fromutc(datetime.utcnow().replace(tzinfo=\var{tz})}. See also \method{today()}, \method{utcnow()}. \end{methoddesc} \begin{methoddesc}{utcnow}{} ! Return the current UTC date and time, with \member{tzinfo} \code{None}. ! This is like \method{now()}, but returns the current UTC date and time, ! as a naive \class{datetime} object. See also \method{now()}. \end{methoddesc} From tim_one@users.sourceforge.net Thu Jan 23 19:58:04 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 11:58:04 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.619,1.620 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv6005/python/Misc Modified Files: NEWS Log Message: Reimplemented datetime.now() to be useful. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.619 retrieving revision 1.620 diff -C2 -d -r1.619 -r1.620 *** NEWS 22 Jan 2003 18:17:25 -0000 1.619 --- NEWS 23 Jan 2003 19:58:01 -0000 1.620 *************** *** 83,86 **** --- 83,97 ---- allows the highly motivated to emulate any scheme expressible in Python. + datetime.now(): The optional tzinfo argument was undocumented (that's + repaired), and its name was changed to tz ("tzinfo" is overloaded enough + already). With a tz argument, now(tz) used to return the local date + and time, and attach tz to it, without any conversion of date and time + members. This was less than useful. Now now(tz) returns the current + date and time as local time in tz's time zone, akin to + tz.fromutc(datetime.utcnow().replace(tzinfo=utc)) + where "utc" is an instance of a tzinfo subclass modeling UTC. Without + a tz argument, now() continues to return the current local date and time, + as a naive datetime object. + The constructors building a datetime from a timestamp could raise ValueError if the platform C localtime()/gmtime() inserted "leap From tim_one@users.sourceforge.net Thu Jan 23 19:58:33 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 11:58:33 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv6005/python/Lib/test Modified Files: test_datetime.py Log Message: Reimplemented datetime.now() to be useful. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** test_datetime.py 23 Jan 2003 16:36:10 -0000 1.27 --- test_datetime.py 23 Jan 2003 19:58:00 -0000 1.28 *************** *** 2229,2233 **** off42 = FixedOffset(42, "42") another = meth(off42) ! again = meth(tzinfo=off42) self.failUnless(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) --- 2229,2233 ---- off42 = FixedOffset(42, "42") another = meth(off42) ! again = meth(tz=off42) self.failUnless(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) *************** *** 2240,2243 **** --- 2240,2261 ---- self.assertRaises(TypeError, meth, off42, off42) + # We don't know which time zone we're in, and don't have a tzinfo + # class to represent it, so seeing whether a tz argument actually + # does a conversion is tricky. + weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0) + utc = FixedOffset(0, "utc", 0) + for dummy in range(3): + now = datetime.now(weirdtz) + self.failUnless(now.tzinfo is weirdtz) + utcnow = datetime.utcnow().replace(tzinfo=utc) + now2 = utcnow.astimezone(weirdtz) + if abs(now - now2) < timedelta(seconds=30): + break + # Else the code is broken, or more than 30 seconds passed between + # calls; assuming the latter, just try again. + else: + # Three strikes and we're out. + self.fail("utcnow(), now(tz), or astimezone() may be broken") + def test_tzinfo_fromtimestamp(self): import time *************** *** 2449,2453 **** fm5h = FixedOffset(-timedelta(hours=5), "m300") ! dt = self.theclass.now(tzinfo=f44m) self.failUnless(dt.tzinfo is f44m) # Replacing with degenerate tzinfo raises an exception. --- 2467,2471 ---- fm5h = FixedOffset(-timedelta(hours=5), "m300") ! dt = self.theclass.now(tz=f44m) self.failUnless(dt.tzinfo is f44m) # Replacing with degenerate tzinfo raises an exception. From tim_one@users.sourceforge.net Thu Jan 23 20:53:14 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 12:53:14 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6370/python/Modules Modified Files: datetimemodule.c Log Message: SF bug 660872: datetimetz constructors behave counterintuitively (2.3a1). This gives much the same treatment to datetime.fromtimestamp(stamp, tz) as the last batch of checkins gave to datetime.now(tz): do "the obvious" thing with the tz argument instead of a senseless thing. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** datetimemodule.c 23 Jan 2003 19:58:02 -0000 1.44 --- datetimemodule.c 23 Jan 2003 20:53:10 -0000 1.45 *************** *** 3683,3688 **** /* Convert UTC to tzinfo's zone. */ PyObject *temp = self; ! self = PyObject_CallMethod(tzinfo, "fromutc", ! "O", self); Py_DECREF(temp); } --- 3683,3687 ---- /* Convert UTC to tzinfo's zone. */ PyObject *temp = self; ! self = PyObject_CallMethod(tzinfo, "fromutc", "O", self); Py_DECREF(temp); } *************** *** 3703,3717 **** datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) { ! PyObject *self = NULL; double timestamp; PyObject *tzinfo = Py_None; ! static char *keywords[] = {"timestamp", "tzinfo", NULL}; ! if (PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp", ! keywords, ×tamp, &tzinfo)) { ! if (check_tzinfo_subclass(tzinfo) < 0) ! return NULL; ! self = datetime_from_timestamp(cls, localtime, timestamp, ! tzinfo); } return self; --- 3702,3725 ---- datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) { ! PyObject *self; double timestamp; PyObject *tzinfo = Py_None; ! static char *keywords[] = {"timestamp", "tz", NULL}; ! if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp", ! keywords, ×tamp, &tzinfo)) ! return NULL; ! if (check_tzinfo_subclass(tzinfo) < 0) ! return NULL; ! ! self = datetime_from_timestamp(cls, ! tzinfo == Py_None ? localtime : gmtime, ! timestamp, ! tzinfo); ! if (self != NULL && tzinfo != Py_None) { ! /* Convert UTC to tzinfo's zone. */ ! PyObject *temp = self; ! self = PyObject_CallMethod(tzinfo, "fromutc", "O", self); ! Py_DECREF(temp); } return self; *************** *** 4405,4409 **** {"now", (PyCFunction)datetime_now, METH_KEYWORDS | METH_CLASS, ! PyDoc_STR("[tzinfo] -> new datetime with local day and time.")}, {"utcnow", (PyCFunction)datetime_utcnow, --- 4413,4417 ---- {"now", (PyCFunction)datetime_now, METH_KEYWORDS | METH_CLASS, ! PyDoc_STR("[tz] -> new datetime with tz's locl day and time.")}, {"utcnow", (PyCFunction)datetime_utcnow, *************** *** 4413,4417 **** {"fromtimestamp", (PyCFunction)datetime_fromtimestamp, METH_KEYWORDS | METH_CLASS, ! PyDoc_STR("timestamp[, tzinfo] -> local time from POSIX timestamp.")}, {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp, --- 4421,4425 ---- {"fromtimestamp", (PyCFunction)datetime_fromtimestamp, METH_KEYWORDS | METH_CLASS, ! PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")}, {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp, From tim_one@users.sourceforge.net Thu Jan 23 20:53:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 12:53:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv6370/python/Doc/lib Modified Files: libdatetime.tex Log Message: SF bug 660872: datetimetz constructors behave counterintuitively (2.3a1). This gives much the same treatment to datetime.fromtimestamp(stamp, tz) as the last batch of checkins gave to datetime.now(tz): do "the obvious" thing with the tz argument instead of a senseless thing. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** libdatetime.tex 23 Jan 2003 19:57:59 -0000 1.38 --- libdatetime.tex 23 Jan 2003 20:53:07 -0000 1.39 *************** *** 535,541 **** Else \var{tz} must be an instance of a class \class{tzinfo} subclass, ! and the current date and time are translated to \var{tz}'s time zone. In this case the result is equivalent to ! \code{\var{tz}.fromutc(datetime.utcnow().replace(tzinfo=\var{tz})}. See also \method{today()}, \method{utcnow()}. \end{methoddesc} --- 535,541 ---- Else \var{tz} must be an instance of a class \class{tzinfo} subclass, ! and the current date and time are converted to \var{tz}'s time zone. In this case the result is equivalent to ! \code{\var{tz}.fromutc(datetime.utcnow().replace(tzinfo=\var{tz}))}. See also \method{today()}, \method{utcnow()}. \end{methoddesc} *************** *** 543,558 **** \begin{methoddesc}{utcnow}{} Return the current UTC date and time, with \member{tzinfo} \code{None}. ! This is like \method{now()}, but returns the current UTC date and time, as a naive \class{datetime} object. See also \method{now()}. \end{methoddesc} ! \begin{methoddesc}{fromtimestamp}{timestamp} ! Return the local \class{datetime} corresponding to the \POSIX{} ! timestamp, such as is returned by \function{time.time()}. This ! may raise \exception{ValueError}, if the timestamp is out of the ! range of values supported by the platform C ! \cfunction{localtime()} function. It's common for this to be ! restricted to years in 1970 through 2038. Note that on non-POSIX systems that include leap seconds in their notion of a timestamp, leap seconds are ignored by --- 543,567 ---- \begin{methoddesc}{utcnow}{} Return the current UTC date and time, with \member{tzinfo} \code{None}. ! This is like \method{now()}, but returns the current UTC date and time, as a naive \class{datetime} object. See also \method{now()}. \end{methoddesc} ! \begin{methoddesc}{fromtimestamp}{timestamp, tz=None} ! Return the local date and time corresponding to the \POSIX{} ! timestamp, such as is returned by \function{time.time()}. ! If optional argument \var{tz} is \code{None} or not specified, the ! timestamp is converted to the platform's local date and time, and ! the returned \class{datetime} object is naive. ! ! Else \var{tz} must be an instance of a class \class{tzinfo} subclass, ! and the timestamp is converted to \var{tz}'s time zone. In this case ! the result is equivalent to ! \code{\var{tz}.fromutc(datetime.utcfromtimestamp(\var{timestamp}).replace(tzinfo=\var{tz}))}. ! ! \method{fromtimestamp()} may raise \exception{ValueError}, if the ! timestamp is out of the range of values supported by the platform C ! \cfunction{localtime()} or \cfunction(gmtime()} functions. It's common ! for this to be restricted to years in 1970 through 2038. Note that on non-POSIX systems that include leap seconds in their notion of a timestamp, leap seconds are ignored by From tim_one@users.sourceforge.net Thu Jan 23 20:53:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 12:53:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv6370/python/Lib/test Modified Files: test_datetime.py Log Message: SF bug 660872: datetimetz constructors behave counterintuitively (2.3a1). This gives much the same treatment to datetime.fromtimestamp(stamp, tz) as the last batch of checkins gave to datetime.now(tz): do "the obvious" thing with the tz argument instead of a senseless thing. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** test_datetime.py 23 Jan 2003 19:58:00 -0000 1.28 --- test_datetime.py 23 Jan 2003 20:53:08 -0000 1.29 *************** *** 2267,2271 **** off42 = FixedOffset(42, "42") another = meth(ts, off42) ! again = meth(ts, tzinfo=off42) self.failUnless(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) --- 2267,2271 ---- off42 = FixedOffset(42, "42") another = meth(ts, off42) ! again = meth(ts, tz=off42) self.failUnless(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) *************** *** 2279,2282 **** --- 2279,2296 ---- # Too few args. self.assertRaises(TypeError, meth) + + # Try to make sure tz= actually does some conversion. + timestamp = 1000000000 # 2001-09-09 01:46:40 UTC, give or take + utc = FixedOffset(0, "utc", 0) + expected = datetime(2001, 9, 9, 1, 46, 40) + got = datetime.utcfromtimestamp(timestamp) + # We don't support leap seconds, but maybe the platfrom insists + # on using them, so don't demand exact equality). + self.failUnless(abs(got - expected) < timedelta(minutes=1)) + + est = FixedOffset(-5*60, "est", 0) + expected -= timedelta(hours=5) + got = datetime.fromtimestamp(timestamp, est).replace(tzinfo=None) + self.failUnless(abs(got - expected) < timedelta(minutes=1)) def test_tzinfo_utcnow(self): From tim_one@users.sourceforge.net Thu Jan 23 20:53:42 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 12:53:42 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.620,1.621 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv6370/python/Misc Modified Files: NEWS Log Message: SF bug 660872: datetimetz constructors behave counterintuitively (2.3a1). This gives much the same treatment to datetime.fromtimestamp(stamp, tz) as the last batch of checkins gave to datetime.now(tz): do "the obvious" thing with the tz argument instead of a senseless thing. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.620 retrieving revision 1.621 diff -C2 -d -r1.620 -r1.621 *** NEWS 23 Jan 2003 19:58:01 -0000 1.620 --- NEWS 23 Jan 2003 20:53:08 -0000 1.621 *************** *** 94,97 **** --- 94,101 ---- as a naive datetime object. + datetime.fromtimestamp(): Like datetime.now() above, this had less than + useful behavior when the optional tinzo argument was specified. See + also SF bug report . + The constructors building a datetime from a timestamp could raise ValueError if the platform C localtime()/gmtime() inserted "leap From nnorwitz@users.sourceforge.net Thu Jan 23 21:09:11 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 23 Jan 2003 13:09:11 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv15898/Modules Modified Files: datetimemodule.c Log Message: Fix typo Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** datetimemodule.c 23 Jan 2003 20:53:10 -0000 1.45 --- datetimemodule.c 23 Jan 2003 21:09:05 -0000 1.46 *************** *** 4413,4417 **** {"now", (PyCFunction)datetime_now, METH_KEYWORDS | METH_CLASS, ! PyDoc_STR("[tz] -> new datetime with tz's locl day and time.")}, {"utcnow", (PyCFunction)datetime_utcnow, --- 4413,4417 ---- {"now", (PyCFunction)datetime_now, METH_KEYWORDS | METH_CLASS, ! PyDoc_STR("[tz] -> new datetime with tz's local day and time.")}, {"utcnow", (PyCFunction)datetime_utcnow, From tim_one@users.sourceforge.net Thu Jan 23 21:22:19 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 13:22:19 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.149,1.150 test_datetime.py,1.102,1.103 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv22861 Modified Files: datetime.py test_datetime.py Log Message: SF bug 660872: datetimetz constructors behave counterintuitively (2.3a1) datetime .now() and .fromtimestamp(): The undocumented optional tzinfo= argument is documented in the LaTeX docs now, and its name was changed to tz= ("tzinfo" had enough meanings without this one). These constructors previously returned local time, and passively attached the tzinfo argument to the result; "passively" == no conversion of date or time members was done. This was less than useful. Now they convert platform-local date and time to local time in tz's time zone, if tz is specified. If tz is not specified, they continue to return a naive datetime object with platform-local date and time (as returned by the platform C localtime() function). Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.149 retrieving revision 1.150 diff -C2 -d -r1.149 -r1.150 *** datetime.py 22 Jan 2003 20:22:23 -0000 1.149 --- datetime.py 23 Jan 2003 21:22:13 -0000 1.150 *************** *** 1197,1209 **** tzinfo = property(lambda self: self._tzinfo, doc="timezone info object") ! def fromtimestamp(cls, t, tzinfo=None): """Construct a datetime from a POSIX timestamp (like time.time()). A timezone info object may be passed in as well. """ ! y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) us = int((t % 1.0) * 1000000) ss = min(ss, 59) # clamp out leap seconds if the platform has them ! return cls(y, m, d, hh, mm, ss, us, tzinfo) fromtimestamp = classmethod(fromtimestamp) --- 1197,1218 ---- tzinfo = property(lambda self: self._tzinfo, doc="timezone info object") ! def fromtimestamp(cls, t, tz=None): """Construct a datetime from a POSIX timestamp (like time.time()). A timezone info object may be passed in as well. """ ! ! _check_tzinfo_arg(tz) ! if tz is None: ! converter = _time.localtime ! else: ! converter = _time.gmtime ! y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) us = int((t % 1.0) * 1000000) ss = min(ss, 59) # clamp out leap seconds if the platform has them ! result = cls(y, m, d, hh, mm, ss, us, tz) ! if tz is not None: ! result = tz.fromutc(result) ! return result fromtimestamp = classmethod(fromtimestamp) *************** *** 1221,1228 **** # XXX available from Python. So now() may return different results # XXX across the implementations. ! def now(cls, tzinfo=None): "Construct a datetime from time.time() and optional time zone info." t = _time.time() ! return cls.fromtimestamp(t, tzinfo) now = classmethod(now) --- 1230,1237 ---- # XXX available from Python. So now() may return different results # XXX across the implementations. ! def now(cls, tz=None): "Construct a datetime from time.time() and optional time zone info." t = _time.time() ! return cls.fromtimestamp(t, tz) now = classmethod(now) Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.102 retrieving revision 1.103 diff -C2 -d -r1.102 -r1.103 *** test_datetime.py 22 Jan 2003 20:49:21 -0000 1.102 --- test_datetime.py 23 Jan 2003 21:22:14 -0000 1.103 *************** *** 2227,2231 **** off42 = FixedOffset(42, "42") another = meth(off42) ! again = meth(tzinfo=off42) self.failUnless(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) --- 2227,2231 ---- off42 = FixedOffset(42, "42") another = meth(off42) ! again = meth(tz=off42) self.failUnless(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) *************** *** 2238,2241 **** --- 2238,2259 ---- self.assertRaises(TypeError, meth, off42, off42) + # We don't know which time zone we're in, and don't have a tzinfo + # class to represent it, so seeing whether a tz argument actually + # does a conversion is tricky. + weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0) + utc = FixedOffset(0, "utc", 0) + for dummy in range(3): + now = datetime.now(weirdtz) + self.failUnless(now.tzinfo is weirdtz) + utcnow = datetime.utcnow().replace(tzinfo=utc) + now2 = utcnow.astimezone(weirdtz) + if abs(now - now2) < timedelta(seconds=30): + break + # Else the code is broken, or more than 30 seconds passed between + # calls; assuming the latter, just try again. + else: + # Three strikes and we're out. + self.fail("utcnow(), now(tz), or astimezone() may be broken") + def test_tzinfo_fromtimestamp(self): import time *************** *** 2247,2251 **** off42 = FixedOffset(42, "42") another = meth(ts, off42) ! again = meth(ts, tzinfo=off42) self.failUnless(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) --- 2265,2269 ---- off42 = FixedOffset(42, "42") another = meth(ts, off42) ! again = meth(ts, tz=off42) self.failUnless(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) *************** *** 2260,2263 **** --- 2278,2295 ---- self.assertRaises(TypeError, meth) + # Try to make sure tz= actually does some conversion. + timestamp = 1000000000 # 2001-09-09 01:46:40 UTC, give or take + utc = FixedOffset(0, "utc", 0) + expected = datetime(2001, 9, 9, 1, 46, 40) + got = datetime.utcfromtimestamp(timestamp) + # We don't support leap seconds, but maybe the platfrom insists + # on using them, so don't demand exact equality). + self.failUnless(abs(got - expected) < timedelta(minutes=1)) + + est = FixedOffset(-5*60, "est", 0) + expected -= timedelta(hours=5) + got = datetime.fromtimestamp(timestamp, est).replace(tzinfo=None) + self.failUnless(abs(got - expected) < timedelta(minutes=1)) + def test_tzinfo_utcnow(self): meth = self.theclass.utcnow *************** *** 2447,2451 **** fm5h = FixedOffset(-timedelta(hours=5), "m300") ! dt = self.theclass.now(tzinfo=f44m) self.failUnless(dt.tzinfo is f44m) # Replacing with degenerate tzinfo raises an exception. --- 2479,2483 ---- fm5h = FixedOffset(-timedelta(hours=5), "m300") ! dt = self.theclass.now(tz=f44m) self.failUnless(dt.tzinfo is f44m) # Replacing with degenerate tzinfo raises an exception. From tim_one@users.sourceforge.net Fri Jan 24 02:36:49 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 18:36:49 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.150,1.151 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv25381 Modified Files: datetime.py Log Message: Updated the astimezone() proof to recover from all the last week's changes (and there were a lot of relevant changes!). Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.150 retrieving revision 1.151 diff -C2 -d -r1.150 -r1.151 *** datetime.py 23 Jan 2003 21:22:13 -0000 1.150 --- datetime.py 24 Jan 2003 02:36:46 -0000 1.151 *************** *** 1638,1650 **** Again follows from how arithmetic is defined. ! Now we can explain x.astimezone(tz). Let's assume it's an interesting case (meaning that the various tzinfo methods exist, and don't blow up or return None when called). The function wants to return a datetime y with timezone tz, equivalent to x. By #3, we want ! y.n - y.o = x.n - x.o [1] The algorithm starts by attaching tz to x.n, and calling that y. So --- 1638,1651 ---- Again follows from how arithmetic is defined. ! Now we can explain tz.fromutc(x). Let's assume it's an interesting case (meaning that the various tzinfo methods exist, and don't blow up or return None when called). The function wants to return a datetime y with timezone tz, equivalent to x. + x is already in UTC. By #3, we want ! y.n - y.o = x.n [1] The algorithm starts by attaching tz to x.n, and calling that y. So *************** *** 1652,1699 **** becomes true; in effect, we want to solve [2] for k: ! (y+k).n - (y+k).o = x.n - x.o [2] By #1, this is the same as ! (y+k).n - ((y+k).s + (y+k).d) = x.n - x.o [3] By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. Substituting that into [3], ! x.n + k - (y+k).s - (y+k).d = x.n - x.o; the x.n terms cancel, leaving ! k - (y+k).s - (y+k).d = - x.o; rearranging, ! k = (y+k).s - x.o - (y+k).d; by #4, (y+k).s == y.s, so ! k = y.s - x.o - (y+k).d; then by #1, y.s = y.o - y.d, so ! k = y.o - y.d - x.o - (y+k).d ! On the RHS, (y+k).d can't be computed directly, but all the rest can be, and ! we approximate k by ignoring the (y+k).d term at first. Note that k can't ! be very large, since all offset-returning methods return a duration of ! magnitude less than 24 hours. For that reason, if y is firmly in std time, ! (y+k).d must be 0, so ignoring it has no consequence then. In any case, the new value is ! z = y + y.o - y.d - x.o [4] ! ! It's helpful to step back at look at [4] from a higher level: rewrite it as ! ! z = (y - x.o) + (y.o - y.d) ! (y - x.o).n = [by #5] y.n - x.o = [since y.n=x.n] x.n - x.o = [by #3] x's ! UTC equivalent time. So the y-x.o part essentially converts x to UTC. Then ! the y.o-y.d part essentially converts x's UTC equivalent into tz's standard ! time (y.o-y.d=y.s by #1). At this point, if ! z.n - z.o = x.n - x.o [5] we have an equivalent time, and are almost done. The insecurity here is at the start of daylight time. Picture US Eastern for concreteness. The wall time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good ! sense then. A sensible Eastern tzinfo class will consider such a time to be ! EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST on the ! day DST starts. We want to return the 1:MM EST spelling because that's the only spelling that makes sense on the local wall clock. --- 1653,1693 ---- becomes true; in effect, we want to solve [2] for k: ! (y+k).n - (y+k).o = x.n [2] By #1, this is the same as ! (y+k).n - ((y+k).s + (y+k).d) = x.n [3] By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. Substituting that into [3], ! x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving ! k - (y+k).s - (y+k).d = 0; rearranging, ! k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so ! k = y.s - (y+k).d ! On the RHS, (y+k).d can't be computed directly, but y.s can be, and we ! approximate k by ignoring the (y+k).d term at first. Note that k can't be ! very large, since all offset-returning methods return a duration of magnitude ! less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must ! be 0, so ignoring it has no consequence then. In any case, the new value is ! z = y + y.s [4] ! It's helpful to step back at look at [4] from a higher level: it's simply ! mapping from UTC to tz's standard time. At this point, if ! z.n - z.o = x.n [5] we have an equivalent time, and are almost done. The insecurity here is at the start of daylight time. Picture US Eastern for concreteness. The wall time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good ! sense then. The docs ask that an Eastern tzinfo class consider such a time to ! be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST ! on the day DST starts. We want to return the 1:MM EST spelling because that's the only spelling that makes sense on the local wall clock. *************** *** 1702,1723 **** difference between the LHS and RHS of [5]? Let ! diff = (x.n - x.o) - (z.n - z.o) [6] Now z.n = by [4] ! (y + y.o - y.d - x.o).n = by #5 ! y.n + y.o - y.d - x.o = since y.n = x.n ! x.n + y.o - y.d - x.o = since y.o = y.s + y.d by #1 ! x.n + (y.s + y.d) - y.d - x.o = cancelling the y.d terms ! x.n + y.s - x.o = since z and y are have the same tzinfo member, ! y.s = z.s by #2 ! x.n + z.s - x.o Plugging that back into [6] gives diff = ! (x.n - x.o) - ((x.n + z.s - x.o) - z.o) = expanding ! x.n - x.o - x.n - z.s + x.o + z.o = cancelling ! - z.s + z.o = by #2 z.d --- 1696,1715 ---- difference between the LHS and RHS of [5]? Let ! diff = x.n - (z.n - z.o) [6] Now z.n = by [4] ! (y + y.s).n = by #5 ! y.n + y.s = since y.n = x.n ! x.n + y.s = since z and y are have the same tzinfo member, ! y.s = z.s by #2 ! x.n + z.s Plugging that back into [6] gives diff = ! x.n - ((x.n + z.s) - z.o) = expanding ! x.n - x.n - z.s + z.o = cancelling ! - z.s + z.o = by #2 z.d *************** *** 1725,1733 **** If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time ! spelling we wanted in the endcase described above. We're done. If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to add to z (in effect, z is in tz's standard time, and we need to shift the ! offset into tz's daylight time). Let --- 1717,1726 ---- If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time ! spelling we wanted in the endcase described above. We're done. Contrarily, ! if z.d = 0, then we have a UTC equivalent, and are also done. If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to add to z (in effect, z is in tz's standard time, and we need to shift the ! local clock into tz's daylight time). Let *************** *** 1737,1754 **** and we can again ask whether ! z'.n - z'.o = x.n - x.o [8] ! If so, we're done. If not, the tzinfo class is insane, or we're trying to ! convert to the hour that can't be spelled in tz. This also requires a ! bit of proof. As before, let's compute the difference between the LHS and ! RHS of [8] (and skipping some of the justifications for the kinds of ! substitutions we've done several times already): ! diff' = (x.n - x.o) - (z'.n - z'.o) = replacing z'.n via [7] ! (x.n - x.o) - (z.n + diff - z'.o) = replacing diff via [6] ! (x.n - x.o) - (z.n + (x.n - x.o) - (z.n - z.o) - z'.o) = ! x.n - x.o - z.n - x.n + x.o + z.n - z.o + z'.o = cancel x.n ! - x.o - z.n + x.o + z.n - z.o + z'.o = cancel x.o ! - z.n + z.n - z.o + z'.o = cancel z.n - z.o + z'.o = #1 twice -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo --- 1730,1746 ---- and we can again ask whether ! z'.n - z'.o = x.n [8] ! If so, we're done. If not, the tzinfo class is insane, according to the ! assumptions we've made. This also requires a bit of proof. As before, let's ! compute the difference between the LHS and RHS of [8] (and skipping some of ! the justifications for the kinds of substitutions we've done several times ! already): ! diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7] ! x.n - (z.n + diff - z'.o) = replacing diff via [6] ! x.n - (z.n + x.n - (z.n - z.o) - z'.o) = ! x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n ! - z.n + z.n - z.o + z'.o = cancel z.n - z.o + z'.o = #1 twice -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo *************** *** 1756,1779 **** So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, ! we've found the UTC-equivalent so are done. ! How could they differ? z' = z + z.d [7], so merely moving z' by a dst() ! offset, and starting *from* a time already in DST (we know z.d != 0), would ! have to change the result dst() returns: we start in DST, and moving a ! little further into it takes us out of DST. ! There's (only) one sane case where this can happen: at the end of DST, ! there's an hour in UTC with no spelling in a hybrid tzinfo class. In US ! Eastern, that's 6:MM UTC = 1:MM EST = 2:MM EDT. During that hour, on an ! Eastern clock 1:MM is taken as being in daylight time (5:MM UTC), but 2:MM is ! taken as being in standard time (7:MM UTC). There is no local time mapping to ! 6:MM UTC. The local clock jumps from 1:59 back to 1:00 again, and repeats the ! 1:MM hour in standard time. Since that's what the local clock *does*, we want ! to map both UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous in local time, but so it goes -- it's the way the local clock works. ! When x = 6:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, ! so z=1:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. ! z' = z + z.d = 2:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] (correctly) concludes that z' is not UTC-equivalent to x. --- 1748,1773 ---- So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, ! we've found the UTC-equivalent so are done. In fact, we stop with [7] and ! return z', not bothering to compute z'.d. ! How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by ! a dst() offset, and starting *from* a time already in DST (we know z.d != 0), ! would have to change the result dst() returns: we start in DST, and moving ! a little further into it takes us out of DST. ! There isn't a sane case where this can happen. The closest it gets is at ! the end of DST, where there's an hour in UTC with no spelling in a hybrid ! tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During ! that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM ! UTC) because the docs insist on that, but 0:MM is taken as being in daylight ! time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local ! clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in ! standard time. Since that's what the local clock *does*, we want to map both ! UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous in local time, but so it goes -- it's the way the local clock works. ! When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, ! so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. ! z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] (correctly) concludes that z' is not UTC-equivalent to x. *************** *** 1784,1793 **** but the reasoning doesn't depend on the example -- it depends on there being two possible dst() outcomes, one zero and the other non-zero). Therefore ! z' must be in standard time, and is not the spelling we want in this case. ! z is in daylight time, and is the spelling we want. Note again that z is ! not UTC-equivalent as far as the hybrid tzinfo class is concerned (because ! it takes z as being in standard time rather than the daylight time we intend ! here), but returning it gives the real-life "local clock repeats an hour" ! behavior when mapping the "unspellable" UTC hour into tz. """ --- 1778,1810 ---- but the reasoning doesn't depend on the example -- it depends on there being two possible dst() outcomes, one zero and the other non-zero). Therefore ! z' must be in standard time, and is the spelling we want in this case. ! ! Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is ! concerned (because it takes z' as being in standard time rather than the ! daylight time we intend here), but returning it gives the real-life "local ! clock repeats an hour" behavior when mapping the "unspellable" UTC hour into ! tz. ! ! When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with ! the 1:MM standard time spelling we want. ! ! So how can this break? One of the assumptions must be violated. Two ! possibilities: ! ! 1) [2] effectively says that y.s is invariant across all y belong to a given ! time zone. This isn't true if, for political reasons or continental drift, ! a region decides to change its base offset from UTC. ! ! 2) There may be versions of "double daylight" time where the tail end of ! the analysis gives up a step too early. I haven't thought about that ! enough to say. ! ! In any case, it's clear that the default fromutc() is strong enough to handle ! "almost all" time zones: so long as the standard offset is invariant, it ! doesn't matter if daylight time transition points change from year to year, or ! if daylight time is skipped in some years; it doesn't matter how large or ! small dst() may get within its bounds; and it doesn't even matter if some ! perverse time zone returns a negative dst()). So a breaking case must be ! pretty bizarre, and a tzinfo subclass can override fromutc() if it is. """ From tim_one@users.sourceforge.net Fri Jan 24 02:44:48 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 23 Jan 2003 18:44:48 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv31440/python/modules Modified Files: datetimemodule.c Log Message: Updated the astimezone() proof to recover from all the last week's changes (and there were a lot of relevant changes!). Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** datetimemodule.c 23 Jan 2003 21:09:05 -0000 1.46 --- datetimemodule.c 24 Jan 2003 02:44:45 -0000 1.47 *************** *** 4807,4824 **** 4. (x+k).s = x.s ! This follows from #2, and that datimetime+timedelta preserves tzinfo. 5. (x+k).n = x.n + k Again follows from how arithmetic is defined. ! Now we can explain x.astimezone(tz). Let's assume it's an interesting case (meaning that the various tzinfo methods exist, and don't blow up or return None when called). The function wants to return a datetime y with timezone tz, equivalent to x. By #3, we want ! y.n - y.o = x.n - x.o [1] The algorithm starts by attaching tz to x.n, and calling that y. So --- 4807,4825 ---- 4. (x+k).s = x.s ! This follows from #2, and that datimetimetz+timedelta preserves tzinfo. 5. (x+k).n = x.n + k Again follows from how arithmetic is defined. ! Now we can explain tz.fromutc(x). Let's assume it's an interesting case (meaning that the various tzinfo methods exist, and don't blow up or return None when called). The function wants to return a datetime y with timezone tz, equivalent to x. + x is already in UTC. By #3, we want ! y.n - y.o = x.n [1] The algorithm starts by attaching tz to x.n, and calling that y. So *************** *** 4826,4873 **** becomes true; in effect, we want to solve [2] for k: ! (y+k).n - (y+k).o = x.n - x.o [2] By #1, this is the same as ! (y+k).n - ((y+k).s + (y+k).d) = x.n - x.o [3] By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. Substituting that into [3], ! x.n + k - (y+k).s - (y+k).d = x.n - x.o; the x.n terms cancel, leaving ! k - (y+k).s - (y+k).d = - x.o; rearranging, ! k = (y+k).s - x.o - (y+k).d; by #4, (y+k).s == y.s, so ! k = y.s - x.o - (y+k).d; then by #1, y.s = y.o - y.d, so ! k = y.o - y.d - x.o - (y+k).d ! On the RHS, (y+k).d can't be computed directly, but all the rest can be, and ! we approximate k by ignoring the (y+k).d term at first. Note that k can't ! be very large, since all offset-returning methods return a duration of ! magnitude less than 24 hours. For that reason, if y is firmly in std time, ! (y+k).d must be 0, so ignoring it has no consequence then. In any case, the new value is ! z = y + y.o - y.d - x.o [4] ! ! It's helpful to step back at look at [4] from a higher level: rewrite it as ! ! z = (y - x.o) + (y.o - y.d) ! (y - x.o).n = [by #5] y.n - x.o = [since y.n=x.n] x.n - x.o = [by #3] x's ! UTC equivalent time. So the y-x.o part essentially converts x to UTC. Then ! the y.o-y.d part essentially converts x's UTC equivalent into tz's standard ! time (y.o-y.d=y.s by #1). At this point, if ! z.n - z.o = x.n - x.o [5] we have an equivalent time, and are almost done. The insecurity here is at the start of daylight time. Picture US Eastern for concreteness. The wall time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good ! sense then. A sensible Eastern tzinfo class will consider such a time to be ! EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST on the ! day DST starts. We want to return the 1:MM EST spelling because that's the only spelling that makes sense on the local wall clock. --- 4827,4867 ---- becomes true; in effect, we want to solve [2] for k: ! (y+k).n - (y+k).o = x.n [2] By #1, this is the same as ! (y+k).n - ((y+k).s + (y+k).d) = x.n [3] By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. Substituting that into [3], ! x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving ! k - (y+k).s - (y+k).d = 0; rearranging, ! k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so ! k = y.s - (y+k).d ! On the RHS, (y+k).d can't be computed directly, but y.s can be, and we ! approximate k by ignoring the (y+k).d term at first. Note that k can't be ! very large, since all offset-returning methods return a duration of magnitude ! less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must ! be 0, so ignoring it has no consequence then. In any case, the new value is ! z = y + y.s [4] ! It's helpful to step back at look at [4] from a higher level: it's simply ! mapping from UTC to tz's standard time. At this point, if ! z.n - z.o = x.n [5] we have an equivalent time, and are almost done. The insecurity here is at the start of daylight time. Picture US Eastern for concreteness. The wall time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good ! sense then. The docs ask that an Eastern tzinfo class consider such a time to ! be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST ! on the day DST starts. We want to return the 1:MM EST spelling because that's the only spelling that makes sense on the local wall clock. *************** *** 4876,4897 **** difference between the LHS and RHS of [5]? Let ! diff = (x.n - x.o) - (z.n - z.o) [6] Now z.n = by [4] ! (y + y.o - y.d - x.o).n = by #5 ! y.n + y.o - y.d - x.o = since y.n = x.n ! x.n + y.o - y.d - x.o = since y.o = y.s + y.d by #1 ! x.n + (y.s + y.d) - y.d - x.o = cancelling the y.d terms ! x.n + y.s - x.o = since z and y are have the same tzinfo member, ! y.s = z.s by #2 ! x.n + z.s - x.o Plugging that back into [6] gives diff = ! (x.n - x.o) - ((x.n + z.s - x.o) - z.o) = expanding ! x.n - x.o - x.n - z.s + x.o + z.o = cancelling ! - z.s + z.o = by #2 z.d --- 4870,4889 ---- difference between the LHS and RHS of [5]? Let ! diff = x.n - (z.n - z.o) [6] Now z.n = by [4] ! (y + y.s).n = by #5 ! y.n + y.s = since y.n = x.n ! x.n + y.s = since z and y are have the same tzinfo member, ! y.s = z.s by #2 ! x.n + z.s Plugging that back into [6] gives diff = ! x.n - ((x.n + z.s) - z.o) = expanding ! x.n - x.n - z.s + z.o = cancelling ! - z.s + z.o = by #2 z.d *************** *** 4899,4907 **** If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time ! spelling we wanted in the endcase described above. We're done. If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to add to z (in effect, z is in tz's standard time, and we need to shift the ! offset into tz's daylight time). Let --- 4891,4900 ---- If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time ! spelling we wanted in the endcase described above. We're done. Contrarily, ! if z.d = 0, then we have a UTC equivalent, and are also done. If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to add to z (in effect, z is in tz's standard time, and we need to shift the ! local clock into tz's daylight time). Let *************** *** 4911,4928 **** and we can again ask whether ! z'.n - z'.o = x.n - x.o [8] ! If so, we're done. If not, the tzinfo class is insane, or we're trying to ! convert to the hour that can't be spelled in tz. This also requires a ! bit of proof. As before, let's compute the difference between the LHS and ! RHS of [8] (and skipping some of the justifications for the kinds of ! substitutions we've done several times already): ! diff' = (x.n - x.o) - (z'.n - z'.o) = replacing z'.n via [7] ! (x.n - x.o) - (z.n + diff - z'.o) = replacing diff via [6] ! (x.n - x.o) - (z.n + (x.n - x.o) - (z.n - z.o) - z'.o) = ! x.n - x.o - z.n - x.n + x.o + z.n - z.o + z'.o = cancel x.n ! - x.o - z.n + x.o + z.n - z.o + z'.o = cancel x.o ! - z.n + z.n - z.o + z'.o = cancel z.n - z.o + z'.o = #1 twice -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo --- 4904,4920 ---- and we can again ask whether ! z'.n - z'.o = x.n [8] ! If so, we're done. If not, the tzinfo class is insane, according to the ! assumptions we've made. This also requires a bit of proof. As before, let's ! compute the difference between the LHS and RHS of [8] (and skipping some of ! the justifications for the kinds of substitutions we've done several times ! already): ! diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7] ! x.n - (z.n + diff - z'.o) = replacing diff via [6] ! x.n - (z.n + x.n - (z.n - z.o) - z'.o) = ! x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n ! - z.n + z.n - z.o + z'.o = cancel z.n - z.o + z'.o = #1 twice -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo *************** *** 4930,4953 **** So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, ! we've found the UTC-equivalent so are done. ! How could they differ? z' = z + z.d [7], so merely moving z' by a dst() ! offset, and starting *from* a time already in DST (we know z.d != 0), would ! have to change the result dst() returns: we start in DST, and moving a ! little further into it takes us out of DST. ! There's (only) one sane case where this can happen: at the end of DST, ! there's an hour in UTC with no spelling in a hybrid tzinfo class. In US ! Eastern, that's 6:MM UTC = 1:MM EST = 2:MM EDT. During that hour, on an ! Eastern clock 1:MM is taken as being in daylight time (5:MM UTC), but 2:MM is ! taken as being in standard time (7:MM UTC). There is no local time mapping to ! 6:MM UTC. The local clock jumps from 1:59 back to 1:00 again, and repeats the ! 1:MM hour in standard time. Since that's what the local clock *does*, we want ! to map both UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous in local time, but so it goes -- it's the way the local clock works. ! When x = 6:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, ! so z=1:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. ! z' = z + z.d = 2:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] (correctly) concludes that z' is not UTC-equivalent to x. --- 4922,4947 ---- So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, ! we've found the UTC-equivalent so are done. In fact, we stop with [7] and ! return z', not bothering to compute z'.d. ! How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by ! a dst() offset, and starting *from* a time already in DST (we know z.d != 0), ! would have to change the result dst() returns: we start in DST, and moving ! a little further into it takes us out of DST. ! There isn't a sane case where this can happen. The closest it gets is at ! the end of DST, where there's an hour in UTC with no spelling in a hybrid ! tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During ! that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM ! UTC) because the docs insist on that, but 0:MM is taken as being in daylight ! time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local ! clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in ! standard time. Since that's what the local clock *does*, we want to map both ! UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous in local time, but so it goes -- it's the way the local clock works. ! When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, ! so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. ! z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] (correctly) concludes that z' is not UTC-equivalent to x. *************** *** 4958,4966 **** but the reasoning doesn't depend on the example -- it depends on there being two possible dst() outcomes, one zero and the other non-zero). Therefore ! z' must be in standard time, and is not the spelling we want in this case. ! z is in daylight time, and is the spelling we want. Note again that z is ! not UTC-equivalent as far as the hybrid tzinfo class is concerned (because ! it takes z as being in standard time rather than the daylight time we intend ! here), but returning it gives the real-life "local clock repeats an hour" ! behavior when mapping the "unspellable" UTC hour into tz. --------------------------------------------------------------------------- */ --- 4952,4983 ---- but the reasoning doesn't depend on the example -- it depends on there being two possible dst() outcomes, one zero and the other non-zero). Therefore ! z' must be in standard time, and is the spelling we want in this case. ! ! Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is ! concerned (because it takes z' as being in standard time rather than the ! daylight time we intend here), but returning it gives the real-life "local ! clock repeats an hour" behavior when mapping the "unspellable" UTC hour into ! tz. ! ! When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with ! the 1:MM standard time spelling we want. ! ! So how can this break? One of the assumptions must be violated. Two ! possibilities: ! ! 1) [2] effectively says that y.s is invariant across all y belong to a given ! time zone. This isn't true if, for political reasons or continental drift, ! a region decides to change its base offset from UTC. ! ! 2) There may be versions of "double daylight" time where the tail end of ! the analysis gives up a step too early. I haven't thought about that ! enough to say. ! ! In any case, it's clear that the default fromutc() is strong enough to handle ! "almost all" time zones: so long as the standard offset is invariant, it ! doesn't matter if daylight time transition points change from year to year, or ! if daylight time is skipped in some years; it doesn't matter how large or ! small dst() may get within its bounds; and it doesn't even matter if some ! perverse time zone returns a negative dst()). So a breaking case must be ! pretty bizarre, and a tzinfo subclass can override fromutc() if it is. --------------------------------------------------------------------------- */ From jackjansen@users.sourceforge.net Fri Jan 24 09:23:16 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 24 Jan 2003 01:23:16 -0800 Subject: [Python-checkins] python/dist/src/Tools/bgen/bgen bgenType.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory sc8-pr-cvs1:/tmp/cvs-serv12357 Modified Files: bgenType.py Log Message: Updated the doc strings to refer to PyArg_Parse and Py_BuildValue in stead of getargs() and mkvalue(). Index: bgenType.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenType.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** bgenType.py 19 Jan 2003 21:53:57 -0000 1.10 --- bgenType.py 24 Jan 2003 09:23:13 -0000 1.11 *************** *** 31,42 **** def getargsFormat(self): ! """Return the format for this type for use with [new]getargs(). Example: int.getargsFormat() returns the string "i". """ return self.fmt def getargsArgs(self, name): ! """Return an argument for use with [new]getargs(). Example: int.getargsArgs("spam") returns the string "&spam". --- 31,43 ---- def getargsFormat(self): ! """Return the format for this type for use with PyArg_Parse(). Example: int.getargsFormat() returns the string "i". + (getargs is a very old name for PyArg_Parse, hence the name of this method). """ return self.fmt def getargsArgs(self, name): ! """Return an argument for use with PyArg_Parse(). Example: int.getargsArgs("spam") returns the string "&spam". *************** *** 80,92 **** def mkvalueFormat(self): ! """Return the format for this type for use with mkvalue(). This is normally the same as getargsFormat() but it is a separate function to allow future divergence. """ return self.getargsFormat() def mkvalueArgs(self, name): ! """Return an argument for use with mkvalue(). Example: int.mkvalueArgs("spam") returns the string "spam". --- 81,95 ---- def mkvalueFormat(self): ! """Return the format for this type for use with Py_BuildValue(). This is normally the same as getargsFormat() but it is a separate function to allow future divergence. + (mkvalue is a very old name for Py_BuildValue, hence the name of this + method). """ return self.getargsFormat() def mkvalueArgs(self, name): ! """Return an argument for use with Py_BuildValue(). Example: int.mkvalueArgs("spam") returns the string "spam". From gvanrossum@users.sourceforge.net Fri Jan 24 14:56:57 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 24 Jan 2003 06:56:57 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils/command build_scripts.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory sc8-pr-cvs1:/tmp/cvs-serv28741 Modified Files: build_scripts.py Log Message: Change the mode of scripts in the build/scripts* directory to executable. Index: build_scripts.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/build_scripts.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** build_scripts.py 19 Nov 2002 13:12:28 -0000 1.18 --- build_scripts.py 24 Jan 2003 14:56:52 -0000 1.19 *************** *** 8,11 **** --- 8,12 ---- import sys, os, re + from stat import ST_MODE from distutils import sysconfig from distutils.core import Command *************** *** 55,62 **** --- 56,65 ---- """ self.mkpath(self.build_dir) + outfiles = [] for script in self.scripts: adjust = 0 script = convert_path(script) outfile = os.path.join(self.build_dir, os.path.basename(script)) + outfiles.append(outfile) if not self.force and not newer(script, outfile): *************** *** 106,109 **** --- 109,121 ---- f.close() self.copy_file(script, outfile) + + if os.name == 'posix': + for file in outfiles: + if self.dry_run: + log.info("changing mode of %s", file) + else: + mode = ((os.stat(file)[ST_MODE]) | 0555) & 07777 + log.info("changing mode of %s to %o", file, mode) + os.chmod(file, mode) # copy_scripts () From tim_one@users.sourceforge.net Fri Jan 24 15:31:35 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 07:31:35 -0800 Subject: [Python-checkins] python/dist/src/PCbuild _bsddb.dsp,1.2,1.3 readme.txt,1.38,1.39 bsddb_patch.txt,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv21630/python/PCbuild Modified Files: _bsddb.dsp readme.txt Removed Files: bsddb_patch.txt Log Message: Bump the Windows build to use Sleepycat's 4.1.25.NC release (the latest bsddb release without strong cryptography). Index: _bsddb.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/_bsddb.dsp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _bsddb.dsp 23 Nov 2002 18:48:06 -0000 1.2 --- _bsddb.dsp 24 Jan 2003 15:31:31 -0000 1.3 *************** *** 45,49 **** F90=df.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\Include" /I "..\PC" /I "..\..\db-4.0.14\build_win32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 --- 45,49 ---- F90=df.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\Include" /I "..\PC" /I "..\..\db-4.1.25\build_win32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 *************** *** 55,59 **** LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 ! # ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\db-4.0.14\build_win32\Release_static\libdb40s.lib /nologo /base:"0x1e180000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"./_bsddb.pyd" # SUBTRACT LINK32 /pdb:none --- 55,59 ---- LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 ! # ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\db-4.1.25\build_win32\Release_static\libdb41s.lib /nologo /base:"0x1e180000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"./_bsddb.pyd" # SUBTRACT LINK32 /pdb:none *************** *** 73,77 **** F90=df.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\Include" /I "..\PC" /I "..\..\db-4.0.14\build_win32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 --- 73,77 ---- F90=df.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\Include" /I "..\PC" /I "..\..\db-4.1.25\build_win32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 *************** *** 83,87 **** LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept ! # ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\db-4.0.14\build_win32\Release_static\libdb40s.lib /nologo /base:"0x1e180000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrtd" /out:"./_bsddb_d.pyd" /pdbtype:sept # SUBTRACT LINK32 /pdb:none --- 83,87 ---- LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept ! # ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\db-4.1.25\build_win32\Release_static\libdb41s.lib /nologo /base:"0x1e180000" /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrtd" /out:"./_bsddb_d.pyd" /pdbtype:sept # SUBTRACT LINK32 /pdb:none Index: readme.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/readme.txt,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** readme.txt 30 Dec 2002 00:40:40 -0000 1.38 --- readme.txt 24 Jan 2003 15:31:31 -0000 1.39 *************** *** 164,191 **** _bsddb ! XXX The Sleepycat release we use will probably change before ! XXX 2.3a1. ! Go to Sleepycat's patches page: ! http://www.sleepycat.com/update/index.html ! and download ! 4.0.14.zip ! from the download page. The file name is db-4.0.14.zip. Unpack into ! dist\db-4.0.14 ! Apply the patch file bsddb_patch.txt in this (PCbuild) directory ! against the file ! dist\db-4.0.14\db\db_reclaim.c ! Go to ! http://www.sleepycat.com/docs/ref/build_win/intro.html ! and follow the instructions for building the Sleepycat software. ! Build the Release version. ! NOTE: The instructions are for a later release of the software, ! so use your imagination. Berkeley_DB.dsw in this release was ! also pre-MSVC6, so you'll be prompted to upgrade the format (say ! yes, of course). Choose configuration "db_buildall - Win32 Release", ! and build db_buildall.exe. ! XXX We're actually linking against Release_static\libdb40s.lib. XXX This yields the following warnings: """ --- 164,188 ---- _bsddb ! Go to Sleepycat's download page: ! http://www.sleepycat.com/download/ ! and download version 4.1.25. The file name is db-4.1.25.NC.zip. ! XXX with or without strong cryptography? I picked "without". ! Unpack into ! dist\db-4.1.25 ! [If using WinZip to unpack the db-4.1.25.NC distro, that requires ! renaming the directory (to remove ".NC") after unpacking. ! ] ! ! Open ! dist\db-4.1.25\docs\index.html ! ! and follow the Windows instructions for building the Sleepycat ! software. Note that Berkeley_DB.dsw is in the build_win32 subdirectory. ! Build the Release version ("build_all -- Win32 Release"). ! ! XXX We're actually linking against Release_static\libdb41s.lib. XXX This yields the following warnings: """ *************** *** 201,204 **** --- 198,226 ---- """ XXX This isn't encouraging, but I don't know what to do about it. + + To run extensive tests, pass "-u bsddb" to regrtest.py. test_bsddb3.py + is then enabled. Running in verbose mode may be helpful. + + XXX The test_bsddb3 tests don't always pass, on Windows (according to + XXX me) or on Linux (according to Barry). I had much better luck + XXX on Win2K than on Win98SE. The common failure mode across platforms + XXX is + XXX DBAgainError: (11, 'Resource temporarily unavailable -- unable + XXX to join the environment') + XXX + XXX and it appears timing-dependent. On Win2K I also saw this once: + XXX + XXX test02_SimpleLocks (bsddb.test.test_thread.HashSimpleThreaded) ... + XXX Exception in thread reader 1: + XXX Traceback (most recent call last): + XXX File "C:\Code\python\lib\threading.py", line 411, in __bootstrap + XXX self.run() + XXX File "C:\Code\python\lib\threading.py", line 399, in run + XXX apply(self.__target, self.__args, self.__kwargs) + XXX File "C:\Code\python\lib\bsddb\test\test_thread.py", line 268, in + XXX readerThread + XXX rec = c.next() + XXX DBLockDeadlockError: (-30996, 'DB_LOCK_DEADLOCK: Locker killed + XXX to resolve a deadlock') --- bsddb_patch.txt DELETED --- From tim_one@users.sourceforge.net Fri Jan 24 15:31:33 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 07:31:33 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.621,1.622 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv21630/python/Misc Modified Files: NEWS Log Message: Bump the Windows build to use Sleepycat's 4.1.25.NC release (the latest bsddb release without strong cryptography). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.621 retrieving revision 1.622 diff -C2 -d -r1.621 -r1.622 *** NEWS 23 Jan 2003 20:53:08 -0000 1.621 --- NEWS 24 Jan 2003 15:31:27 -0000 1.622 *************** *** 33,36 **** --- 33,39 ---- - fcntl now exposes the strops.h I_* constants. + - Fix a crash on Solaris that occurred when calling close() on + an mmap'ed file which was already closed. (SF patch #665913) + - datetime changes: *************** *** 104,110 **** datetimes constructed from them are equal. - - Fix a crash on Solaris that occurred when calling close() on - an mmap'ed file which was already closed. (SF patch #665913) - Library ------- --- 107,110 ---- *************** *** 181,184 **** --- 181,187 ---- Windows ------- + + - The bsddb module now ships with Sleepycat's 4.1.25.NC, the latest + release without strong cryptography. - sys.path[0], if it contains a directory name, is now always an From jackjansen@users.sourceforge.net Fri Jan 24 16:15:53 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 24 Jan 2003 08:15:53 -0800 Subject: [Python-checkins] python/dist/src/Python import.c,2.215,2.216 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv13898 Modified Files: import.c Log Message: MacPython-OS9 specific fix: If there are non-string items on sys.path don't try to intern them. This has the theoretical problem that resource filenames on sys.path cannot be unicode objects, but in practice that shouldn't matter. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.215 retrieving revision 2.216 diff -C2 -d -r2.215 -r2.216 *** import.c 30 Dec 2002 22:08:04 -0000 2.215 --- import.c 24 Jan 2003 16:15:45 -0000 2.216 *************** *** 1215,1235 **** ** FindResourceModule remembers which items refer to ** folders (so we don't have to bother trying to look ! ** into them for resources). */ ! PyString_InternInPlace(&PyList_GET_ITEM(path, i)); ! v = PyList_GET_ITEM(path, i); ! if (PyMac_FindResourceModule((PyStringObject *)v, name, buf)) { ! static struct filedescr resfiledescr = ! {"", "", PY_RESOURCE}; ! Py_XDECREF(copy); ! return &resfiledescr; ! } ! if (PyMac_FindCodeResourceModule((PyStringObject *)v, name, buf)) { ! static struct filedescr resfiledescr = ! {"", "", PY_CODERESOURCE}; ! Py_XDECREF(copy); ! return &resfiledescr; } #endif --- 1215,1238 ---- ** FindResourceModule remembers which items refer to ** folders (so we don't have to bother trying to look ! ** into them for resources). We only do this for string ! ** items. */ ! if (PyString_Check(PyList_GET_ITEM(path, i))) { ! PyString_InternInPlace(&PyList_GET_ITEM(path, i)); ! v = PyList_GET_ITEM(path, i); ! if (PyMac_FindResourceModule((PyStringObject *)v, name, buf)) { ! static struct filedescr resfiledescr = ! {"", "", PY_RESOURCE}; ! Py_XDECREF(copy); ! return &resfiledescr; ! } ! if (PyMac_FindCodeResourceModule((PyStringObject *)v, name, buf)) { ! static struct filedescr resfiledescr = ! {"", "", PY_CODERESOURCE}; ! Py_XDECREF(copy); ! return &resfiledescr; ! } } #endif From jackjansen@users.sourceforge.net Fri Jan 24 16:17:22 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 24 Jan 2003 08:17:22 -0800 Subject: [Python-checkins] python/dist/src/Python pythonrun.c,2.175,2.176 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv14502 Modified Files: pythonrun.c Log Message: MacPython-OS9 has had an abort() function for quite a while now, so there's no reason to stall in an endless loop, just call abort() on a fatal error. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.175 retrieving revision 2.176 diff -C2 -d -r2.175 -r2.176 *** pythonrun.c 22 Jan 2003 09:00:38 -0000 2.175 --- pythonrun.c 24 Jan 2003 16:17:18 -0000 2.176 *************** *** 1324,1330 **** { fprintf(stderr, "Fatal Python error: %s\n", msg); - #ifdef macintosh - for (;;); - #endif #ifdef MS_WINDOWS OutputDebugString("Fatal Python error: "); --- 1324,1327 ---- From bwarsaw@users.sourceforge.net Fri Jan 24 17:33:33 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 24 Jan 2003 09:33:33 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libshutil.tex,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv17189 Modified Files: libshutil.tex Log Message: Fred drives and fixes a formatting nit. Index: libshutil.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libshutil.tex,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** libshutil.tex 7 Oct 2002 13:23:24 -0000 1.11 --- libshutil.tex 24 Jan 2003 17:33:30 -0000 1.12 *************** *** 77,82 **** \begin{funcdesc}{rmtree}{path\optional{, ignore_errors\optional{, onerror}}} ! \index{directory!deleting} ! Delete an entire directory tree. If \var{ignore_errors} is true, errors resulting from failed removals will be ignored; if false or omitted, such errors are handled by calling a handler specified by --- 77,82 ---- \begin{funcdesc}{rmtree}{path\optional{, ignore_errors\optional{, onerror}}} ! Delete an entire directory tree.\index{directory!deleting} ! If \var{ignore_errors} is true, errors resulting from failed removals will be ignored; if false or omitted, such errors are handled by calling a handler specified by From bwarsaw@users.sourceforge.net Fri Jan 24 17:34:15 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 24 Jan 2003 09:34:15 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_shutil.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv17501 Added Files: test_shutil.py Log Message: A very minimal start to a test of the shutil module. --- NEW FILE: test_shutil.py --- # Copyright (C) 2003 Python Software Foundation import unittest import shutil import tempfile from test import test_support class TestShutil(unittest.TestCase): def test_rmtree_errors(self): # filename is guaranteed not to exist filename = tempfile.mktemp() self.assertRaises(OSError, shutil.rmtree, filename) self.assertEqual(shutil.rmtree(filename, True), None) def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestShutil)) return suite def test_main(): test_support.run_suite(suite()) if __name__ == '__main__': unittest.main(defaultTest='suite') From bwarsaw@users.sourceforge.net Fri Jan 24 17:36:17 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 24 Jan 2003 09:36:17 -0800 Subject: [Python-checkins] python/dist/src/Lib shutil.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv18409 Modified Files: shutil.py Log Message: rmtree(): Make implementation agree with documentation (both latex and docstring). Even if ignore_errors was true, an exception would occur if path didn't exist. Index: shutil.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/shutil.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** shutil.py 5 Jan 2003 19:44:11 -0000 1.26 --- shutil.py 24 Jan 2003 17:36:15 -0000 1.27 *************** *** 118,122 **** raise Error, errors ! def rmtree(path, ignore_errors=0, onerror=None): """Recursively delete a directory tree. --- 118,122 ---- raise Error, errors ! def rmtree(path, ignore_errors=False, onerror=None): """Recursively delete a directory tree. *************** *** 124,142 **** onerror is set, it is called to handle the error; otherwise, an exception is raised. - """ cmdtuples = [] ! _build_cmdtuple(path, cmdtuples) ! for func, arg in cmdtuples: ! try: func(arg) ! except OSError: ! exc = sys.exc_info() ! if ignore_errors: ! pass ! elif onerror is not None: ! onerror(func, arg, exc) ! else: ! raise exc[0], (exc[1][0], exc[1][1] + ' removing '+arg) # Helper for rmtree() --- 124,142 ---- onerror is set, it is called to handle the error; otherwise, an exception is raised. """ cmdtuples = [] ! arg = path ! try: ! _build_cmdtuple(path, cmdtuples) ! for func, arg in cmdtuples: func(arg) ! except OSError: ! exc = sys.exc_info() ! if ignore_errors: ! pass ! elif onerror is not None: ! onerror(func, arg, exc) ! else: ! raise exc[0], (exc[1][0], exc[1][1] + ' removing '+arg) # Helper for rmtree() From tim_one@users.sourceforge.net Fri Jan 24 18:56:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 10:56:41 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.151,1.152 test_datetime.py,1.103,1.104 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv16915 Modified Files: datetime.py test_datetime.py Log Message: date and datetime comparison: when we don't know how to compare against "the other" argument, we raise TypeError, in order to prevent comparison from falling back to the default (and worse than useless, in this case) comparison by object address. That's fine so far as it goes, but leaves no way for another date/datetime object to make itself comparable to our objects. For example, it leaves Marc-Andre no way to teach mxDateTime dates how to compare against Python dates. Discussion on Python-Dev raised a number of impractical ideas, and the simple one implemented here: when we don't know how to compare against "the other" argument, we raise TypeError *unless* the other object has a timetuple attr. In that case, we return NotImplemented instead, and Python will give the other object a shot at handling the comparison then. Note that comparisons of time and timedelta objects still suffer the original problem, though. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.151 retrieving revision 1.152 diff -C2 -d -r1.151 -r1.152 *** datetime.py 24 Jan 2003 02:36:46 -0000 1.151 --- datetime.py 24 Jan 2003 18:56:35 -0000 1.152 *************** *** 762,765 **** --- 762,767 ---- y2, m2, d2 = other.__year, other.__month, other.__day return cmp((y, m, d), (y2, m2, d2)) + elif hasattr(other, "timetuple"): + return NotImplemented else: raise TypeError, ("can't compare date to %s instance" % *************** *** 1434,1440 **** def __cmp__(self, other): if not isinstance(other, datetime): ! # XXX Buggy in 2.2.2. ! raise TypeError("can't compare '%s' to '%s'" % ( ! type(self).__name__, type(other).__name__)) mytz = self._tzinfo ottz = other._tzinfo --- 1436,1445 ---- def __cmp__(self, other): if not isinstance(other, datetime): ! if hasattr(other, "timetuple"): ! return NotImplemented ! else: ! # XXX Buggy in 2.2.2. ! raise TypeError("can't compare '%s' to '%s'" % ( ! type(self).__name__, type(other).__name__)) mytz = self._tzinfo ottz = other._tzinfo Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.103 retrieving revision 1.104 diff -C2 -d -r1.103 -r1.104 *** test_datetime.py 23 Jan 2003 21:22:14 -0000 1.103 --- test_datetime.py 24 Jan 2003 18:56:36 -0000 1.104 *************** *** 879,882 **** --- 879,914 ---- self.assertRaises(TypeError, lambda: badarg >= t1) + def test_mixed_compare(self): + our = self.theclass(2000, 4, 5) + self.assertRaises(TypeError, cmp, our, 1) + self.assertRaises(TypeError, cmp, 1, our) + + class AnotherDateTimeClass(object): + def __cmp__(self, other): + # Return "equal" so calling this can't be confused with + # compare-by-address (which never says "equal" for distinct + # objects). + return 0 + + # This still errors, because date and datetime comparison raise + # TypeError instead of NotImplemented when they don't know what to + # do, in order to stop comparison from falling back to the default + # compare-by-address. + their = AnotherDateTimeClass() + self.assertRaises(TypeError, cmp, our, their) + self.assertEqual(cmp(their, our), 0) + + # But date and datetime comparison aise NotImplemented instead if the + # other object has a timetuple attr. + class Comparable(AnotherDateTimeClass): + def timetuple(self): + return () + + their = Comparable() + self.assertEqual(cmp(our, their), 0) + self.assertEqual(cmp(their, our), 0) + self.failUnless(our == their) + self.failUnless(their == our) + def test_bool(self): # All dates are considered true. From tim_one@users.sourceforge.net Fri Jan 24 19:08:00 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 11:08:00 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.104,1.105 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv21125 Modified Files: test_datetime.py Log Message: Typo repair. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.104 retrieving revision 1.105 diff -C2 -d -r1.104 -r1.105 *** test_datetime.py 24 Jan 2003 18:56:36 -0000 1.104 --- test_datetime.py 24 Jan 2003 19:07:56 -0000 1.105 *************** *** 899,904 **** self.assertEqual(cmp(their, our), 0) ! # But date and datetime comparison aise NotImplemented instead if the ! # other object has a timetuple attr. class Comparable(AnotherDateTimeClass): def timetuple(self): --- 899,905 ---- self.assertEqual(cmp(their, our), 0) ! # But date and datetime comparison return NotImplemented instead if the ! # other object has a timetuple attr. This gives the other object a ! # chance to do the comparison. class Comparable(AnotherDateTimeClass): def timetuple(self): From jhylton@users.sourceforge.net Fri Jan 24 19:29:55 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 24 Jan 2003 11:29:55 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.72,1.73 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv30250 Modified Files: pickle.py Log Message: Raise PicklingError when __reduce__() fails, and add memoize() helper function to update the memo. The first element of the tuple returned by __reduce__() must be a callable. If it isn't the Unpickler will raise an error. Catch this error in the pickler and raise the error there. The memoize() helper also has a comment explaining how the memo works. So methods can't use memoize() because the write funny codes. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** pickle.py 13 Nov 2002 22:01:26 -0000 1.72 --- pickle.py 24 Jan 2003 19:29:52 -0000 1.73 *************** *** 168,171 **** --- 168,187 ---- self.write(STOP) + def memoize(self, obj): + """Store an object in the memo.""" + + # The memo is a dictionary mapping object ids to 2-tuples + # that contains the memo value and the object being memoized. + # The memo value is written to the pickle and will become + # the key in the Unpickler's memo. The object is stored in the + # memo so that transient objects are kept alive during pickling. + + # The use of the memo length as the memo value is just a convention. + # The only requirement is that the memo values by unique. + d = id(obj) + memo_len = len(self.memo) + self.write(self.put(memo_len)) + self.memo[d] = memo_len, obj + def put(self, i): if self.bin: *************** *** 281,289 **** self.write(BINPERSID) ! def save_reduce(self, callable, arg_tup, state = None): write = self.write save = self.save ! save(callable) save(arg_tup) write(REDUCE) --- 297,309 ---- self.write(BINPERSID) ! def save_reduce(self, acallable, arg_tup, state = None): write = self.write save = self.save ! if not callable(acallable): ! raise PicklingError("__reduce__() must return callable as " ! "first argument, not %s" % `acallable`) ! ! save(acallable) save(arg_tup) write(REDUCE) *************** *** 341,347 **** def save_string(self, object): - d = id(object) - memo = self.memo - if self.bin: l = len(object) --- 361,364 ---- *************** *** 353,366 **** else: self.write(STRING + `object` + '\n') ! ! memo_len = len(memo) ! self.write(self.put(memo_len)) ! memo[d] = (memo_len, object) dispatch[StringType] = save_string def save_unicode(self, object): - d = id(object) - memo = self.memo - if self.bin: encoding = object.encode('utf-8') --- 370,377 ---- else: self.write(STRING + `object` + '\n') ! self.memoize(object) dispatch[StringType] = save_string def save_unicode(self, object): if self.bin: encoding = object.encode('utf-8') *************** *** 372,379 **** object = object.replace("\n", "\\u000a") self.write(UNICODE + object.encode('raw-unicode-escape') + '\n') ! ! memo_len = len(memo) ! self.write(self.put(memo_len)) ! memo[d] = (memo_len, object) dispatch[UnicodeType] = save_unicode --- 383,387 ---- object = object.replace("\n", "\\u000a") self.write(UNICODE + object.encode('raw-unicode-escape') + '\n') ! self.memoize(object) dispatch[UnicodeType] = save_unicode *************** *** 381,386 **** # This is true for Jython def save_string(self, object): - d = id(object) - memo = self.memo unicode = object.isunicode() --- 389,392 ---- *************** *** 405,416 **** else: self.write(STRING + `object` + '\n') ! ! memo_len = len(memo) ! self.write(self.put(memo_len)) ! memo[d] = (memo_len, object) dispatch[StringType] = save_string def save_tuple(self, object): - write = self.write save = self.save --- 411,418 ---- else: self.write(STRING + `object` + '\n') ! self.memoize(object) dispatch[StringType] = save_string def save_tuple(self, object): write = self.write save = self.save *************** *** 435,438 **** --- 437,441 ---- self.write(TUPLE + self.put(memo_len)) memo[d] = (memo_len, object) + dispatch[TupleType] = save_tuple *************** *** 452,458 **** write(MARK + LIST) ! memo_len = len(memo) ! write(self.put(memo_len)) ! memo[d] = (memo_len, object) using_appends = (self.bin and (len(object) > 1)) --- 455,459 ---- write(MARK + LIST) ! self.memoize(object) using_appends = (self.bin and (len(object) > 1)) *************** *** 472,480 **** def save_dict(self, object): - d = id(object) - write = self.write save = self.save - memo = self.memo if self.bin: --- 473,478 ---- *************** *** 483,489 **** write(MARK + DICT) ! memo_len = len(memo) ! self.write(self.put(memo_len)) ! memo[d] = (memo_len, object) using_setitems = (self.bin and (len(object) > 1)) --- 481,485 ---- write(MARK + DICT) ! self.memoize(object) using_setitems = (self.bin and (len(object) > 1)) *************** *** 530,533 **** --- 526,531 ---- save(arg) + # This method does not use memoize() so that it can handle + # the special case for non-binary mode. memo_len = len(memo) if self.bin: From nascheme@users.sourceforge.net Fri Jan 24 22:15:56 2003 From: nascheme@users.sourceforge.net (nascheme@users.sourceforge.net) Date: Fri, 24 Jan 2003 14:15:56 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.622,1.623 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv10516/Misc Modified Files: NEWS Log Message: Add news about getargs change. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.622 retrieving revision 1.623 diff -C2 -d -r1.622 -r1.623 *** NEWS 24 Jan 2003 15:31:27 -0000 1.622 --- NEWS 24 Jan 2003 22:15:53 -0000 1.623 *************** *** 167,171 **** ----- ! TBD New platforms --- 167,174 ---- ----- ! - The PyArg_Parse functions now raise a TypeError instead of truncating float ! arguments if an integer is specified (this affects the 'b', 'B', 'h', 'H', ! 'i', and 'l' codes). ! New platforms From tim_one@users.sourceforge.net Fri Jan 24 22:32:31 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 14:32:31 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime test_datetime.py,1.105,1.106 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv18543 Modified Files: test_datetime.py Log Message: Commenting out an obscure endcase test that can't be made to work the same way under the C and Python implementations of datetime without more work than it's worth. This has to do with exactly when mixed-type comparisons, of date or datetime objects, against other kinds of objects defining __cmp__, will or won't raise TypeError. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.105 retrieving revision 1.106 diff -C2 -d -r1.105 -r1.106 *** test_datetime.py 24 Jan 2003 19:07:56 -0000 1.105 --- test_datetime.py 24 Jan 2003 22:32:27 -0000 1.106 *************** *** 897,901 **** their = AnotherDateTimeClass() self.assertRaises(TypeError, cmp, our, their) ! self.assertEqual(cmp(their, our), 0) # But date and datetime comparison return NotImplemented instead if the --- 897,906 ---- their = AnotherDateTimeClass() self.assertRaises(TypeError, cmp, our, their) ! # Oops: The next stab raises TypeError in the C implementation, ! # but not in the Python implementation of datetime. The difference ! # is due to that the Python implementation defines __cmp__ but ! # the C implementation defines tp_richcompare. This is more pain ! # to fix than it's worth, so commenting out the test. ! # self.assertEqual(cmp(their, our), 0) # But date and datetime comparison return NotImplemented instead if the From nascheme@users.sourceforge.net Fri Jan 24 22:15:25 2003 From: nascheme@users.sourceforge.net (nascheme@users.sourceforge.net) Date: Fri, 24 Jan 2003 14:15:25 -0800 Subject: [Python-checkins] python/dist/src/Python getargs.c,2.94,2.95 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv9306/Python Modified Files: getargs.c Log Message: Raise a TypeError if a float is passed when an integer is specified. Calling PyInt_AsLong() on a float truncates it which is almost never the desired behavior. This closes SF bug #660144. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.94 retrieving revision 2.95 diff -C2 -d -r2.94 -r2.95 *** getargs.c 21 Nov 2002 20:23:11 -0000 2.94 --- getargs.c 24 Jan 2003 22:15:21 -0000 2.95 *************** *** 409,413 **** case 'b': { /* unsigned byte -- very short int */ char *p = va_arg(*p_va, char *); ! long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); --- 409,416 ---- case 'b': { /* unsigned byte -- very short int */ char *p = va_arg(*p_va, char *); ! long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ! ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); *************** *** 430,434 **** values allowed */ char *p = va_arg(*p_va, char *); ! long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); --- 433,440 ---- values allowed */ char *p = va_arg(*p_va, char *); ! long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ! ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); *************** *** 450,454 **** case 'h': {/* signed short int */ short *p = va_arg(*p_va, short *); ! long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); --- 456,463 ---- case 'h': {/* signed short int */ short *p = va_arg(*p_va, short *); ! long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ! ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); *************** *** 471,475 **** unsigned allowed */ unsigned short *p = va_arg(*p_va, unsigned short *); ! long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); --- 480,487 ---- unsigned allowed */ unsigned short *p = va_arg(*p_va, unsigned short *); ! long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ! ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); *************** *** 491,495 **** case 'i': {/* signed int */ int *p = va_arg(*p_va, int *); ! long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); --- 503,510 ---- case 'i': {/* signed int */ int *p = va_arg(*p_va, int *); ! long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ! ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); *************** *** 511,515 **** case 'l': {/* long int */ long *p = va_arg(*p_va, long *); ! long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); --- 526,533 ---- case 'l': {/* long int */ long *p = va_arg(*p_va, long *); ! long ival; ! if (PyFloat_Check(arg)) ! return converterr("integer", arg, msgbuf, bufsize); ! ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); From tim_one@users.sourceforge.net Fri Jan 24 22:36:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 14:36:36 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.623,1.624 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv21358/python/Misc Modified Files: NEWS Log Message: date and datetime comparison: when we don't know how to compare against "the other" argument, we raise TypeError, in order to prevent comparison from falling back to the default (and worse than useless, in this case) comparison by object address. That's fine so far as it goes, but leaves no way for another date/datetime object to make itself comparable to our objects. For example, it leaves Marc-Andre no way to teach mxDateTime dates how to compare against Python dates. Discussion on Python-Dev raised a number of impractical ideas, and the simple one implemented here: when we don't know how to compare against "the other" argument, we raise TypeError *unless* the other object has a timetuple attr. In that case, we return NotImplemented instead, and Python will give the other object a shot at handling the comparison then. Note that comparisons of time and timedelta objects still suffer the original problem, though. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.623 retrieving revision 1.624 diff -C2 -d -r1.623 -r1.624 *** NEWS 24 Jan 2003 22:15:53 -0000 1.623 --- NEWS 24 Jan 2003 22:36:31 -0000 1.624 *************** *** 101,104 **** --- 101,112 ---- also SF bug report . + date and datetime comparison: In order to prevent comparison from + falling back to the default compare-object-addresses strategy, these + raised TypeError whenever they didn't understand the other object type. + They still do, except when the other object has a "timetuple" attribute, + in which case they return NotImplemented now. This gives other + datetime objects (e.g., mxDateTime) a chance to intercept the + comparison. + The constructors building a datetime from a timestamp could raise ValueError if the platform C localtime()/gmtime() inserted "leap From tim_one@users.sourceforge.net Fri Jan 24 22:36:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 14:36:36 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.47,1.48 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv21358/python/Modules Modified Files: datetimemodule.c Log Message: date and datetime comparison: when we don't know how to compare against "the other" argument, we raise TypeError, in order to prevent comparison from falling back to the default (and worse than useless, in this case) comparison by object address. That's fine so far as it goes, but leaves no way for another date/datetime object to make itself comparable to our objects. For example, it leaves Marc-Andre no way to teach mxDateTime dates how to compare against Python dates. Discussion on Python-Dev raised a number of impractical ideas, and the simple one implemented here: when we don't know how to compare against "the other" argument, we raise TypeError *unless* the other object has a timetuple attr. In that case, we return NotImplemented instead, and Python will give the other object a shot at handling the comparison then. Note that comparisons of time and timedelta objects still suffer the original problem, though. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** datetimemodule.c 24 Jan 2003 02:44:45 -0000 1.47 --- datetimemodule.c 24 Jan 2003 22:36:34 -0000 1.48 *************** *** 2438,2443 **** if (! PyDate_Check(other)) { PyErr_Format(PyExc_TypeError, ! "can't compare date to %s instance", other->ob_type->tp_name); return NULL; --- 2438,2450 ---- if (! PyDate_Check(other)) { + if (PyObject_HasAttrString(other, "timetuple")) { + /* A hook for other kinds of date objects. */ + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + /* Stop this from falling back to address comparison. */ PyErr_Format(PyExc_TypeError, ! "can't compare '%s' to '%s'", ! self->ob_type->tp_name, other->ob_type->tp_name); return NULL; *************** *** 4019,4022 **** --- 4026,4034 ---- if (! PyDateTime_Check(other)) { + if (PyObject_HasAttrString(other, "timetuple")) { + /* A hook for other kinds of datetime objects. */ + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } /* Stop this from falling back to address comparison. */ PyErr_Format(PyExc_TypeError, From tim_one@users.sourceforge.net Fri Jan 24 22:37:02 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 14:37:02 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv21358/python/Doc/lib Modified Files: libdatetime.tex Log Message: date and datetime comparison: when we don't know how to compare against "the other" argument, we raise TypeError, in order to prevent comparison from falling back to the default (and worse than useless, in this case) comparison by object address. That's fine so far as it goes, but leaves no way for another date/datetime object to make itself comparable to our objects. For example, it leaves Marc-Andre no way to teach mxDateTime dates how to compare against Python dates. Discussion on Python-Dev raised a number of impractical ideas, and the simple one implemented here: when we don't know how to compare against "the other" argument, we raise TypeError *unless* the other object has a timetuple attr. In that case, we return NotImplemented instead, and Python will give the other object a shot at handling the comparison then. Note that comparisons of time and timedelta objects still suffer the original problem, though. Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** libdatetime.tex 23 Jan 2003 20:53:07 -0000 1.39 --- libdatetime.tex 24 Jan 2003 22:36:30 -0000 1.40 *************** *** 382,385 **** --- 382,393 ---- date2 when date1 precedes date2 in time. In other words, date1 < date2 if and only if date1.toordinal() < date2.toordinal(). + \note{In order to stop comparison from falling back to the default + scheme of comparing object addresses, date comparison + normally raises \exception{TypeError} if the other comparand + isn't also a \class{date} object. However, \code{NotImplemented} + is returned instead if the other comparand has a + \method{timetuple} attribute. This hook gives other kinds of + date objects a chance at implementing mixed-type comparison.} + \item *************** *** 712,715 **** --- 720,731 ---- \member{tzinfo} members, the comparands are first adjusted by subtracting their UTC offsets (obtained from \code{self.utcoffset()}). + \note{In order to stop comparison from falling back to the default + scheme of comparing object addresses, datetime comparison + normally raises \exception{TypeError} if the other comparand + isn't also a \class{datetime} object. However, + \code{NotImplemented} is returned instead if the other comparand + has a \method{timetuple} attribute. This hook gives other + kinds of date objects a chance at implementing mixed-type + comparison.} \item From tim_one@users.sourceforge.net Fri Jan 24 22:37:03 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 24 Jan 2003 14:37:03 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv21358/python/Lib/test Modified Files: test_datetime.py Log Message: date and datetime comparison: when we don't know how to compare against "the other" argument, we raise TypeError, in order to prevent comparison from falling back to the default (and worse than useless, in this case) comparison by object address. That's fine so far as it goes, but leaves no way for another date/datetime object to make itself comparable to our objects. For example, it leaves Marc-Andre no way to teach mxDateTime dates how to compare against Python dates. Discussion on Python-Dev raised a number of impractical ideas, and the simple one implemented here: when we don't know how to compare against "the other" argument, we raise TypeError *unless* the other object has a timetuple attr. In that case, we return NotImplemented instead, and Python will give the other object a shot at handling the comparison then. Note that comparisons of time and timedelta objects still suffer the original problem, though. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** test_datetime.py 23 Jan 2003 20:53:08 -0000 1.29 --- test_datetime.py 24 Jan 2003 22:36:30 -0000 1.30 *************** *** 881,884 **** --- 881,922 ---- self.assertRaises(TypeError, lambda: badarg >= t1) + def test_mixed_compare(self): + our = self.theclass(2000, 4, 5) + self.assertRaises(TypeError, cmp, our, 1) + self.assertRaises(TypeError, cmp, 1, our) + + class AnotherDateTimeClass(object): + def __cmp__(self, other): + # Return "equal" so calling this can't be confused with + # compare-by-address (which never says "equal" for distinct + # objects). + return 0 + + # This still errors, because date and datetime comparison raise + # TypeError instead of NotImplemented when they don't know what to + # do, in order to stop comparison from falling back to the default + # compare-by-address. + their = AnotherDateTimeClass() + self.assertRaises(TypeError, cmp, our, their) + # Oops: The next stab raises TypeError in the C implementation, + # but not in the Python implementation of datetime. The difference + # is due to that the Python implementation defines __cmp__ but + # the C implementation defines tp_richcompare. This is more pain + # to fix than it's worth, so commenting out the test. + # self.assertEqual(cmp(their, our), 0) + + # But date and datetime comparison return NotImplemented instead if the + # other object has a timetuple attr. This gives the other object a + # chance to do the comparison. + class Comparable(AnotherDateTimeClass): + def timetuple(self): + return () + + their = Comparable() + self.assertEqual(cmp(our, their), 0) + self.assertEqual(cmp(their, our), 0) + self.failUnless(our == their) + self.failUnless(their == our) + def test_bool(self): # All dates are considered true. From fdrake@users.sourceforge.net Sat Jan 25 03:47:37 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 24 Jan 2003 19:47:37 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv18435 Modified Files: ref6.tex Log Message: Fix typo reported to python-docs. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** ref6.tex 19 Jan 2003 13:08:18 -0000 1.61 --- ref6.tex 25 Jan 2003 03:47:35 -0000 1.62 *************** *** 534,538 **** If the first object is an instance, the type of the exception is the ! class of the instance, the instance itself if the value, and the second object must be \code{None}. --- 534,538 ---- If the first object is an instance, the type of the exception is the ! class of the instance, the instance itself is the value, and the second object must be \code{None}. From fdrake@users.sourceforge.net Sat Jan 25 03:48:14 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 24 Jan 2003 19:48:14 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref6.tex,1.47.4.7,1.47.4.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv18651 Modified Files: Tag: release22-maint ref6.tex Log Message: Fix typo reported to python-docs. Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.47.4.7 retrieving revision 1.47.4.8 diff -C2 -d -r1.47.4.7 -r1.47.4.8 *** ref6.tex 19 Jan 2003 14:54:08 -0000 1.47.4.7 --- ref6.tex 25 Jan 2003 03:48:12 -0000 1.47.4.8 *************** *** 534,538 **** If the first object is an instance, the type of the exception is the ! class of the instance, the instance itself if the value, and the second object must be \code{None}. --- 534,538 ---- If the first object is an instance, the type of the exception is the ! class of the instance, the instance itself is the value, and the second object must be \code{None}. From fdrake@users.sourceforge.net Sat Jan 25 07:48:16 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 24 Jan 2003 23:48:16 -0800 Subject: [Python-checkins] python/dist/src/Doc/api abstract.tex,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv31190 Modified Files: abstract.tex Log Message: Include version annotation for PyObject_Call(). Index: abstract.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/abstract.tex,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** abstract.tex 12 Dec 2002 16:41:37 -0000 1.22 --- abstract.tex 25 Jan 2003 07:48:13 -0000 1.23 *************** *** 237,240 **** --- 237,241 ---- or \samp{\var{callable_object}(*\var{args}, **\var{kw})}. \bifuncindex{apply} + \versionadded{2.2} \end{cfuncdesc} From loewis@users.sourceforge.net Sat Jan 25 15:11:09 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 07:11:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/dom expatbuilder.py,NONE,1.1 minicompat.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory sc8-pr-cvs1:/tmp/cvs-serv1599 Added Files: expatbuilder.py minicompat.py Log Message: Import expatbuilder, minicompat from PyXML. --- NEW FILE: expatbuilder.py --- """Facility to use the Expat parser to load a minidom instance from a string or file. This avoids all the overhead of SAX and pulldom to gain performance. """ # Warning! # # This module is tightly bound to the implementation details of the # minidom DOM and can't be used with other DOM implementations. This # is due, in part, to a lack of appropriate methods in the DOM (there is # no way to create Entity and Notation nodes via the DOM Level 2 # interface), and for performance. The later is the cause of some fairly # cryptic code. # # Performance hacks: # # - .character_data_handler() has an extra case in which continuing # data is appended to an existing Text node; this can be a # speedup since pyexpat can break up character data into multiple # callbacks even though we set the buffer_text attribute on the # parser. This also gives us the advantage that we don't need a # separate normalization pass. # # - Determining that a node exists is done using an identity comparison # with None rather than a truth test; this avoids searching for and # calling any methods on the node object if it exists. (A rather # nice speedup is achieved this way as well!) from xml.dom import xmlbuilder, minidom, Node from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE from xml.parsers import expat from xml.dom.minidom import _append_child, _set_attribute_node from xml.dom.NodeFilter import NodeFilter from xml.dom.minicompat import * TEXT_NODE = Node.TEXT_NODE CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE DOCUMENT_NODE = Node.DOCUMENT_NODE FILTER_ACCEPT = xmlbuilder.DOMBuilderFilter.FILTER_ACCEPT FILTER_REJECT = xmlbuilder.DOMBuilderFilter.FILTER_REJECT FILTER_SKIP = xmlbuilder.DOMBuilderFilter.FILTER_SKIP FILTER_INTERRUPT = xmlbuilder.DOMBuilderFilter.FILTER_INTERRUPT theDOMImplementation = minidom.getDOMImplementation() # Expat typename -> TypeInfo _typeinfo_map = { "CDATA": minidom.TypeInfo(None, "cdata"), "ENUM": minidom.TypeInfo(None, "enumeration"), "ENTITY": minidom.TypeInfo(None, "entity"), "ENTITIES": minidom.TypeInfo(None, "entities"), "ID": minidom.TypeInfo(None, "id"), "IDREF": minidom.TypeInfo(None, "idref"), "IDREFS": minidom.TypeInfo(None, "idrefs"), "NMTOKEN": minidom.TypeInfo(None, "nmtoken"), "NMTOKENS": minidom.TypeInfo(None, "nmtokens"), } class ElementInfo(NewStyle): __slots__ = '_attr_info', '_model', 'tagName' def __init__(self, tagName, model=None): self.tagName = tagName self._attr_info = [] self._model = model def __getstate__(self): return self._attr_info, self._model, self.tagName def __setstate__(self, state): self._attr_info, self._model, self.tagName = state def getAttributeType(self, aname): for info in self._attr_info: if info[1] == aname: t = info[-2] if t[0] == "(": return _typeinfo_map["ENUM"] else: return _typeinfo_map[info[-2]] return minidom._no_type def getAttributeTypeNS(self, namespaceURI, localName): return minidom._no_type def isElementContent(self): if self._model: type = self._model[0] return type not in (expat.model.XML_CTYPE_ANY, expat.model.XML_CTYPE_MIXED) else: return False def isEmpty(self): if self._model: return self._model[0] == expat.model.XML_CTYPE_EMPTY else: return False def isId(self, aname): for info in self._attr_info: if info[1] == aname: return info[-2] == "ID" return False def isIdNS(self, euri, ename, auri, aname): # not sure this is meaningful return self.isId((auri, aname)) def _intern(builder, s): return builder._intern_setdefault(s, s) def _parse_ns_name(builder, name): assert ' ' in name parts = name.split(' ') intern = builder._intern_setdefault if len(parts) == 3: uri, localname, prefix = parts prefix = intern(prefix, prefix) qname = "%s:%s" % (prefix, localname) qname = intern(qname, qname) localname = intern(localname, localname) else: uri, localname = parts prefix = EMPTY_PREFIX qname = localname = intern(localname, localname) return intern(uri, uri), localname, prefix, qname class ExpatBuilder: """Document builder that uses Expat to build a ParsedXML.DOM document instance.""" def __init__(self, options=None): if options is None: options = xmlbuilder.Options() self._options = options if self._options.filter is not None: self._filter = FilterVisibilityController(self._options.filter) else: self._filter = None # This *really* doesn't do anything in this case, so # override it with something fast & minimal. self._finish_start_element = id self._parser = None self.reset() def createParser(self): """Create a new parser object.""" return expat.ParserCreate() def getParser(self): """Return the parser object, creating a new one if needed.""" if not self._parser: self._parser = self.createParser() self._intern_setdefault = self._parser.intern.setdefault self._parser.buffer_text = True self._parser.ordered_attributes = True self._parser.specified_attributes = True self.install(self._parser) return self._parser def reset(self): """Free all data structures used during DOM construction.""" self.document = theDOMImplementation.createDocument( EMPTY_NAMESPACE, None, None) self.curNode = self.document self._elem_info = self.document._elem_info self._cdata = False def install(self, parser): """Install the callbacks needed to build the DOM into the parser.""" # This creates circular references! parser.StartDoctypeDeclHandler = self.start_doctype_decl_handler parser.StartElementHandler = self.first_element_handler parser.EndElementHandler = self.end_element_handler parser.ProcessingInstructionHandler = self.pi_handler if self._options.entities: parser.EntityDeclHandler = self.entity_decl_handler parser.NotationDeclHandler = self.notation_decl_handler if self._options.comments: parser.CommentHandler = self.comment_handler if self._options.cdata_sections: parser.StartCdataSectionHandler = self.start_cdata_section_handler parser.EndCdataSectionHandler = self.end_cdata_section_handler parser.CharacterDataHandler = self.character_data_handler_cdata else: parser.CharacterDataHandler = self.character_data_handler parser.ExternalEntityRefHandler = self.external_entity_ref_handler parser.XmlDeclHandler = self.xml_decl_handler parser.ElementDeclHandler = self.element_decl_handler parser.AttlistDeclHandler = self.attlist_decl_handler def parseFile(self, file): """Parse a document from a file object, returning the document node.""" parser = self.getParser() first_buffer = True try: while 1: buffer = file.read(16*1024) if not buffer: break parser.Parse(buffer, 0) if first_buffer and self.document.documentElement: self._setup_subset(buffer) first_buffer = False parser.Parse("", True) except ParseEscape: pass doc = self.document self.reset() self._parser = None return doc def parseString(self, string): """Parse a document from a string, returning the document node.""" parser = self.getParser() try: parser.Parse(string, True) self._setup_subset(string) except ParseEscape: pass doc = self.document self.reset() self._parser = None return doc def _setup_subset(self, buffer): """Load the internal subset if there might be one.""" if self.document.doctype: extractor = InternalSubsetExtractor() extractor.parseString(buffer) subset = extractor.getSubset() self.document.doctype.internalSubset = subset def start_doctype_decl_handler(self, doctypeName, systemId, publicId, has_internal_subset): doctype = self.document.implementation.createDocumentType( doctypeName, publicId, systemId) doctype.ownerDocument = self.document self.document.childNodes.append(doctype) self.document.doctype = doctype if self._filter and self._filter.acceptNode(doctype) == FILTER_REJECT: self.document.doctype = None del self.document.childNodes[-1] doctype = None self._parser.EntityDeclHandler = None self._parser.NotationDeclHandler = None if has_internal_subset: if doctype is not None: doctype.entities._seq = [] doctype.notations._seq = [] self._parser.CommentHandler = None self._parser.ProcessingInstructionHandler = None self._parser.EndDoctypeDeclHandler = self.end_doctype_decl_handler def end_doctype_decl_handler(self): if self._options.comments: self._parser.CommentHandler = self.comment_handler self._parser.ProcessingInstructionHandler = self.pi_handler if not (self._elem_info or self._filter): self._finish_end_element = id def pi_handler(self, target, data): node = self.document.createProcessingInstruction(target, data) _append_child(self.curNode, node) if self._filter and self._filter.acceptNode(node) == FILTER_REJECT: curNode.removeChild(node) def character_data_handler_cdata(self, data): childNodes = self.curNode.childNodes if self._cdata: if ( self._cdata_continue and childNodes[-1].nodeType == CDATA_SECTION_NODE): childNodes[-1].appendData(data) return node = self.document.createCDATASection(data) self._cdata_continue = True elif childNodes and childNodes[-1].nodeType == TEXT_NODE: node = childNodes[-1] value = node.data + data d = node.__dict__ d['data'] = d['nodeValue'] = value return else: node = minidom.Text() d = node.__dict__ d['data'] = d['nodeValue'] = data d['ownerDocument'] = self.document _append_child(self.curNode, node) def character_data_handler(self, data): childNodes = self.curNode.childNodes if childNodes and childNodes[-1].nodeType == TEXT_NODE: node = childNodes[-1] d = node.__dict__ d['data'] = d['nodeValue'] = node.data + data return node = minidom.Text() d = node.__dict__ d['data'] = d['nodeValue'] = node.data + data d['ownerDocument'] = self.document _append_child(self.curNode, node) def entity_decl_handler(self, entityName, is_parameter_entity, value, base, systemId, publicId, notationName): if is_parameter_entity: # we don't care about parameter entities for the DOM return if not self._options.entities: return node = self.document._create_entity(entityName, publicId, systemId, notationName) if value is not None: # internal entity # node *should* be readonly, but we'll cheat child = self.document.createTextNode(value) node.childNodes.append(child) self.document.doctype.entities._seq.append(node) if self._filter and self._filter.acceptNode(node) == FILTER_REJECT: del self.document.doctype.entities._seq[-1] def notation_decl_handler(self, notationName, base, systemId, publicId): node = self.document._create_notation(notationName, publicId, systemId) self.document.doctype.notations._seq.append(node) if self._filter and self._filter.acceptNode(node) == FILTER_ACCEPT: del self.document.doctype.notations._seq[-1] def comment_handler(self, data): node = self.document.createComment(data) _append_child(self.curNode, node) if self._filter and self._filter.acceptNode(node) == FILTER_REJECT: curNode.removeChild(node) def start_cdata_section_handler(self): self._cdata = True self._cdata_continue = False def end_cdata_section_handler(self): self._cdata = False self._cdata_continue = False def external_entity_ref_handler(self, context, base, systemId, publicId): return 1 def first_element_handler(self, name, attributes): if self._filter is None and not self._elem_info: self._finish_end_element = id self.getParser().StartElementHandler = self.start_element_handler self.start_element_handler(name, attributes) def start_element_handler(self, name, attributes): node = self.document.createElement(name) _append_child(self.curNode, node) self.curNode = node if attributes: for i in range(0, len(attributes), 2): a = minidom.Attr(attributes[i], EMPTY_NAMESPACE, None, EMPTY_PREFIX) value = attributes[i+1] d = a.childNodes[0].__dict__ d['data'] = d['nodeValue'] = value d = a.__dict__ d['value'] = d['nodeValue'] = value d['ownerDocument'] = self.document _set_attribute_node(node, a) if node is not self.document.documentElement: self._finish_start_element(node) def _finish_start_element(self, node): if self._filter: # To be general, we'd have to call isSameNode(), but this # is sufficient for minidom: if node is self.document.documentElement: return filt = self._filter.startContainer(node) if filt == FILTER_REJECT: # ignore this node & all descendents Rejecter(self) elif filt == FILTER_SKIP: # ignore this node, but make it's children become # children of the parent node Skipper(self) else: return self.curNode = node.parentNode node.parentNode.removeChild(node) node.unlink() # If this ever changes, Namespaces.end_element_handler() needs to # be changed to match. # def end_element_handler(self, name): curNode = self.curNode self.curNode = curNode.parentNode self._finish_end_element(curNode) def _finish_end_element(self, curNode): info = self._elem_info.get(curNode.tagName) if info: self._handle_white_text_nodes(curNode, info) if self._filter: if curNode is self.document.documentElement: return if self._filter.acceptNode(curNode) == FILTER_REJECT: self.curNode.removeChild(curNode) curNode.unlink() def _handle_white_text_nodes(self, node, info): if (self._options.whitespace_in_element_content or not info.isElementContent()): return # We have element type information and should remove ignorable # whitespace; identify for text nodes which contain only # whitespace. L = [] for child in node.childNodes: if child.nodeType == TEXT_NODE and not child.data.strip(): L.append(child) # Remove ignorable whitespace from the tree. for child in L: node.removeChild(child) def element_decl_handler(self, name, model): info = self._elem_info.get(name) if info is None: self._elem_info[name] = ElementInfo(name, model) else: assert info._model is None info._model = model def attlist_decl_handler(self, elem, name, type, default, required): info = self._elem_info.get(elem) if info is None: info = ElementInfo(elem) self._elem_info[elem] = info info._attr_info.append( [None, name, None, None, default, 0, type, required]) def xml_decl_handler(self, version, encoding, standalone): self.document.version = version self.document.encoding = encoding # This is still a little ugly, thanks to the pyexpat API. ;-( if standalone >= 0: if standalone: self.document.standalone = True else: self.document.standalone = False # Don't include FILTER_INTERRUPT, since that's checked separately # where allowed. _ALLOWED_FILTER_RETURNS = (FILTER_ACCEPT, FILTER_REJECT, FILTER_SKIP) class FilterVisibilityController(NewStyle): """Wrapper around a DOMBuilderFilter which implements the checks to make the whatToShow filter attribute work.""" __slots__ = 'filter', def __init__(self, filter): self.filter = filter def startContainer(self, node): mask = self._nodetype_mask[node.nodeType] if self.filter.whatToShow & mask: val = self.filter.startContainer(node) if val == FILTER_INTERRUPT: raise ParseEscape if val not in _ALLOWED_FILTER_RETURNS: raise ValueError, \ "startContainer() returned illegal value: " + repr(val) return val else: return FILTER_ACCEPT def acceptNode(self, node): mask = self._nodetype_mask[node.nodeType] if self.filter.whatToShow & mask: val = self.filter.acceptNode(node) if val == FILTER_INTERRUPT: raise ParseEscape if val == FILTER_SKIP: # move all child nodes to the parent, and remove this node parent = node.parentNode for child in node.childNodes[:]: parent.appendChild(child) # node is handled by the caller return FILTER_REJECT if val not in _ALLOWED_FILTER_RETURNS: raise ValueError, \ "acceptNode() returned illegal value: " + repr(val) return val else: return FILTER_ACCEPT _nodetype_mask = { Node.ELEMENT_NODE: NodeFilter.SHOW_ELEMENT, Node.ATTRIBUTE_NODE: NodeFilter.SHOW_ATTRIBUTE, Node.TEXT_NODE: NodeFilter.SHOW_TEXT, Node.CDATA_SECTION_NODE: NodeFilter.SHOW_CDATA_SECTION, Node.ENTITY_REFERENCE_NODE: NodeFilter.SHOW_ENTITY_REFERENCE, Node.ENTITY_NODE: NodeFilter.SHOW_ENTITY, Node.PROCESSING_INSTRUCTION_NODE: NodeFilter.SHOW_PROCESSING_INSTRUCTION, Node.COMMENT_NODE: NodeFilter.SHOW_COMMENT, Node.DOCUMENT_NODE: NodeFilter.SHOW_DOCUMENT, Node.DOCUMENT_TYPE_NODE: NodeFilter.SHOW_DOCUMENT_TYPE, Node.DOCUMENT_FRAGMENT_NODE: NodeFilter.SHOW_DOCUMENT_FRAGMENT, Node.NOTATION_NODE: NodeFilter.SHOW_NOTATION, } class FilterCrutch(NewStyle): __slots__ = '_builder', '_level', '_old_start', '_old_end' def __init__(self, builder): self._level = 0 self._builder = builder parser = builder._parser self._old_start = parser.StartElementHandler self._old_end = parser.EndElementHandler parser.StartElementHandler = self.start_element_handler parser.EndElementHandler = self.end_element_handler class Rejecter(FilterCrutch): __slots__ = () def __init__(self, builder): FilterCrutch.__init__(self, builder) parser = builder._parser for name in ("ProcessingInstructionHandler", "CommentHandler", "CharacterDataHandler", "StartCdataSectionHandler", "EndCdataSectionHandler", "ExternalEntityRefHandler", ): setattr(parser, name, None) def start_element_handler(self, *args): self._level = self._level + 1 def end_element_handler(self, *args): if self._level == 0: # restore the old handlers parser = self._builder._parser self._builder.install(parser) parser.StartElementHandler = self._old_start parser.EndElementHandler = self._old_end else: self._level = self._level - 1 class Skipper(FilterCrutch): __slots__ = () def start_element_handler(self, *args): node = self._builder.curNode self._old_start(*args) if self._builder.curNode is not node: self._level = self._level + 1 def end_element_handler(self, *args): if self._level == 0: # We're popping back out of the node we're skipping, so we # shouldn't need to do anything but reset the handlers. self._builder._parser.StartElementHandler = self._old_start self._builder._parser.EndElementHandler = self._old_end self._builder = None else: self._level = self._level - 1 self._old_end(*args) # framework document used by the fragment builder. # Takes a string for the doctype, subset string, and namespace attrs string. _FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID = \ "http://xml.python.org/entities/fragment-builder/internal" _FRAGMENT_BUILDER_TEMPLATE = ( '''\ %%s ]> &fragment-builder-internal;''' % _FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID) class FragmentBuilder(ExpatBuilder): """Builder which constructs document fragments given XML source text and a context node. The context node is expected to provide information about the namespace declarations which are in scope at the start of the fragment. """ def __init__(self, context, options=None): if context.nodeType == DOCUMENT_NODE: self.originalDocument = context self.context = context else: self.originalDocument = context.ownerDocument self.context = context ExpatBuilder.__init__(self, options) def reset(self): ExpatBuilder.reset(self) self.fragment = None def parseFile(self, file): """Parse a document fragment from a file object, returning the fragment node.""" return self.parseString(file.read()) def parseString(self, string): """Parse a document fragment from a string, returning the fragment node.""" self._source = string parser = self.getParser() doctype = self.originalDocument.doctype ident = "" if doctype: subset = doctype.internalSubset or self._getDeclarations() if doctype.publicId: ident = ('PUBLIC "%s" "%s"' % (doctype.publicId, doctype.systemId)) elif doctype.systemId: ident = 'SYSTEM "%s"' % doctype.systemId else: subset = "" nsattrs = self._getNSattrs() # get ns decls from node's ancestors document = _FRAGMENT_BUILDER_TEMPLATE % (ident, subset, nsattrs) try: parser.Parse(document, 1) except: self.reset() raise fragment = self.fragment self.reset() ## self._parser = None return fragment def _getDeclarations(self): """Re-create the internal subset from the DocumentType node. This is only needed if we don't already have the internalSubset as a string. """ doctype = self.context.ownerDocument.doctype s = "" if doctype: for i in range(doctype.notations.length): notation = doctype.notations.item(i) if s: s = s + "\n " s = "%s' \ % (s, notation.publicId, notation.systemId) else: s = '%s SYSTEM "%s">' % (s, notation.systemId) for i in range(doctype.entities.length): entity = doctype.entities.item(i) if s: s = s + "\n " s = "%s" return s def _getNSattrs(self): return "" def external_entity_ref_handler(self, context, base, systemId, publicId): if systemId == _FRAGMENT_BUILDER_INTERNAL_SYSTEM_ID: # this entref is the one that we made to put the subtree # in; all of our given input is parsed in here. old_document = self.document old_cur_node = self.curNode parser = self._parser.ExternalEntityParserCreate(context) # put the real document back, parse into the fragment to return self.document = self.originalDocument self.fragment = self.document.createDocumentFragment() self.curNode = self.fragment try: parser.Parse(self._source, 1) finally: self.curNode = old_cur_node self.document = old_document self._source = None return -1 else: return ExpatBuilder.external_entity_ref_handler( self, context, base, systemId, publicId) class Namespaces: """Mix-in class for builders; adds support for namespaces.""" def _initNamespaces(self): # list of (prefix, uri) ns declarations. Namespace attrs are # constructed from this and added to the element's attrs. self._ns_ordered_prefixes = [] def createParser(self): """Create a new namespace-handling parser.""" parser = expat.ParserCreate(namespace_separator=" ") parser.namespace_prefixes = True return parser def install(self, parser): """Insert the namespace-handlers onto the parser.""" ExpatBuilder.install(self, parser) if self._options.namespace_declarations: parser.StartNamespaceDeclHandler = ( self.start_namespace_decl_handler) def start_namespace_decl_handler(self, prefix, uri): """Push this namespace declaration on our storage.""" self._ns_ordered_prefixes.append((prefix, uri)) def start_element_handler(self, name, attributes): if ' ' in name: uri, localname, prefix, qname = _parse_ns_name(self, name) else: uri = EMPTY_NAMESPACE qname = name localname = None prefix = EMPTY_PREFIX node = minidom.Element(qname, uri, prefix, localname) node.ownerDocument = self.document _append_child(self.curNode, node) self.curNode = node if self._ns_ordered_prefixes: for prefix, uri in self._ns_ordered_prefixes: if prefix: a = minidom.Attr(_intern(self, 'xmlns:' + prefix), XMLNS_NAMESPACE, prefix, "xmlns") else: a = minidom.Attr("xmlns", XMLNS_NAMESPACE, "xmlns", EMPTY_PREFIX) d = a.childNodes[0].__dict__ d['data'] = d['nodeValue'] = uri d = a.__dict__ d['value'] = d['nodeValue'] = uri d['ownerDocument'] = self.document _set_attribute_node(node, a) del self._ns_ordered_prefixes[:] if attributes: _attrs = node._attrs _attrsNS = node._attrsNS for i in range(0, len(attributes), 2): aname = attributes[i] value = attributes[i+1] if ' ' in aname: uri, localname, prefix, qname = _parse_ns_name(self, aname) a = minidom.Attr(qname, uri, localname, prefix) _attrs[qname] = a _attrsNS[(uri, localname)] = a else: a = minidom.Attr(aname, EMPTY_NAMESPACE, aname, EMPTY_PREFIX) _attrs[aname] = a _attrsNS[(EMPTY_NAMESPACE, aname)] = a d = a.childNodes[0].__dict__ d['data'] = d['nodeValue'] = value d = a.__dict__ d['ownerDocument'] = self.document d['value'] = d['nodeValue'] = value d['ownerElement'] = node if __debug__: # This only adds some asserts to the original # end_element_handler(), so we only define this when -O is not # used. If changing one, be sure to check the other to see if # it needs to be changed as well. # def end_element_handler(self, name): curNode = self.curNode if ' ' in name: uri, localname, prefix, qname = _parse_ns_name(self, name) assert (curNode.namespaceURI == uri and curNode.localName == localname and curNode.prefix == prefix), \ "element stack messed up! (namespace)" else: assert curNode.nodeName == name, \ "element stack messed up - bad nodeName" assert curNode.namespaceURI == EMPTY_NAMESPACE, \ "element stack messed up - bad namespaceURI" self.curNode = curNode.parentNode self._finish_end_element(curNode) class ExpatBuilderNS(Namespaces, ExpatBuilder): """Document builder that supports namespaces.""" def reset(self): ExpatBuilder.reset(self) self._initNamespaces() class FragmentBuilderNS(Namespaces, FragmentBuilder): """Fragment builder that supports namespaces.""" def reset(self): FragmentBuilder.reset(self) self._initNamespaces() def _getNSattrs(self): """Return string of namespace attributes from this element and ancestors.""" # XXX This needs to be re-written to walk the ancestors of the # context to build up the namespace information from # declarations, elements, and attributes found in context. # Otherwise we have to store a bunch more data on the DOM # (though that *might* be more reliable -- not clear). attrs = "" context = self.context L = [] while context: if hasattr(context, '_ns_prefix_uri'): for prefix, uri in context._ns_prefix_uri.items(): # add every new NS decl from context to L and attrs string if prefix in L: continue L.append(prefix) if prefix: declname = "xmlns:" + prefix else: declname = "xmlns" if attrs: attrs = "%s\n %s='%s'" % (attrs, declname, uri) else: attrs = " %s='%s'" % (declname, uri) context = context.parentNode return attrs class ParseEscape(Exception): """Exception raised to short-circuit parsing in InternalSubsetExtractor.""" pass class InternalSubsetExtractor(ExpatBuilder): """XML processor which can rip out the internal document type subset.""" subset = None def getSubset(self): """Return the internal subset as a string.""" return self.subset def parseFile(self, file): try: ExpatBuilder.parseFile(self, file) except ParseEscape: pass def parseString(self, string): try: ExpatBuilder.parseString(self, string) except ParseEscape: pass def install(self, parser): parser.StartDoctypeDeclHandler = self.start_doctype_decl_handler parser.StartElementHandler = self.start_element_handler def start_doctype_decl_handler(self, name, publicId, systemId, has_internal_subset): if has_internal_subset: parser = self.getParser() self.subset = [] parser.DefaultHandler = self.subset.append parser.EndDoctypeDeclHandler = self.end_doctype_decl_handler else: raise ParseEscape() def end_doctype_decl_handler(self): s = ''.join(self.subset).replace('\r\n', '\n').replace('\r', '\n') self.subset = s raise ParseEscape() def start_element_handler(self, name, attrs): raise ParseEscape() def parse(file, namespaces=1): """Parse a document, returning the resulting Document node. 'file' may be either a file name or an open file object. """ if namespaces: builder = ExpatBuilderNS() else: builder = ExpatBuilder() if isinstance(file, StringTypes): fp = open(file, 'rb') try: result = builder.parseFile(fp) finally: fp.close() else: result = builder.parseFile(file) return result def parseString(string, namespaces=1): """Parse a document from a string, returning the resulting Document node. """ if namespaces: builder = ExpatBuilderNS() else: builder = ExpatBuilder() return builder.parseString(string) def parseFragment(file, context, namespaces=1): """Parse a fragment of a document, given the context from which it was originally extracted. context should be the parent of the node(s) which are in the fragment. 'file' may be either a file name or an open file object. """ if namespaces: builder = FragmentBuilderNS(context) else: builder = FragmentBuilder(context) if isinstance(file, StringTypes): fp = open(file, 'rb') try: result = builder.parseFile(fp) finally: fp.close() else: result = builder.parseFile(file) return result def parseFragmentString(string, context, namespaces=1): """Parse a fragment of a document from a string, given the context from which it was originally extracted. context should be the parent of the node(s) which are in the fragment. """ if namespaces: builder = FragmentBuilderNS(context) else: builder = FragmentBuilder(context) return builder.parseString(string) def makeBuilder(options): """Create a builder based on an Options object.""" if options.namespaces: return ExpatBuilderNS(options) else: return ExpatBuilder(options) --- NEW FILE: minicompat.py --- """Python version compatibility support for minidom.""" # This module should only be imported using "import *". # # The following names are defined: # # isinstance -- version of the isinstance() function that accepts # tuples as the second parameter regardless of the # Python version # # NodeList -- lightest possible NodeList implementation # # EmptyNodeList -- lightest possible NodeList that is guarateed to # remain empty (immutable) # # StringTypes -- tuple of defined string types # # GetattrMagic -- base class used to make _get_ be magically # invoked when available # defproperty -- function used in conjunction with GetattrMagic; # using these together is needed to make them work # as efficiently as possible in both Python 2.2+ # and older versions. For example: # # class MyClass(GetattrMagic): # def _get_myattr(self): # return something # # defproperty(MyClass, "myattr", # "return some value") # # For Python 2.2 and newer, this will construct a # property object on the class, which avoids # needing to override __getattr__(). It will only # work for read-only attributes. # # For older versions of Python, inheriting from # GetattrMagic will use the traditional # __getattr__() hackery to achieve the same effect, # but less efficiently. # # defproperty() should be used for each version of # the relevant _get_() function. # # NewStyle -- base class to cause __slots__ to be honored in # the new world # # True, False -- only for Python 2.2 and earlier __all__ = ["NodeList", "EmptyNodeList", "NewStyle", "StringTypes", "defproperty", "GetattrMagic"] import xml.dom try: unicode except NameError: StringTypes = type(''), else: StringTypes = type(''), type(unicode('')) # define True and False only if not defined as built-ins try: True except NameError: True = 1 False = 0 __all__.extend(["True", "False"]) try: isinstance('', StringTypes) except TypeError: # # Wrap isinstance() to make it compatible with the version in # Python 2.2 and newer. # _isinstance = isinstance def isinstance(obj, type_or_seq): try: return _isinstance(obj, type_or_seq) except TypeError: for t in type_or_seq: if _isinstance(obj, t): return 1 return 0 __all__.append("isinstance") if list is type([]): class NodeList(list): __slots__ = () def item(self, index): if 0 <= index < len(self): return self[index] def _get_length(self): return len(self) def _set_length(self, value): raise xml.dom.NoModificationAllowedErr( "attempt to modify read-only attribute 'length'") length = property(_get_length, _set_length, doc="The number of nodes in the NodeList.") def __getstate__(self): return list(self) def __setstate__(self, state): self[:] = state class EmptyNodeList(tuple): __slots__ = () def __add__(self, other): NL = NodeList() NL.extend(other) return NL def __radd__(self, other): NL = NodeList() NL.extend(other) return NL def item(self, index): return None def _get_length(self): return 0 def _set_length(self, value): raise xml.dom.NoModificationAllowedErr( "attempt to modify read-only attribute 'length'") length = property(_get_length, _set_length, doc="The number of nodes in the NodeList.") else: def NodeList(): return [] def EmptyNodeList(): return [] try: property except NameError: def defproperty(klass, name, doc): # taken care of by the base __getattr__() pass class GetattrMagic: def __getattr__(self, key): if key.startswith("_"): raise AttributeError, key try: get = getattr(self, "_get_" + key) except AttributeError: raise AttributeError, key return get() class NewStyle: pass else: def defproperty(klass, name, doc): get = getattr(klass, ("_get_" + name)).im_func def set(self, value, name=name): raise xml.dom.NoModificationAllowedErr( "attempt to modify read-only attribute " + repr(name)) assert not hasattr(klass, "_set_" + name), \ "expected not to find _set_" + name prop = property(get, set, doc=doc) setattr(klass, name, prop) class GetattrMagic: pass NewStyle = object From loewis@users.sourceforge.net Sat Jan 25 15:28:31 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 07:28:31 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/dom minidom.py,1.48,1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory sc8-pr-cvs1:/tmp/cvs-serv8551 Modified Files: minidom.py Log Message: Merge with PyXML 1.80: Basic minidom changes to support the new higher-performance builder, as described: http://mail.python.org/pipermail/xml-sig/2002-February/007217.html Use True/False where appropriate. isSupported(): Implemented from DOM Level 2. Support a variety of things from the DOM Level 3 draft, integrate with the xml.dom.xmlbuilder module for the new Document and DOMImplementation methods. Support the NODE_CLONED callback for the UserDataHandler set using setUserData(). Add Entity and Notation nodes to minidom. Add __getitem__() to ReadOnlySequentialNamedNodeMap to match NamedNodeMap. TupleType was used without being defined; rename to _TupleType and define. Add magic so that instances of the NamedNodeMap (and its read-only cousin) take a bit less memory in the new-style world of Python 2.2/2.3. Now, the assignments to __slots__ actually work. ;-) Add support for the Text.wholeText attribute. Document.createCDATASection(): Do not pass unsupported arg to CDATASection constructor. Implemented Text.replaceWholeText(). Updated minidom interfaces to work better with current 4Suite XPath and Xslt. * Added childNodes to class Attr * Added localName and prefix to all Nodes * Added specified on class Attr * Changed DOMImplementation.createDocument to all creating a document with no document element and a Null doctype * Changed CharacterData__setattr__ to keep nodeValue and data in synch * fixed typo of ownerDoc in createDocumentFragment * Changed Comment to inherit from CharacterData * Allowed mutation of name on PIs * Added importNode and rewrote cloneNode so both use same code base * Changed EmptyNodeList to be a list not a tuple Use a table-driven DOMImplementation.hasFeature(). Shorten lines longer than 80 characters. Rename CloneNode to _clone_node (better naming consistency within the module). When defining localName as a property, the defproperty() call is needed for each class that defined _get_localName(), otherwise only the first version is used for Python 2.2 and newer. Node.insertBefore(): When the reference node is not found, raise the exception defined by the DOM specification. Attr._set_value(): Added setter that does the right thing. Childless.removeChild(): Raise the exception defined by the specification, even though it seem less than intuitive. _clone_node(): Access nodeType constants so we actually find them. Add support for document fragments. Node.removeChild(), .replaceChild(): Fix exception raised when a reference node is not found. CharacterData._set_data(): Update the nodeValue attribute as well as the data attribute. Entity.attributes, .childNodes: Added these attributes. Document.removeChild(): Raise the right exception when the node being removed is not a child of this node. Element.removeAttributeNode(): Raise the right exception when the node isn't present on this element. Don't unlink the node unless it is present. Added support for the following methods and accessors: Node._get_childNodes(), Attr._get_specified(), Attr._set_prefix(), NamedNodeMap.has_key(), .getNamedItem(), .getNamedItemNS(), .removeNamedItem(), .removeNamedItemNS(), ProcessingInstruction._get_data(), ._get_target(), ._set_data(), ._set_target(), CharacterData.__len__(), Document.getElementById(). Add many more of the _get_*() accessors. Convert internal helpers to use a more consistent naming convention. Remove unused definition of _nssplit(); there can be only one! Move the Identified mixin up so it can be used by one more class. Remove comment about NamedNodeMap.__getitem__(); the API won't be changing now! Way too late for that. Preliminary support for getElementById() for DOMs built with xml.dom.expatbuilder. Not necessarily very efficient, but it works, and is still fast for Document instances that do not have the ID information. DOMImplementation.createDocument(): Don't forget to add the DocumentType node to the tree. This appearantly was lost in the previous release. DocumentType.writexml(): New function. Implement the final determination on the behaviors of importNode() and cloneNode() with regard to Document and DocumentType nodes. When cloning and importing, call the UserDataHandler with the right operation, not just blindly use NODE_CLONED. parse(), parseString(): When called with parser=None, use xml.dom.expatbuilder instead of xml.dom.pulldom, to get a performance boost (the main point of expatbuilder). Fix for calling parse / parseString with a given parser instance; the else-paths were ignored when refactoring the function signatures; pychecker found that error instantly, BTW (hint, hint) Added pickle support for NamedNodeMap, ReadOnlySequentialNamedNodeMap, and ElementInfo. Closes SF bug #609641. In _clone_node for elements, fixed arguments for getAttributeNodeNS At least make sure the DOM API won't allow you to modify the child node list of an entity node (since entity ndoes are supposed to be readonly). Add support for the DOM Level 3 (draft) DOMImplementationSource interface to the xml.dom and xml.dom.minidom modules. Note API issue: the draft spec says to return null when there is no suitable implementation, while the Python getDOMImplementation() function raises ImportError (minor). Implement the DOM Level 3 Attr.isId property. Refactor the lookup of the ElementInfo objects. Implement the schemaType attribute for Element and Attr nodes. Defined by the (draft) DOM Level 3 specification. getElementById(): Support caching of IDs found. This implementation is sufficient for DOM Level 2 compliance, but additional changes will be needed to support the setIdAttribute() and setIdAttributeNS() methods in DOM Level 3. Add support for Text.isWhitespaceInElementContent (draft Level 3). NamedNodeMap.removeNamedItem(), .removeNamedItemNS(): Pass the new tests: Return the removed node, or raise NotFoundErr if there was no matching node. When changing attributes via a NamedNodeMap, update the ID-cache appropriately. Added support for the DOM Level 3 (draft) Element.setIdAttribute*() methods. setAttributeNode(): Be more careful about not calling removeAttributeNode() twice for a single node. Do more to avoid creating new Attr nodes, so that attributes do not lose their ID-ness when set using setIdAttribute*(). Work harder to avoid calls to Attr.__setattr__() and CharacterData.__setattr__(). Attr.unlink(): Implement everything directly instead of calling to the base class, which does several things that aren't needed for Attr nodes. Change some remaining assignments that caused __setattr__() to be called when it can be avoided. expatbuilder can now perform DOM construction without __setattr__() interferance in common cases. Remove unused _make_parent_nodes logic. Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -d -r1.48 -r1.49 *** minidom.py 2 Jul 2002 17:27:06 -0000 1.48 --- minidom.py 25 Jan 2003 15:28:29 -0000 1.49 *************** *** 15,68 **** """ - from xml.dom import HierarchyRequestErr, EMPTY_NAMESPACE - - # localize the types, and allow support for Unicode values if available: - import types - _TupleType = types.TupleType - try: - _StringTypes = (types.StringType, types.UnicodeType) - except AttributeError: [...2421 lines suppressed...] ! {'parser': parser, 'bufsize': bufsize}) ! def parseString(string, parser=None): """Parse a file into a DOM from a string.""" ! if parser is None: ! from xml.dom import expatbuilder ! return expatbuilder.parseString(string) ! else: ! from xml.dom import pulldom ! return _do_pulldom_parse(pulldom.parseString, (string,), ! {'parser': parser}) ! def getDOMImplementation(features=None): ! if features: ! if isinstance(features, StringTypes): ! features = domreg._parse_feature_string(features) ! for f, v in features: ! if not Document.implementation.hasFeature(f, v): ! return None return Document.implementation From loewis@users.sourceforge.net Sat Jan 25 15:29:58 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 07:29:58 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/dom xmlbuilder.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory sc8-pr-cvs1:/tmp/cvs-serv9664 Added Files: xmlbuilder.py Log Message: Import from PyXML 1.10. --- NEW FILE: xmlbuilder.py --- """Implementation of the DOM Level 3 'LS-Load' feature.""" import copy import xml.dom from xml.dom.minicompat import * from xml.dom.NodeFilter import NodeFilter __all__ = ["DOMBuilder", "DOMEntityResolver", "DOMInputSource"] class Options: """Features object that has variables set for each DOMBuilder feature. The DOMBuilder class uses an instance of this class to pass settings to the ExpatBuilder class. """ # Note that the DOMBuilder class in LoadSave constrains which of these # values can be set using the DOM Level 3 LoadSave feature. namespaces = 1 namespace_declarations = True validation = False external_parameter_entities = True external_general_entities = True external_dtd_subset = True validate_if_schema = False validate = False datatype_normalization = False create_entity_ref_nodes = True entities = True whitespace_in_element_content = True cdata_sections = True comments = True charset_overrides_xml_encoding = True infoset = False supported_mediatypes_only = False errorHandler = None filter = None class DOMBuilder: entityResolver = None errorHandler = None filter = None ACTION_REPLACE = 1 ACTION_APPEND_AS_CHILDREN = 2 ACTION_INSERT_AFTER = 3 ACTION_INSERT_BEFORE = 4 _legal_actions = (ACTION_REPLACE, ACTION_APPEND_AS_CHILDREN, ACTION_INSERT_AFTER, ACTION_INSERT_BEFORE) def __init__(self): self._options = Options() def _get_entityResolver(self): return self.entityResolver def _set_entityResolver(self, entityResolver): self.entityResolver = entityResolver def _get_errorHandler(self): return self.errorHandler def _set_errorHandler(self, errorHandler): self.errorHandler = errorHandler def _get_filter(self): return self.filter def _set_filter(self, filter): self.filter = filter def setFeature(self, name, state): if self.supportsFeature(name): state = state and 1 or 0 try: settings = self._settings[(_name_xform(name), state)] except KeyError: raise xml.dom.NotSupportedErr( "unsupported feature: " + `name`) else: for name, value in settings: setattr(self._options, name, value) else: raise xml.dom.NotFoundErr("unknown feature: " + repr(name)) def supportsFeature(self, name): return hasattr(self._options, _name_xform(name)) def canSetFeature(self, name, state): key = (_name_xform(name), state and 1 or 0) return self._settings.has_key(key) # This dictionary maps from (feature,value) to a list of # (option,value) pairs that should be set on the Options object. # If a (feature,value) setting is not in this dictionary, it is # not supported by the DOMBuilder. # _settings = { ("namespace_declarations", 0): [ ("namespace_declarations", 0)], ("namespace_declarations", 1): [ ("namespace_declarations", 1)], ("validation", 0): [ ("validation", 0)], ("external_general_entities", 0): [ ("external_general_entities", 0)], ("external_general_entities", 1): [ ("external_general_entities", 1)], ("external_parameter_entities", 0): [ ("external_parameter_entities", 0)], ("external_parameter_entities", 1): [ ("external_parameter_entities", 1)], ("validate_if_schema", 0): [ ("validate_if_schema", 0)], ("create_entity_ref_nodes", 0): [ ("create_entity_ref_nodes", 0)], ("create_entity_ref_nodes", 1): [ ("create_entity_ref_nodes", 1)], ("entities", 0): [ ("create_entity_ref_nodes", 0), ("entities", 0)], ("entities", 1): [ ("entities", 1)], ("whitespace_in_element_content", 0): [ ("whitespace_in_element_content", 0)], ("whitespace_in_element_content", 1): [ ("whitespace_in_element_content", 1)], ("cdata_sections", 0): [ ("cdata_sections", 0)], ("cdata_sections", 1): [ ("cdata_sections", 1)], ("comments", 0): [ ("comments", 0)], ("comments", 1): [ ("comments", 1)], ("charset_overrides_xml_encoding", 0): [ ("charset_overrides_xml_encoding", 0)], ("charset_overrides_xml_encoding", 1): [ ("charset_overrides_xml_encoding", 1)], ("infoset", 0): [], ("infoset", 1): [ ("namespace_declarations", 0), ("validate_if_schema", 0), ("create_entity_ref_nodes", 0), ("entities", 0), ("cdata_sections", 0), ("datatype_normalization", 1), ("whitespace_in_element_content", 1), ("comments", 1), ("charset_overrides_xml_encoding", 1)], ("supported_mediatypes_only", 0): [ ("supported_mediatypes_only", 0)], ("namespaces", 0): [ ("namespaces", 0)], ("namespaces", 1): [ ("namespaces", 1)], } def getFeature(self, name): xname = _name_xform(name) try: return getattr(self._options, xname) except AttributeError: if name == "infoset": options = self._options return (options.datatype_normalization and options.whitespace_in_element_content and options.comments and options.charset_overrides_xml_encoding and not (options.namespace_declarations or options.validate_if_schema or options.create_entity_ref_nodes or options.entities or options.cdata_sections)) raise xml.dom.NotFoundErr("feature %s not known" % repr(name)) def parseURI(self, uri): if self.entityResolver: input = self.entityResolver.resolveEntity(None, uri) else: input = DOMEntityResolver().resolveEntity(None, uri) return self.parse(input) def parse(self, input): options = copy.copy(self._options) options.filter = self.filter options.errorHandler = self.errorHandler fp = input.byteStream if fp is None and options.systemId: import urllib2 fp = urllib2.urlopen(input.systemId) return self._parse_bytestream(fp, options) def parseWithContext(self, input, cnode, action): if action not in self._legal_actions: raise ValueError("not a legal action") raise NotImplementedError("Haven't written this yet...") def _parse_bytestream(self, stream, options): import xml.dom.expatbuilder builder = xml.dom.expatbuilder.makeBuilder(options) return builder.parseFile(stream) def _name_xform(name): return name.lower().replace('-', '_') class DOMEntityResolver(NewStyle): __slots__ = '_opener', def resolveEntity(self, publicId, systemId): assert systemId is not None source = DOMInputSource() source.publicId = publicId source.systemId = systemId source.byteStream = self._get_opener().open(systemId) # determine the encoding if the transport provided it source.encoding = self._guess_media_encoding(source) # determine the base URI is we can import posixpath, urlparse parts = urlparse.urlparse(systemId) scheme, netloc, path, params, query, fragment = parts # XXX should we check the scheme here as well? if path and not path.endswith("/"): path = posixpath.dirname(path) + "/" parts = scheme, netloc, path, params, query, fragment source.baseURI = urlparse.urlunparse(parts) return source def _get_opener(self): try: return self._opener except AttributeError: self._opener = self._create_opener() return self._opener def _create_opener(self): import urllib2 return urllib2.build_opener() def _guess_media_encoding(self, source): info = source.byteStream.info() if info.has_key("Content-Type"): for param in info.getplist(): if param.startswith("charset="): return param.split("=", 1)[1].lower() class DOMInputSource(NewStyle): __slots__ = ('byteStream', 'characterStream', 'stringData', 'encoding', 'publicId', 'systemId', 'baseURI') def __init__(self): self.byteStream = None self.characterStream = None self.stringData = None self.encoding = None self.publicId = None self.systemId = None self.baseURI = None def _get_byteStream(self): return self.byteStream def _set_byteStream(self, byteStream): self.byteStream = byteStream def _get_characterStream(self): return self.characterStream def _set_characterStream(self, characterStream): self.characterStream = characterStream def _get_stringData(self): return self.stringData def _set_stringData(self, data): self.stringData = data def _get_encoding(self): return self.encoding def _set_encoding(self, encoding): self.encoding = encoding def _get_publicId(self): return self.publicId def _set_publicId(self, publicId): self.publicId = publicId def _get_systemId(self): return self.systemId def _set_systemId(self, systemId): self.systemId = systemId def _get_baseURI(self): return self.baseURI def _set_baseURI(self, uri): self.baseURI = uri class DOMBuilderFilter: """Element filter which can be used to tailor construction of a DOM instance. """ # There's really no need for this class; concrete implementations # should just implement the endElement() and startElement() # methods as appropriate. Using this makes it easy to only # implement one of them. FILTER_ACCEPT = 1 FILTER_REJECT = 2 FILTER_SKIP = 3 FILTER_INTERRUPT = 4 whatToShow = NodeFilter.SHOW_ALL def _get_whatToShow(self): return self.whatToShow def acceptNode(self, element): return self.FILTER_ACCEPT def startContainer(self, element): return self.FILTER_ACCEPT del NodeFilter class DocumentLS: """Mixin to create documents that conform to the load/save spec.""" async = False def _get_async(self): return False def _set_async(self, async): if async: raise xml.dom.NotSupportedErr( "asynchronous document loading is not supported") def abort(self): # What does it mean to "clear" a document? Does the # documentElement disappear? raise NotImplementedError( "haven't figured out what this means yet") def load(self, uri): raise NotImplementedError("haven't written this yet") def loadXML(self, source): raise NotImplementedError("haven't written this yet") def saveXML(self, snode): if snode is None: snode = self elif snode.ownerDocument is not self: raise xml.dom.WrongDocumentErr() return snode.toxml() class DOMImplementationLS: MODE_SYNCHRONOUS = 1 MODE_ASYNCHRONOUS = 2 def createDOMBuilder(self, mode, schemaType): if schemaType is not None: raise xml.dom.NotSupportedErr( "schemaType not yet supported") if mode == self.MODE_SYNCHRONOUS: return DOMBuilder() if mode == self.MODE_ASYNCHRONOUS: raise xml.dom.NotSupportedErr( "asynchronous builders are not supported") raise ValueError("unknown value for mode") def createDOMWriter(self): raise NotImplementedError( "the writer interface hasn't been written yet!") def createDOMInputSource(self): return DOMInputSource() From loewis@users.sourceforge.net Sat Jan 25 16:51:52 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 08:51:52 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/sax expatreader.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/sax In directory sc8-pr-cvs1:/tmp/cvs-serv28717 Modified Files: expatreader.py Log Message: Merge with PyXML 1.28: Wrap a lot of long lines. Clean up a handler for expat.error. If a lexical handler is set, make sure we call the startDTD() and endDTD(). If the lexical handler is unset (by setting it to None), remove the handlers from the underlying pyexpat parser object. Closes SF bug #485584. In namespaces mode, make sure we set up the qnames dictionary correctly for the AttributesNSImpl instance passed to the start-element-handler. Closes SF bug #563399. Support skippedEntity. Fixes #665486. Index: expatreader.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/sax/expatreader.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** expatreader.py 30 Jun 2002 07:27:30 -0000 1.30 --- expatreader.py 25 Jan 2003 16:51:50 -0000 1.31 *************** *** 1,4 **** """ ! SAX driver for the Pyexpat C module. This driver works with pyexpat.__version__ == '2.22'. """ --- 1,4 ---- """ ! SAX driver for the pyexpat C module. This driver works with pyexpat.__version__ == '2.22'. """ *************** *** 83,87 **** class ExpatParser(xmlreader.IncrementalParser, xmlreader.Locator): ! "SAX driver for the Pyexpat C module." def __init__(self, namespaceHandling=0, bufsize=2**16-20): --- 83,87 ---- class ExpatParser(xmlreader.IncrementalParser, xmlreader.Locator): ! """SAX driver for the pyexpat C module.""" def __init__(self, namespaceHandling=0, bufsize=2**16-20): *************** *** 111,115 **** self._parser.SetBase(source.getSystemId()) ! # Redefined setContentHandle to allow changing handlers during parsing def setContentHandler(self, handler): --- 111,115 ---- self._parser.SetBase(source.getSystemId()) ! # Redefined setContentHandler to allow changing handlers during parsing def setContentHandler(self, handler): *************** *** 146,159 **** elif name == feature_validation: if state: ! raise SAXNotSupportedException("expat does not support validation") elif name == feature_external_pes: if state: ! raise SAXNotSupportedException("expat does not read external parameter entities") elif name == feature_namespace_prefixes: if state: ! raise SAXNotSupportedException("expat does not report namespace prefixes") else: ! raise SAXNotRecognizedException("Feature '%s' not recognized" % ! name) def getProperty(self, name): --- 146,162 ---- elif name == feature_validation: if state: ! raise SAXNotSupportedException( ! "expat does not support validation") elif name == feature_external_pes: if state: ! raise SAXNotSupportedException( ! "expat does not read external parameter entities") elif name == feature_namespace_prefixes: if state: ! raise SAXNotSupportedException( ! "expat does not report namespace prefixes") else: ! raise SAXNotRecognizedException( ! "Feature '%s' not recognized" % name) def getProperty(self, name): *************** *** 167,173 **** return self._parser.GetInputContext() else: ! raise SAXNotRecognizedException("This version of expat does not support getting the XML string") else: ! raise SAXNotSupportedException("XML string cannot be returned when not parsing") raise SAXNotRecognizedException("Property '%s' not recognized" % name) --- 170,179 ---- return self._parser.GetInputContext() else: ! raise SAXNotRecognizedException( ! "This version of expat does not support getting" ! " the XML string") else: ! raise SAXNotSupportedException( ! "XML string cannot be returned when not parsing") raise SAXNotRecognizedException("Property '%s' not recognized" % name) *************** *** 200,206 **** # except when invoked from close. self._parser.Parse(data, isFinal) ! except expat.error: ! error_code = self._parser.ErrorCode ! exc = SAXParseException(expat.ErrorString(error_code), None, self) # FIXME: when to invoke error()? self._err_handler.fatalError(exc) --- 206,211 ---- # except when invoked from close. self._parser.Parse(data, isFinal) ! except expat.error, e: ! exc = SAXParseException(expat.ErrorString(e.code), e, self) # FIXME: when to invoke error()? self._err_handler.fatalError(exc) *************** *** 222,232 **** def _reset_lex_handler_prop(self): ! self._parser.CommentHandler = self._lex_handler_prop.comment ! self._parser.StartCdataSectionHandler = self._lex_handler_prop.startCDATA ! self._parser.EndCdataSectionHandler = self._lex_handler_prop.endCDATA def reset(self): if self._namespaces: ! self._parser = expat.ParserCreate(None, " ", intern = self._interning) self._parser.StartElementHandler = self.start_element_ns self._parser.EndElementHandler = self.end_element_ns --- 227,250 ---- def _reset_lex_handler_prop(self): ! lex = self._lex_handler_prop ! parser = self._parser ! if lex is None: ! parser.CommentHandler = None ! parser.StartCdataSectionHandler = None ! parser.EndCdataSectionHandler = None ! parser.StartDoctypeDeclHandler = None ! parser.EndDoctypeDeclHandler = None ! else: ! parser.CommentHandler = lex.comment ! parser.StartCdataSectionHandler = lex.startCDATA ! parser.EndCdataSectionHandler = lex.endCDATA ! parser.StartDoctypeDeclHandler = self.start_doctype_decl ! parser.EndDoctypeDeclHandler = lex.endDTD def reset(self): if self._namespaces: ! self._parser = expat.ParserCreate(None, " ", ! intern=self._interning) ! self._parser.namespace_prefixes = 1 self._parser.StartElementHandler = self.start_element_ns self._parser.EndElementHandler = self.end_element_ns *************** *** 249,253 **** # self._parser.NotStandaloneHandler = self._parser.ExternalEntityRefHandler = self.external_entity_ref ! self._parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) self._parsing = 0 --- 267,277 ---- # self._parser.NotStandaloneHandler = self._parser.ExternalEntityRefHandler = self.external_entity_ref ! try: ! self._parser.SkippedEntityHandler = self.skipped_entity_handler ! except AttributeError: ! # This pyexpat does not support SkippedEntity ! pass ! self._parser.SetParamEntityParsing( ! expat.XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) self._parsing = 0 *************** *** 282,301 **** pair = name.split() if len(pair) == 1: pair = (None, name) else: pair = tuple(pair) newattrs = {} for (aname, value) in attrs.items(): ! apair = aname.split() ! if len(apair) == 1: apair = (None, aname) else: ! apair = tuple(apair) newattrs[apair] = value self._cont_handler.startElementNS(pair, None, ! AttributesNSImpl(newattrs, {})) def end_element_ns(self, name): --- 306,339 ---- pair = name.split() if len(pair) == 1: + # no namespace pair = (None, name) + elif len(pair) == 3: + pair = pair[0], pair[1] else: + # default namespace pair = tuple(pair) newattrs = {} + qnames = {} for (aname, value) in attrs.items(): ! parts = aname.split() ! length = len(parts) ! if length == 1: ! # no namespace ! qname = aname apair = (None, aname) + elif length == 3: + qname = "%s:%s" % (parts[2], parts[1]) + apair = parts[0], parts[1] else: ! # default namespace ! qname = parts[1] ! apair = tuple(parts) newattrs[apair] = value + qnames[apair] = qname self._cont_handler.startElementNS(pair, None, ! AttributesNSImpl(newattrs, qnames)) def end_element_ns(self, name): *************** *** 303,306 **** --- 341,346 ---- if len(pair) == 1: pair = (None, name) + elif len(pair) == 3: + pair = pair[0], pair[1] else: pair = tuple(pair) *************** *** 322,325 **** --- 362,368 ---- self._cont_handler.endPrefixMapping(prefix) + def start_doctype_decl(self, name, pubid, sysid, has_internal_subset): + self._lex_handler_prop.startDTD(name, pubid, sysid) + def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name): self._dtd_handler.unparsedEntityDecl(name, pubid, sysid, notation_name) *************** *** 349,352 **** --- 392,401 ---- del self._entity_stack[-1] return 1 + + def skipped_entity_handler(self, name, is_pe): + if is_pe: + # The SAX spec requires to report skipped PEs with a '%' + name = '%'+name + self._cont_handler.skippedEntity(name) # --- From loewis@users.sourceforge.net Sat Jan 25 17:07:06 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 09:07:06 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/dom NodeFilter.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory sc8-pr-cvs1:/tmp/cvs-serv6700 Added Files: NodeFilter.py Log Message: Import NodeFilter from DOM2 Traversal/Range. --- NEW FILE: NodeFilter.py --- # This is the Python mapping for interface NodeFilter from # DOM2-Traversal-Range. It contains only constants. class NodeFilter: """ This is the DOM2 NodeFilter interface. It contains only constants. """ FILTER_ACCEPT = 1 FILTER_REJECT = 2 FILTER_SKIP = 3 SHOW_ALL = 0xFFFFFFFFL SHOW_ELEMENT = 0x00000001 SHOW_ATTRIBUTE = 0x00000002 SHOW_TEXT = 0x00000004 SHOW_CDATA_SECTION = 0x00000008 SHOW_ENTITY_REFERENCE = 0x00000010 SHOW_ENTITY = 0x00000020 SHOW_PROCESSING_INSTRUCTION = 0x00000040 SHOW_COMMENT = 0x00000080 SHOW_DOCUMENT = 0x00000100 SHOW_DOCUMENT_TYPE = 0x00000200 SHOW_DOCUMENT_FRAGMENT = 0x00000400 SHOW_NOTATION = 0x00000800 def acceptNode(self, node): raise NotImplementedError From loewis@users.sourceforge.net Sat Jan 25 17:11:09 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 09:11:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/dom __init__.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory sc8-pr-cvs1:/tmp/cvs-serv9518 Modified Files: __init__.py Log Message: Import UserDataHandler from PyXML. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/__init__.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** __init__.py 9 Aug 2002 14:57:55 -0000 1.11 --- __init__.py 25 Jan 2003 17:11:07 -0000 1.12 *************** *** 121,124 **** --- 121,133 ---- code = VALIDATION_ERR + class UserDataHandler: + """Class giving the operation constants for UserDataHandler.handle().""" + + # Based on DOM Level 3 (WD 9 April 2002) + + NODE_CLONED = 1 + NODE_IMPORTED = 2 + NODE_DELETED = 3 + NODE_RENAMED = 4 XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" From rhettinger@users.sourceforge.net Sat Jan 25 20:15:38 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 25 Jan 2003 12:15:38 -0800 Subject: [Python-checkins] python/nondist/peps pep-0290.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv8654 Modified Files: pep-0290.txt Log Message: Added migration issue for booleans. Index: pep-0290.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0290.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0290.txt 15 Jan 2003 01:55:12 -0000 1.5 --- pep-0290.txt 25 Jan 2003 20:15:35 -0000 1.6 *************** *** 60,63 **** --- 60,96 ---- + Migration Issues + ================ + + Comparison Operators Not a Shortcut for Producing 0 or 1 + -------------------------------------------------------- + + Prior to Python 2.3, comparison operations returned 0 or 1 rather + than True or False. Some code may have used this as a shortcut for + producing zero or one in places where their boolean counterparts are + not appropriate. For example:: + + def identity(m=1): + """Create and m-by-m identity matrix""" + return [[i==j for i in range(m)] for j in range(m)] + + In Python 2.2, a call to identity(2) would produce:: + + [[1, 0], [0, 1]] + + In Python 2.3, the same call would produce:: + + [[True, False], [False, True]] + + Since booleans are a subclass of integers, the matrix would continue + to calculate normally, but it will not print as expected. The list + comprehension should be changed to read:: + + return [[i==j and 1 or 0 for i in range(m)] for j in range(m)] + + There are similiar concerns when storing data to be used by other + applications which may expect a number instead of True or False. + + Modernization Procedures ======================== From rhettinger@users.sourceforge.net Sat Jan 25 20:21:32 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 25 Jan 2003 12:21:32 -0800 Subject: [Python-checkins] python/nondist/peps pep-0290.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv11269 Modified Files: pep-0290.txt Log Message: Jp Calderone pointed out that most Python library modules were updated to support __iter__ and __contains__. * Removed shelve as a specific counter-example. * Changed the wording to "may not" so that user and third party modules are considered. Index: pep-0290.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0290.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0290.txt 25 Jan 2003 20:15:35 -0000 1.6 --- pep-0290.txt 25 Jan 2003 20:21:30 -0000 1.7 *************** *** 136,140 **** Contra-indications: ! 1. Some dictionary-like objects like ``shelve`` do not define a ``__contains__()`` method:: --- 136,140 ---- Contra-indications: ! 1. Some dictionary-like objects may not define a ``__contains__()`` method:: *************** *** 167,171 **** def getids(): return d.keys() ! 2. Some dictionary-like objects like ``shelve`` do not define ``iter`` methods:: --- 167,171 ---- def getids(): return d.keys() ! 2. Some dictionary-like objects may not define ``iter`` methods:: From just@letterror.com Sat Jan 25 20:24:26 2003 From: just@letterror.com (Just van Rossum) Date: Sat, 25 Jan 2003 21:24:26 +0100 Subject: [Python-checkins] python/nondist/peps pep-0290.txt,1.5,1.6 In-Reply-To: Message-ID: rhettinger@users.sourceforge.net wrote: > + Since booleans are a subclass of integers, the matrix would continue > + to calculate normally, but it will not print as expected. The list > + comprehension should be changed to read:: > + > + return [[i==j and 1 or 0 for i in range(m)] for j in range(m)] Ugh, I don't think we should recommend the and/or shortcut idiom too much, if at all. In this particular case, I think the following is much clearer: return [[int(i==j) for i in range(m)] for j in range(m)] Just From neal@metaslash.com Sat Jan 25 20:27:33 2003 From: neal@metaslash.com (Neal Norwitz) Date: Sat, 25 Jan 2003 15:27:33 -0500 Subject: [Python-checkins] python/nondist/peps pep-0290.txt,1.5,1.6 In-Reply-To: References: Message-ID: <20030125202733.GB24222@epoch.metaslash.com> > + Prior to Python 2.3, comparison operations returned 0 or 1 rather > + than True or False. Some code may have used this as a shortcut for > + producing zero or one in places where their boolean counterparts are > + not appropriate. For example:: > + > + def identity(m=1): > + """Create and m-by-m identity matrix""" > + return [[i==j for i in range(m)] for j in range(m)] > + > + Since booleans are a subclass of integers, the matrix would continue > + to calculate normally, but it will not print as expected. The list > + comprehension should be changed to read:: > + > + return [[i==j and 1 or 0 for i in range(m)] for j in range(m)] Why not: return [[int(i==j) for i in range(m)] for j in range(m)] In essence, if they want an integer, make it explicit. Same with: print '5 == 3: %s' % (5 == 3) Could become: print '5 == 3: %d' % (5 == 3) If an integer is required. Neal From rhettinger@users.sourceforge.net Sat Jan 25 20:30:04 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 25 Jan 2003 12:30:04 -0800 Subject: [Python-checkins] python/nondist/peps pep-0290.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv17108 Modified Files: pep-0290.txt Log Message: Just pointed out an improvement to the code example. Index: pep-0290.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0290.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pep-0290.txt 25 Jan 2003 20:21:30 -0000 1.7 --- pep-0290.txt 25 Jan 2003 20:30:02 -0000 1.8 *************** *** 87,91 **** comprehension should be changed to read:: ! return [[i==j and 1 or 0 for i in range(m)] for j in range(m)] There are similiar concerns when storing data to be used by other --- 87,91 ---- comprehension should be changed to read:: ! return [[int(i==j) for i in range(m)] for j in range(m)] There are similiar concerns when storing data to be used by other From tim_one@users.sourceforge.net Sat Jan 25 20:57:07 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 12:57:07 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools - New directory Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv1598/pickletools Log Message: Directory /cvsroot/python/python/nondist/sandbox/pickletools added to the repository From tim_one@users.sourceforge.net Sat Jan 25 20:58:55 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 12:58:55 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv2358 Added Files: pickletools.py Log Message: A start at a suite of pickle tools. --- NEW FILE: pickletools.py --- # This is meant to become the basis for several pickle helpers: # # - "Executable documentation". The descriptions are meant to be precise # enough to execute, and the various doc attrs are meant to hold text good # enough so that reference docs could be generated by crawling over the # descriptors. # # - A symbolic pickle disassembler. # # - A pickle verifier -- read a pickle and check it exhaustively for # well-formedness. # Meta-rule: Descriptions are stored in instances of descriptor objects, # with plain constructors. No meta-language is defined from which # descriptors could be constructed. If you want, e.g., XML, write a little # program to generate XML from the objects. # Some pickle opcodes have an argument, following the opcode in the # bytestream. An argument is of a specific type, described by an instance # of ArgumentDescriptor. class ArgumentDescriptor(object): __slots__ = ( # name of descriptor record, also a module global name; a string 'name', # length of argument, in bytes; an int; or None means variable-length 'n', # a function taking a file-like object, reading this kind of argument # from the object at the current position, advancing the current # position by n bytes, and returning the value of the argument 'reader', # human-readable docs for this arg descriptor; a string 'doc', ) def __init__(self, name, n, reader, doc): assert isinstance(name, str) self.name = name assert n is None or (isinstance(n, int) and n >= 0) self.n = n self.reader = reader assert isinstance(doc, str) self.doc = doc from struct import unpack as _unpack def read_uint1(f): """ >>> import StringIO >>> read_uint1(StringIO.StringIO('\\xff')) 255 """ data = f.read(1) if data: return ord(data) raise ValueError("not enough data in stream to read uint1") uint1 = ArgumentDescriptor( name='uint1', n=1, reader=read_uint1, doc="one-byte unsigned integer") def read_uint2(f): """ >>> import StringIO >>> read_uint2(StringIO.StringIO('\\xff\\x00')) 255 >>> read_uint2(StringIO.StringIO('\\xff\\xff')) 65535 """ data = f.read(2) if len(data) == 2: return _unpack(">> import StringIO >>> read_int4(StringIO.StringIO('\\xff\\x00\\x00\\x00')) 255 >>> read_int4(StringIO.StringIO('\\x00\\x00\\x00\\x80')) == -(2**31) True """ data = f.read(4) if len(data) == 4: return _unpack(">> import StringIO >>> read_stringnl(StringIO.StringIO("abcd\\nefg\\n")) 'abcd' >>> read_stringnl(StringIO.StringIO("\\n")) '' >>> read_stringnl(StringIO.StringIO("abcd")) Traceback (most recent call last): ... ValueError: no newline found when trying to read stringnl Embedded escapes are undone in the result. >>> read_stringnl(StringIO.StringIO("a\\\\nb\\x00c\\td\\ne")) 'a\\nb\\x00c\\td' """ data = f.readline() if not data.endswith('\n'): raise ValueError("no newline found when trying to read stringnl") data = data[:-1] # lose the newline # I'm not sure when 'string_escape' was added to the std codecs; it's # crazy not to use it if it's there. return data.decode('string_escape') stringnl = ArgumentDescriptor( name='stringnl', n=None, reader=read_stringnl, doc="""A newline-terminated string. This is a repr-style string, with embedded escapes. """) # Descriptors for pickle opcodes. class OpcodeInfo(object): __slots__ = ( # symbolic name of opcode; a string 'name', # the code used in a bytestream to represent the opcode; a string, # usually one letter 'code', # list of 0 or more argument descriptors 'args', # what the stack looks like before this opcode runs; a list 'stack_before', # what the stack looks like after this opcode runs; a list 'stack_after', # the protocol number in which this opcode was introduced; an int 'proto', # human-readable docs for this opcode; a string 'doc', ) def __init__(self, name, code, args, stack_before, stack_after, proto, doc): assert isinstance(name, str) self.name = name assert isinstance(code, str) self.code = code assert isinstance(args, list) self.args = args assert isinstance(stack_before, list) self.stack_before = stack_before assert isinstance(stack_after, list) self.stack_after = stack_after assert isinstance(proto, int) self.proto = proto assert isinstance(doc, str) self.doc = doc I = OpcodeInfo opcodes = [ I(name='MARK', code='(', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='STOP', code='.', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='POP', code='0', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='POP_MARK', code='1', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='DUP', code='2', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='FLOAT', code='F', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='INT', code='I', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BININT', code='J', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BININT1', code='K', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='LONG', code='L', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BININT2', code='M', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='NONE', code='N', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='PERSID', code='P', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BINPERSID', code='Q', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='REDUCE', code='R', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='STRING', code='S', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BINSTRING', code='T', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='SHORT_BINSTRING', code='U', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='UNICODE', code='V', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BINUNICODE', code='X', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='APPEND', code='a', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BUILD', code='b', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='GLOBAL', code='c', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='DICT', code='d', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='EMPTY_DICT', code='}', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='APPENDS', code='e', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='GET', code='g', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BINGET', code='h', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='INST', code='i', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='LONG_BINGET', code='j', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='LIST', code='l', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='EMPTY_LIST', code=']', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='OBJ', code='o', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='PUT', code='p', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BINPUT', code='q', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='LONG_BINPUT', code='r', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='SETITEM', code='s', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='TUPLE', code='t', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='EMPTY_TUPLE', code=')', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='SETITEMS', code='u', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='BINFLOAT', code='G', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='TRUE', code='I01\n', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), I(name='FALSE', code='I00\n', args=[], stack_before=[], stack_after=[], proto=0, doc="""XXX One-line description goes here. XXX Doc body goes here. """), ] del I # Verify uniqueness of .name and .code members. name2i = {} code2i = {} i = 0 for d in opcodes: if d.name in name2i: raise ValueError("repeated name %r at indices %d and %d" % (d.name, name2i[d.name], i)) if d.code in code2i: raise ValueError("repeated code %r at indices %d and %d" % (d.code, code2i[d.code], i)) name2i[d.name] = i code2i[d.code] = i i += 1 del name2i, code2i, i, d def _test(): import doctest return doctest.testmod() if __name__ == "__main__": _test() From nnorwitz@users.sourceforge.net Sat Jan 25 21:08:32 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sat, 25 Jan 2003 13:08:32 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv8159/Doc/lib Modified Files: libdatetime.tex Log Message: Fix markup Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** libdatetime.tex 24 Jan 2003 22:36:30 -0000 1.40 --- libdatetime.tex 25 Jan 2003 21:08:30 -0000 1.41 *************** *** 570,574 **** \method{fromtimestamp()} may raise \exception{ValueError}, if the timestamp is out of the range of values supported by the platform C ! \cfunction{localtime()} or \cfunction(gmtime()} functions. It's common for this to be restricted to years in 1970 through 2038. Note that on non-POSIX systems that include leap seconds in their --- 570,574 ---- \method{fromtimestamp()} may raise \exception{ValueError}, if the timestamp is out of the range of values supported by the platform C ! \cfunction{localtime()} or \cfunction{gmtime()} functions. It's common for this to be restricted to years in 1970 through 2038. Note that on non-POSIX systems that include leap seconds in their From rhettinger@users.sourceforge.net Sat Jan 25 21:23:01 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 25 Jan 2003 13:23:01 -0800 Subject: [Python-checkins] python/dist/src/Misc cheatsheet,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv16384 Modified Files: cheatsheet Log Message: Part I of an update for Python 2.3. Index: cheatsheet =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/cheatsheet,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cheatsheet 6 Aug 2001 17:43:49 -0000 1.2 --- cheatsheet 25 Jan 2003 21:22:52 -0000 1.3 *************** *** 1,6 **** ! Python 2.0 Quick Reference ! 16 May 2001 upgraded by Richard Gruet and Simon Brunning for Python 2.0 2000/07/18 upgraded by Richard Gruet, rgruet@intraware.com for Python 1.5.2 --- 1,6 ---- ! Python 2.3 Quick Reference + 25 Jan 2003 upgraded by Raymond Hettinger for Python 2.3 16 May 2001 upgraded by Richard Gruet and Simon Brunning for Python 2.0 2000/07/18 upgraded by Richard Gruet, rgruet@intraware.com for Python 1.5.2 *************** *** 20,49 **** Python/ newsgroup: comp.lang.python Help desk: help@python.org ! Resources: http://starship.python.net/ and http://www.vex.net/parnassus/ Full documentation: http://www.python.org/doc/ ! An excellent Python reference book: Python Essential Reference by David Beazley ! (New Riders) ! ! ! Contents ! ! * Invocation Options ! * Environment Variables ! * Lexical Entities : keywords, identifiers, strings, numbers, sequences, ! dictionaries, operators ! * Basic Types And Their Operations ! * Advanced Types ! * Statements ! * Built In Functions ! * Built In Exceptions ! * Standard methods & operators redefinition in user-created Classes ! * Special informative state attributes for some types ! * Important Modules : sys, os, posix, posixpath, shutil, time, string, re, ! math, getopt ! * List of modules In base distribution ! * Workspace Exploration And Idiom Hints ! * Python Mode for Emacs ! * The Python Debugger ! --- 20,31 ---- Python/ newsgroup: comp.lang.python Help desk: help@python.org ! Resources: http://starship.python.net/ ! http://www.vex.net/parnassus/ ! http://aspn.activestate.com/ASPN/Cookbook/Python ! FAQ: http://www.python.org/cgi-bin/faqw.py Full documentation: http://www.python.org/doc/ ! Excellent reference books: ! Python Essential Reference by David Beazley (New Riders) ! Python Pocket Reference by Mark Lutz (O'Reilly) *************** *** 54,69 **** Invocation Options Option Effect -d Outputs parser debugging information (also PYTHONDEBUG=x) -i Inspect interactively after running script (also PYTHONINSPECT=x) and force prompts, even if stdin appears not to be a terminal ! -O Optimize generated bytecode (set __debug__ = 0 =>s suppresses asserts) -S Don't perform 'import site' on initialization -t Issue warnings about inconsistent tab usage (-tt: issue errors) -u Unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x). - -U Force Python to interpret all string literals as Unicode literals. -v Verbose (trace import statements) (also PYTHONVERBOSE=x) -x Skip first line of source, allowing use of non-unix Forms of #!cmd - [DEL:-X [DEL:Disable class based built-in exceptions (for backward - :DEL] compatibility management of exceptions):DEL] -? Help! -c Specify the command to execute (see next section). This terminates the --- 36,54 ---- Invocation Options Option Effect + -c cmd program passed in as string (terminates option list) -d Outputs parser debugging information (also PYTHONDEBUG=x) + -E ignore environment variables (such as PYTHONPATH) + -h print this help message and exit -i Inspect interactively after running script (also PYTHONINSPECT=x) and force prompts, even if stdin appears not to be a terminal ! -O optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x) ! -OO remove doc-strings in addition to the -O optimizations ! -Q arg division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew -S Don't perform 'import site' on initialization -t Issue warnings about inconsistent tab usage (-tt: issue errors) -u Unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x). -v Verbose (trace import statements) (also PYTHONVERBOSE=x) + -W arg : warning control (arg is action:message:category:module:lineno) -x Skip first line of source, allowing use of non-unix Forms of #!cmd -? Help! -c Specify the command to execute (see next section). This terminates the *************** *** 116,120 **** break else global not try class except if or while ! continue exec import pass def finally in print --- 101,105 ---- break else global not try class except if or while ! continue exec import pass yield def finally in print *************** *** 175,181 **** Decimal integer: 1234, 1234567890546378940L (or l) ! Octal integer: 0177, 0177777777777777777L (begin with a 0) ! Hex integer: 0xFF, 0XFFFFffffFFFFFFFFFFL (begin with 0x or 0X) ! Long integer (unlimited precision): 1234567890123456L (ends with L or l) Float (double precision): 3.14e-10, .001, 10., 1E3 Complex: 1J, 2+3J, 4+5j (ends with J or j, + separates (float) real and --- 160,166 ---- Decimal integer: 1234, 1234567890546378940L (or l) ! Octal integer: 0177, 0177777777777777777 (begin with a 0) ! Hex integer: 0xFF, 0XFFFFffffFFFFFFFFFF (begin with 0x or 0X) ! Long integer (unlimited precision): 1234567890123456 Float (double precision): 3.14e-10, .001, 10., 1E3 Complex: 1J, 2+3J, 4+5j (ends with J or j, + separates (float) real and *************** *** 207,212 **** Dictionaries (Mappings) ! Dictionary of length 0, 1, 2, etc: ! {} {1 : 'first'} {1 : 'first', 'next': 'second'} Operators and their evaluation order --- 192,201 ---- Dictionaries (Mappings) ! {} # Zero length empty dictionary ! {1 : 'first'} # Dictionary with one (key, value) pair ! {1 : 'first', 'next': 'second'} ! dict([('one',1),('two',2)]) # Construct a dict from an item list ! dict('one'=1, 'two'=2) # Construct a dict using keyword args ! dict.fromkeys(['one', 'keys']) # Construct a dict from a sequence Operators and their evaluation order *************** *** 236,240 **** Alternate names are defined in module operator (e.g. __add__ and add for +) ! Most operators are overridable --- 225,232 ---- Alternate names are defined in module operator (e.g. __add__ and add for +) ! Most operators are overridable. ! ! Many of binary operators support augmented assignment: ! x += 1 # Same as x = x + 1 *************** *** 257,260 **** --- 249,255 ---- Comparison behavior can be overridden for a given class by defining special method __cmp__. + The above comparisions return True or False which are of type bool + (a subclass of int) and behave exactly as 1 or 0 except their type and + that they print as True or False instead of 1 or 0. (1) X < Y < Z < W has expected meaning, unlike C (2) Compare object identities (i.e. id(object)), not object values. *************** *** 345,348 **** --- 340,344 ---- x in s 1 if an item of s is equal to x, else 0 x not in s 0 if an item of s is equal to x, else 1 + for x in s: loops over the sequence s + t the concatenation of s and t s * n, n*s n copies of s concatenated *************** *** 352,355 **** --- 348,352 ---- min(s) smallest item of s max(s) largest item of (s) + iter(s) returns an iterator over s. iterators define __iter__ and next() Notes : *************** *** 371,380 **** del s[i:j] same as s[i:j] = [] s.append(x) same as s[len(s) : len(s)] = [x] - s.extend(x) same as s[len(s):len(s)]= x (5) s.count(x) return number of i's for which s[i] == x s.index(x) return smallest i such that s[i] == x (1) s.insert(i, x) same as s[i:i] = [x] if i >= 0 - s.remove(x) same as del s[s.index(x)] (1) s.pop([i]) same as x = s[i]; del s[i]; return x (4) s.reverse() reverse the items of s in place (3) s.sort([cmpFct]) sort the items of s in place (2), (3) --- 368,377 ---- del s[i:j] same as s[i:j] = [] s.append(x) same as s[len(s) : len(s)] = [x] s.count(x) return number of i's for which s[i] == x + s.extend(x) same as s[len(s):len(s)]= x s.index(x) return smallest i such that s[i] == x (1) s.insert(i, x) same as s[i:i] = [x] if i >= 0 s.pop([i]) same as x = s[i]; del s[i]; return x (4) + s.remove(x) same as del s[s.index(x)] (1) s.reverse() reverse the items of s in place (3) s.sort([cmpFct]) sort the items of s in place (2), (3) *************** *** 392,401 **** They don't return the sorted or reversed list to remind you of this side effect. ! (4) [New 1.5.2] The pop() method is experimental and not supported by ! other mutable sequence types than lists. ! The optional argument i defaults to -1, so that by default the last item is removed and returned. - (5) [New 1.5.2] Experimental ! Raises an exception when x is not a list - object. --- 389,394 ---- They don't return the sorted or reversed list to remind you of this side effect. ! (4) [New 1.5.2] The optional argument i defaults to -1, so that by default the last item is removed and returned. *************** *** 411,420 **** d.clear() remove all items from d d.copy() a shallow copy of d d.has_key(k) 1 if d has key k, else 0 d.items() a copy of d's list of (key, item) pairs (2) d.keys() a copy of d's list of keys (2) d1.update(d2) for k, v in d2.items(): d1[k] = v (3) d.values() a copy of d's list of values (2) ! d.get(k,defaultval) the item of d with key k (4) d.setdefault(k,defaultval) the item of d with key k (5) --- 404,419 ---- d.clear() remove all items from d d.copy() a shallow copy of d + d.get(k,defaultval) the item of d with key k (4) d.has_key(k) 1 if d has key k, else 0 d.items() a copy of d's list of (key, item) pairs (2) + d.iteritems() an iterator over (key, value) pairs (7) + d.iterkeys() an iterator over the keys of d (7) + d.itervalues() an iterator over the values of d (7) d.keys() a copy of d's list of keys (2) d1.update(d2) for k, v in d2.items(): d1[k] = v (3) d.values() a copy of d's list of values (2) ! d.pop(k) remove d[k] and return its value ! d.popitem() remove and return an arbitrary (6) ! (key, item) pair d.setdefault(k,defaultval) the item of d with key k (5) *************** *** 432,435 **** --- 431,437 ---- optional. When not provided and k is not in the map, None is returned and added to map. + (6) Raises a KeyError if the dictionary is emtpy. + (7) While iterating over a dictionary, the values may be updated but + the keys cannot be changed. Operations on strings *************** *** 447,455 **** s.count(sub[ return the number of occurrences of substring sub in (2) ,start[,end]]) string s. s.encode([ return an encoded version of s. Default encoding is the ! encoding[,errors current default string encoding. (3) ! ]]) s.endswith(suffix return true if s ends with the specified suffix, (2) ! [,start[,end]]) otherwise return false. s.expandtabs([ return a copy of s where all tab characters are (4) tabsize]) expanded using spaces. --- 449,460 ---- s.count(sub[ return the number of occurrences of substring sub in (2) ,start[,end]]) string s. + s.decode(([ return a decoded version of s. (3) + encoding + [,errors]]) s.encode([ return an encoded version of s. Default encoding is the ! encoding current default string encoding. (3) ! [,errors]]) s.endswith(suffix return true if s ends with the specified suffix, (2) ! [,start[,end]]) otherwise return False. s.expandtabs([ return a copy of s where all tab characters are (4) tabsize]) expanded using spaces. *************** *** 458,474 **** s.index(sub[ like find(), but raise ValueError when the substring is (2) ,start[,end]]) not found. ! s.isalnum() return true if all characters in s are alphanumeric, (5) ! false otherwise. ! s.isalpha() return true if all characters in s are alphabetic, (5) ! false otherwise. ! s.isdigit() return true if all characters in s are digit (5) ! characters, false otherwise. ! s.islower() return true if all characters in s are lowercase, false (6) otherwise. ! s.isspace() return true if all characters in s are whitespace (5) ! characters, false otherwise. ! s.istitle() return true if string s is a titlecased string, false (7) otherwise. ! s.isupper() return true if all characters in s are uppercase, false (6) otherwise. s.join(seq) return a concatenation of the strings in the sequence --- 463,479 ---- s.index(sub[ like find(), but raise ValueError when the substring is (2) ,start[,end]]) not found. ! s.isalnum() return True if all characters in s are alphanumeric, (5) ! False otherwise. ! s.isalpha() return True if all characters in s are alphabetic, (5) ! False otherwise. ! s.isdigit() return True if all characters in s are digit (5) ! characters, False otherwise. ! s.islower() return True if all characters in s are lowercase, False (6) otherwise. ! s.isspace() return True if all characters in s are whitespace (5) ! characters, False otherwise. ! s.istitle() return True if string s is a titlecased string, False (7) otherwise. ! s.isupper() return True if all characters in s are uppercase, False (6) otherwise. s.join(seq) return a concatenation of the strings in the sequence *************** *** 504,507 **** --- 509,514 ---- [,deletechars]) table. s.upper() return a copy of s converted to uppercase. + s.zfill(width) return a string padded with zeroes on the left and + sliding a minus sign left if necessary. never truncates. Notes : From nnorwitz@users.sourceforge.net Sat Jan 25 21:29:44 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sat, 25 Jan 2003 13:29:44 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib liblogging.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv19927/lib Modified Files: liblogging.tex Log Message: SF #638299, LaTeX documentation for logging package Replace existing doc with new version from Vinay. Fixed markup and wrapped long lines from patch. Needs review. Index: liblogging.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liblogging.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** liblogging.tex 25 Nov 2002 16:01:08 -0000 1.3 --- liblogging.tex 25 Jan 2003 21:29:41 -0000 1.4 *************** *** 7,1139 **** \moduleauthor{Vinay Sajip}{vinay_sajip@red-dove.com} ! \sectionauthor{Skip Montanaro}{skip@pobox.com} \modulesynopsis{Logging module for Python based on PEP 282.} ! There is a need for a standard logging system in Python, as documented in ! {}\pep{282} and enthusiastically endorsed by Guido van Rossum in the ! {}\citetitle[http://www.python.org/doc/essays/pepparade.html]{Parade of the [...2199 lines suppressed...] ! level=NOTSET ! formatter=form09 ! args=('localhost:9022', '/log', 'GET') \end{verbatim} ! Sections which specify formatter configuration are typified by the following. \begin{verbatim} ! [formatter_form01] ! format=F1 %(asctime)s %(levelname)s %(message)s ! datefmt= \end{verbatim} + + The \code{format} entry is the overall format string, and the + \code{datefmt} entry is the \function{strftime()}-compatible date/time format + string. If empty, the package substitutes ISO8601 format date/times, which + is almost equivalent to specifying the date format string "%Y-%m-%d %H:%M:%S". + The ISO8601 format also specifies milliseconds, which are appended to the + result of using the above format string, with a comma separator. An example + time in ISO8601 format is \code{2003-01-23 00:29:50,411}. From loewis@users.sourceforge.net Sat Jan 25 21:39:12 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 13:39:12 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_minidom.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25078 Modified Files: test_minidom.py Log Message: Merge PyXML 1.11-1.26: Re-arrange the imports into "Python normal form." Add test of the getUserData() / setUserData() methods, including the NODE_CLONED callback. Added support for renameNode() and getInterface(). Changed Node.unlink() so an unlinked node is not rendered completely unusable by setting childNodes to None. Element.removeAttributeNode() is slightly less destructive. Added test for the wholeText attribute. Added a test for Text.replaceWholeText(). Fixed to properly create Element in test of user data Rename a local variable so it makes sense when viewed as a sequence. Unlink a few documents when we're done with them. Added tests to define the behavior of the cloneNode() and importNode() mehods, especially in the "difficult" cases of document and document-type nodes. Filled in a few more of the other cloneNode() tests. NodeList.item() does not exist before Python 2.2, since it requires being able to create subtypes of list. Use the subscript syntax instead. Added a test that minidom documents can be pickled and unpickled. Closes SF bug #609641. Fill in an empty test, making sure we get the whitespace right for the data attribute of a processing instruction. Added checks for a few more invariants for processing instructions. testProcessingInstruction(): The length attribute of the NodeList interface is not implemented for Python 2.0, 2.1, so only use len() to test the length. testSchemaType(): New test, testing just the minimum of schemaType support; this is different from the test_xmlbuilder version of the test since it doesn't rely on using a specific builder, and the builders support different levels of DTD support. Add tests for the removeNamedItem() and removeNamedItemNS() methods of the NamedNodeMap instances found on Element nodes. These do not pass; the fix will be committed shortly. Added support for the DOM Level 3 (draft) Element.setIdAttribute*() methods. Do more to avoid creating new Attr nodes, so that attributes do not lose their ID-ness when set using setIdAttribute*(). Index: test_minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_minidom.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** test_minidom.py 12 Sep 2002 17:03:02 -0000 1.36 --- test_minidom.py 25 Jan 2003 21:39:09 -0000 1.37 *************** *** 24,29 **** raise Exception - Node._debug = 1 - def testParseFromFile(): from StringIO import StringIO --- 24,27 ---- *************** *** 284,288 **** node = child.getAttributeNode("spam") child.removeAttributeNode(node) ! confirm(len(child.attributes) == 0) dom.unlink() --- 282,287 ---- node = child.getAttributeNode("spam") child.removeAttributeNode(node) ! confirm(len(child.attributes) == 0 ! and child.getAttributeNode("spam") is None) dom.unlink() *************** *** 294,304 **** confirm(len(el.attributes) == 1) el.setAttribute("spam", "bam") ! confirm(len(el.attributes) == 1) el.attributes["spam"] = "ham" ! confirm(len(el.attributes) == 1) el.setAttribute("spam2", "bam") ! confirm(len(el.attributes) == 2) ! el.attributes[ "spam2"] = "bam2" ! confirm(len(el.attributes) == 2) dom.unlink() --- 293,326 ---- confirm(len(el.attributes) == 1) el.setAttribute("spam", "bam") ! # Set this attribute to be an ID and make sure that doesn't change ! # when changing the value: ! el.setIdAttribute("spam") ! confirm(len(el.attributes) == 1 ! and el.attributes["spam"].value == "bam" ! and el.attributes["spam"].nodeValue == "bam" ! and el.getAttribute("spam") == "bam" ! and el.getAttributeNode("spam").isId) el.attributes["spam"] = "ham" ! confirm(len(el.attributes) == 1 ! and el.attributes["spam"].value == "ham" ! and el.attributes["spam"].nodeValue == "ham" ! and el.getAttribute("spam") == "ham" ! and el.attributes["spam"].isId) el.setAttribute("spam2", "bam") ! confirm(len(el.attributes) == 2 ! and el.attributes["spam"].value == "ham" ! and el.attributes["spam"].nodeValue == "ham" ! and el.getAttribute("spam") == "ham" ! and el.attributes["spam2"].value == "bam" ! and el.attributes["spam2"].nodeValue == "bam" ! and el.getAttribute("spam2") == "bam") ! el.attributes["spam2"] = "bam2" ! confirm(len(el.attributes) == 2 ! and el.attributes["spam"].value == "ham" ! and el.attributes["spam"].nodeValue == "ham" ! and el.getAttribute("spam") == "ham" ! and el.attributes["spam2"].value == "bam2" ! and el.attributes["spam2"].nodeValue == "bam2" ! and el.getAttribute("spam2") == "bam2") dom.unlink() *************** *** 317,329 **** def testGetElementsByTagNameNS(): ! d=""" """ dom = parseString(d) ! elem = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom","myelem") ! confirm(len(elem) == 1) dom.unlink() ! def testGetEmptyNodeListFromElementsByTagNameNS(): pass def testElementReprAndStr(): --- 339,375 ---- def testGetElementsByTagNameNS(): ! d=""" """ dom = parseString(d) ! elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom", "myelem") ! confirm(len(elems) == 1 ! and elems[0].namespaceURI == "http://pyxml.sf.net/minidom" ! and elems[0].localName == "myelem" ! and elems[0].prefix == "minidom" ! and elems[0].tagName == "minidom:myelem" ! and elems[0].nodeName == "minidom:myelem") dom.unlink() ! def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc, nsuri, lname): ! nodelist = doc.getElementsByTagNameNS(nsuri, lname) ! confirm(len(nodelist) == 0) ! ! def testGetEmptyNodeListFromElementsByTagNameNS(): ! doc = parseString('') ! get_empty_nodelist_from_elements_by_tagName_ns_helper( ! doc, 'http://xml.python.org/namespaces/a', 'localname') ! get_empty_nodelist_from_elements_by_tagName_ns_helper( ! doc, '*', 'splat') ! get_empty_nodelist_from_elements_by_tagName_ns_helper( ! doc, 'http://xml.python.org/namespaces/a', '*') ! ! doc = parseString('') ! get_empty_nodelist_from_elements_by_tagName_ns_helper( ! doc, "http://xml.python.org/splat", "not-there") ! get_empty_nodelist_from_elements_by_tagName_ns_helper( ! doc, "*", "not-there") ! get_empty_nodelist_from_elements_by_tagName_ns_helper( ! doc, "http://somewhere.else.net/not-there", "e") def testElementReprAndStr(): *************** *** 371,375 **** confirm(str == domstr) ! def testProcessingInstruction(): pass def testProcessingInstructionRepr(): pass --- 417,434 ---- confirm(str == domstr) ! def testProcessingInstruction(): ! dom = parseString('') ! pi = dom.documentElement.firstChild ! confirm(pi.target == "mypi" ! and pi.data == "data \t\n " ! and pi.nodeName == "mypi" ! and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE ! and pi.attributes is None ! and not pi.hasChildNodes() ! and len(pi.childNodes) == 0 ! and pi.firstChild is None ! and pi.lastChild is None ! and pi.localName is None ! and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE) def testProcessingInstructionRepr(): pass *************** *** 414,417 **** --- 473,500 ---- def testAttrListKeysNS(): pass + def testRemoveNamedItem(): + doc = parseString("") + e = doc.documentElement + attrs = e.attributes + a1 = e.getAttributeNode("a") + a2 = attrs.removeNamedItem("a") + confirm(a1.isSameNode(a2)) + try: + attrs.removeNamedItem("a") + except xml.dom.NotFoundErr: + pass + + def testRemoveNamedItemNS(): + doc = parseString("") + e = doc.documentElement + attrs = e.attributes + a1 = e.getAttributeNodeNS("http://xml.python.org/", "b") + a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b") + confirm(a1.isSameNode(a2)) + try: + attrs.removeNamedItemNS("http://xml.python.org/", "b") + except xml.dom.NotFoundErr: + pass + def testAttrListValues(): pass *************** *** 490,505 **** "clone of attribute node correctly owned") ! def testCloneDocumentShallow(): pass ! def testCloneDocumentDeep(): pass ! def testCloneAttributeShallow(): pass ! def testCloneAttributeDeep(): pass ! def testClonePIShallow(): pass ! def testClonePIDeep(): pass def testNormalize(): --- 573,775 ---- "clone of attribute node correctly owned") + def testCloneDocumentShallow(): + doc = parseString("\n" + "" + "\n" + "]>\n" + "") + doc2 = doc.cloneNode(0) + confirm(doc2 is None, + "testCloneDocumentShallow:" + " shallow cloning of documents makes no sense!") ! def testCloneDocumentDeep(): ! doc = parseString("\n" ! "" ! "\n" ! "]>\n" ! "") ! doc2 = doc.cloneNode(1) ! confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)), ! "testCloneDocumentDeep: document objects not distinct") ! confirm(len(doc.childNodes) == len(doc2.childNodes), ! "testCloneDocumentDeep: wrong number of Document children") ! confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE, ! "testCloneDocumentDeep: documentElement not an ELEMENT_NODE") ! confirm(doc2.documentElement.ownerDocument.isSameNode(doc2), ! "testCloneDocumentDeep: documentElement owner is not new document") ! confirm(not doc.documentElement.isSameNode(doc2.documentElement), ! "testCloneDocumentDeep: documentElement should not be shared") ! if doc.doctype is not None: ! # check the doctype iff the original DOM maintained it ! confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE, ! "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE") ! confirm(doc2.doctype.ownerDocument.isSameNode(doc2)) ! confirm(not doc.doctype.isSameNode(doc2.doctype)) ! def testCloneDocumentTypeDeepOk(): ! doctype = create_nonempty_doctype() ! clone = doctype.cloneNode(1) ! confirm(clone is not None ! and clone.nodeName == doctype.nodeName ! and clone.name == doctype.name ! and clone.publicId == doctype.publicId ! and clone.systemId == doctype.systemId ! and len(clone.entities) == len(doctype.entities) ! and clone.entities.item(len(clone.entities)) is None ! and len(clone.notations) == len(doctype.notations) ! and clone.notations.item(len(clone.notations)) is None ! and len(clone.childNodes) == 0) ! for i in range(len(doctype.entities)): ! se = doctype.entities.item(i) ! ce = clone.entities.item(i) ! confirm((not se.isSameNode(ce)) ! and (not ce.isSameNode(se)) ! and ce.nodeName == se.nodeName ! and ce.notationName == se.notationName ! and ce.publicId == se.publicId ! and ce.systemId == se.systemId ! and ce.encoding == se.encoding ! and ce.actualEncoding == se.actualEncoding ! and ce.version == se.version) ! for i in range(len(doctype.notations)): ! sn = doctype.notations.item(i) ! cn = clone.notations.item(i) ! confirm((not sn.isSameNode(cn)) ! and (not cn.isSameNode(sn)) ! and cn.nodeName == sn.nodeName ! and cn.publicId == sn.publicId ! and cn.systemId == sn.systemId) ! def testCloneDocumentTypeDeepNotOk(): ! doc = create_doc_with_doctype() ! clone = doc.doctype.cloneNode(1) ! confirm(clone is None, "testCloneDocumentTypeDeepNotOk") ! def testCloneDocumentTypeShallowOk(): ! doctype = create_nonempty_doctype() ! clone = doctype.cloneNode(0) ! confirm(clone is not None ! and clone.nodeName == doctype.nodeName ! and clone.name == doctype.name ! and clone.publicId == doctype.publicId ! and clone.systemId == doctype.systemId ! and len(clone.entities) == 0 ! and clone.entities.item(0) is None ! and len(clone.notations) == 0 ! and clone.notations.item(0) is None ! and len(clone.childNodes) == 0) ! def testCloneDocumentTypeShallowNotOk(): ! doc = create_doc_with_doctype() ! clone = doc.doctype.cloneNode(0) ! confirm(clone is None, "testCloneDocumentTypeShallowNotOk") ! def check_import_document(deep, testName): ! doc1 = parseString("") ! doc2 = parseString("") ! try: ! doc1.importNode(doc2, deep) ! except xml.dom.NotSupportedErr: ! pass ! else: ! raise Exception(testName + ! ": expected NotSupportedErr when importing a document") ! ! def testImportDocumentShallow(): ! check_import_document(0, "testImportDocumentShallow") ! ! def testImportDocumentDeep(): ! check_import_document(1, "testImportDocumentDeep") ! ! # The tests of DocumentType importing use these helpers to construct ! # the documents to work with, since not all DOM builders actually ! # create the DocumentType nodes. ! ! def create_doc_without_doctype(doctype=None): ! return getDOMImplementation().createDocument(None, "doc", doctype) ! ! def create_nonempty_doctype(): ! doctype = getDOMImplementation().createDocumentType("doc", None, None) ! doctype.entities._seq = [] ! doctype.notations._seq = [] ! notation = xml.dom.minidom.Notation("my-notation", None, ! "http://xml.python.org/notations/my") ! doctype.notations._seq.append(notation) ! entity = xml.dom.minidom.Entity("my-entity", None, ! "http://xml.python.org/entities/my", ! "my-notation") ! entity.version = "1.0" ! entity.encoding = "utf-8" ! entity.actualEncoding = "us-ascii" ! doctype.entities._seq.append(entity) ! return doctype ! ! def create_doc_with_doctype(): ! doctype = create_nonempty_doctype() ! doc = create_doc_without_doctype(doctype) ! doctype.entities.item(0).ownerDocument = doc ! doctype.notations.item(0).ownerDocument = doc ! return doc ! ! def testImportDocumentTypeShallow(): ! src = create_doc_with_doctype() ! target = create_doc_without_doctype() ! try: ! imported = target.importNode(src.doctype, 0) ! except xml.dom.NotSupportedErr: ! pass ! else: ! raise Exception( ! "testImportDocumentTypeShallow: expected NotSupportedErr") ! ! def testImportDocumentTypeDeep(): ! src = create_doc_with_doctype() ! target = create_doc_without_doctype() ! try: ! imported = target.importNode(src.doctype, 1) ! except xml.dom.NotSupportedErr: ! pass ! else: ! raise Exception( ! "testImportDocumentTypeDeep: expected NotSupportedErr") ! ! # Testing attribute clones uses a helper, and should always be deep, ! # even if the argument to cloneNode is false. ! def check_clone_attribute(deep, testName): ! doc = parseString("") ! attr = doc.documentElement.getAttributeNode("attr") ! assert attr is not None ! clone = attr.cloneNode(deep) ! confirm(not clone.isSameNode(attr)) ! confirm(not attr.isSameNode(clone)) ! confirm(clone.ownerElement is None, ! testName + ": ownerElement should be None") ! confirm(clone.ownerDocument.isSameNode(attr.ownerDocument), ! testName + ": ownerDocument does not match") ! confirm(clone.specified, ! testName + ": cloned attribute must have specified == True") ! ! def testCloneAttributeShallow(): ! check_clone_attribute(0, "testCloneAttributeShallow") ! ! def testCloneAttributeDeep(): ! check_clone_attribute(1, "testCloneAttributeDeep") ! ! def check_clone_pi(deep, testName): ! doc = parseString("") ! pi = doc.firstChild ! assert pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE ! clone = pi.cloneNode(deep) ! confirm(clone.target == pi.target ! and clone.data == pi.data) ! ! def testClonePIShallow(): ! check_clone_pi(0, "testClonePIShallow") ! ! def testClonePIDeep(): ! check_clone_pi(1, "testClonePIDeep") def testNormalize(): *************** *** 611,614 **** --- 881,1322 ---- "testEncodings - encoding EURO SIGN") doc.unlink() + + class UserDataHandler: + called = 0 + def handle(self, operation, key, data, src, dst): + dst.setUserData(key, data + 1, self) + src.setUserData(key, None, None) + self.called = 1 + + def testUserData(): + dom = Document() + n = dom.createElement('e') + confirm(n.getUserData("foo") is None) + n.setUserData("foo", None, None) + confirm(n.getUserData("foo") is None) + n.setUserData("foo", 12, 12) + n.setUserData("bar", 13, 13) + confirm(n.getUserData("foo") == 12) + confirm(n.getUserData("bar") == 13) + n.setUserData("foo", None, None) + confirm(n.getUserData("foo") is None) + confirm(n.getUserData("bar") == 13) + + handler = UserDataHandler() + n.setUserData("bar", 12, handler) + c = n.cloneNode(1) + confirm(handler.called + and n.getUserData("bar") is None + and c.getUserData("bar") == 13) + n.unlink() + c.unlink() + dom.unlink() + + def testRenameAttribute(): + doc = parseString("") + elem = doc.documentElement + attrmap = elem.attributes + attr = elem.attributes['a'] + + # Simple renaming + attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b") + confirm(attr.name == "b" + and attr.nodeName == "b" + and attr.localName is None + and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE + and attr.prefix is None + and attr.value == "v" + and elem.getAttributeNode("a") is None + and elem.getAttributeNode("b").isSameNode(attr) + and attrmap["b"].isSameNode(attr) + and attr.ownerDocument.isSameNode(doc) + and attr.ownerElement.isSameNode(elem)) + + # Rename to have a namespace, no prefix + attr = doc.renameNode(attr, "http://xml.python.org/ns", "c") + confirm(attr.name == "c" + and attr.nodeName == "c" + and attr.localName == "c" + and attr.namespaceURI == "http://xml.python.org/ns" + and attr.prefix is None + and attr.value == "v" + and elem.getAttributeNode("a") is None + and elem.getAttributeNode("b") is None + and elem.getAttributeNode("c").isSameNode(attr) + and elem.getAttributeNodeNS( + "http://xml.python.org/ns", "c").isSameNode(attr) + and attrmap["c"].isSameNode(attr) + and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr)) + + # Rename to have a namespace, with prefix + attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d") + confirm(attr.name == "p:d" + and attr.nodeName == "p:d" + and attr.localName == "d" + and attr.namespaceURI == "http://xml.python.org/ns2" + and attr.prefix == "p" + and attr.value == "v" + and elem.getAttributeNode("a") is None + and elem.getAttributeNode("b") is None + and elem.getAttributeNode("c") is None + and elem.getAttributeNodeNS( + "http://xml.python.org/ns", "c") is None + and elem.getAttributeNode("p:d").isSameNode(attr) + and elem.getAttributeNodeNS( + "http://xml.python.org/ns2", "d").isSameNode(attr) + and attrmap["p:d"].isSameNode(attr) + and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr)) + + # Rename back to a simple non-NS node + attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e") + confirm(attr.name == "e" + and attr.nodeName == "e" + and attr.localName is None + and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE + and attr.prefix is None + and attr.value == "v" + and elem.getAttributeNode("a") is None + and elem.getAttributeNode("b") is None + and elem.getAttributeNode("c") is None + and elem.getAttributeNode("p:d") is None + and elem.getAttributeNodeNS( + "http://xml.python.org/ns", "c") is None + and elem.getAttributeNode("e").isSameNode(attr) + and attrmap["e"].isSameNode(attr)) + + try: + doc.renameNode(attr, "http://xml.python.org/ns", "xmlns") + except xml.dom.NamespaceErr: + pass + else: + print "expected NamespaceErr" + + checkRenameNodeSharedConstraints(doc, attr) + doc.unlink() + + def testRenameElement(): + doc = parseString("") + elem = doc.documentElement + + # Simple renaming + elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a") + confirm(elem.tagName == "a" + and elem.nodeName == "a" + and elem.localName is None + and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE + and elem.prefix is None + and elem.ownerDocument.isSameNode(doc)) + + # Rename to have a namespace, no prefix + elem = doc.renameNode(elem, "http://xml.python.org/ns", "b") + confirm(elem.tagName == "b" + and elem.nodeName == "b" + and elem.localName == "b" + and elem.namespaceURI == "http://xml.python.org/ns" + and elem.prefix is None + and elem.ownerDocument.isSameNode(doc)) + + # Rename to have a namespace, with prefix + elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c") + confirm(elem.tagName == "p:c" + and elem.nodeName == "p:c" + and elem.localName == "c" + and elem.namespaceURI == "http://xml.python.org/ns2" + and elem.prefix == "p" + and elem.ownerDocument.isSameNode(doc)) + + # Rename back to a simple non-NS node + elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d") + confirm(elem.tagName == "d" + and elem.nodeName == "d" + and elem.localName is None + and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE + and elem.prefix is None + and elem.ownerDocument.isSameNode(doc)) + + checkRenameNodeSharedConstraints(doc, elem) + doc.unlink() + + def checkRenameNodeSharedConstraints(doc, node): + # Make sure illegal NS usage is detected: + try: + doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo") + except xml.dom.NamespaceErr: + pass + else: + print "expected NamespaceErr" + + doc2 = parseString("") + try: + doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo") + except xml.dom.WrongDocumentErr: + pass + else: + print "expected WrongDocumentErr" + + def testRenameOther(): + # We have to create a comment node explicitly since not all DOM + # builders used with minidom add comments to the DOM. + doc = xml.dom.minidom.getDOMImplementation().createDocument( + xml.dom.EMPTY_NAMESPACE, "e", None) + node = doc.createComment("comment") + try: + doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo") + except xml.dom.NotSupportedErr: + pass + else: + print "expected NotSupportedErr when renaming comment node" + doc.unlink() + + def checkWholeText(node, s): + t = node.wholeText + confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t))) + + def testWholeText(): + doc = parseString("a") + elem = doc.documentElement + text = elem.childNodes[0] + assert text.nodeType == Node.TEXT_NODE + + checkWholeText(text, "a") + elem.appendChild(doc.createTextNode("b")) + checkWholeText(text, "ab") + elem.insertBefore(doc.createCDATASection("c"), text) + checkWholeText(text, "cab") + + # make sure we don't cross other nodes + splitter = doc.createComment("comment") + elem.appendChild(splitter) + text2 = doc.createTextNode("d") + elem.appendChild(text2) + checkWholeText(text, "cab") + checkWholeText(text2, "d") + + x = doc.createElement("x") + elem.replaceChild(x, splitter) + splitter = x + checkWholeText(text, "cab") + checkWholeText(text2, "d") + + x = doc.createProcessingInstruction("y", "z") + elem.replaceChild(x, splitter) + splitter = x + checkWholeText(text, "cab") + checkWholeText(text2, "d") + + elem.removeChild(splitter) + checkWholeText(text, "cabd") + checkWholeText(text2, "cabd") + + def testReplaceWholeText(): + def setup(): + doc = parseString("ad") + elem = doc.documentElement + text1 = elem.firstChild + text2 = elem.lastChild + splitter = text1.nextSibling + elem.insertBefore(doc.createTextNode("b"), splitter) + elem.insertBefore(doc.createCDATASection("c"), text1) + return doc, elem, text1, splitter, text2 + + doc, elem, text1, splitter, text2 = setup() + text = text1.replaceWholeText("new content") + checkWholeText(text, "new content") + checkWholeText(text2, "d") + confirm(len(elem.childNodes) == 3) + + doc, elem, text1, splitter, text2 = setup() + text = text2.replaceWholeText("new content") + checkWholeText(text, "new content") + checkWholeText(text1, "cab") + confirm(len(elem.childNodes) == 5) + + doc, elem, text1, splitter, text2 = setup() + text = text1.replaceWholeText("") + checkWholeText(text2, "d") + confirm(text is None + and len(elem.childNodes) == 2) + + def testSchemaType(): + doc = parseString( + "\n" + " \n" + " \n" + "]>") + elem = doc.documentElement + # We don't want to rely on any specific loader at this point, so + # just make sure we can get to all the names, and that the + # DTD-based namespace is right. The names can vary by loader + # since each supports a different level of DTD information. + t = elem.schemaType + confirm(t.name is None + and t.namespace == xml.dom.EMPTY_NAMESPACE) + names = "id notid text enum ref refs ent ents nm nms".split() + for name in names: + a = elem.getAttributeNode(name) + t = a.schemaType + confirm(hasattr(t, "name") + and t.namespace == xml.dom.EMPTY_NAMESPACE) + + def testSetIdAttribute(): + doc = parseString("") + e = doc.documentElement + a1 = e.getAttributeNode("a1") + a2 = e.getAttributeNode("a2") + confirm(doc.getElementById("v") is None + and not a1.isId + and not a2.isId) + e.setIdAttribute("a1") + confirm(e.isSameNode(doc.getElementById("v")) + and a1.isId + and not a2.isId) + e.setIdAttribute("a2") + confirm(e.isSameNode(doc.getElementById("v")) + and e.isSameNode(doc.getElementById("w")) + and a1.isId + and a2.isId) + # replace the a1 node; the new node should *not* be an ID + a3 = doc.createAttribute("a1") + a3.value = "v" + e.setAttributeNode(a3) + confirm(doc.getElementById("v") is None + and e.isSameNode(doc.getElementById("w")) + and not a1.isId + and a2.isId + and not a3.isId) + # renaming an attribute should not affect it's ID-ness: + doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") + confirm(e.isSameNode(doc.getElementById("w")) + and a2.isId) + + def testSetIdAttributeNS(): + NS1 = "http://xml.python.org/ns1" + NS2 = "http://xml.python.org/ns2" + doc = parseString("") + e = doc.documentElement + a1 = e.getAttributeNodeNS(NS1, "a1") + a2 = e.getAttributeNodeNS(NS2, "a2") + confirm(doc.getElementById("v") is None + and not a1.isId + and not a2.isId) + e.setIdAttributeNS(NS1, "a1") + confirm(e.isSameNode(doc.getElementById("v")) + and a1.isId + and not a2.isId) + e.setIdAttributeNS(NS2, "a2") + confirm(e.isSameNode(doc.getElementById("v")) + and e.isSameNode(doc.getElementById("w")) + and a1.isId + and a2.isId) + # replace the a1 node; the new node should *not* be an ID + a3 = doc.createAttributeNS(NS1, "a1") + a3.value = "v" + e.setAttributeNode(a3) + confirm(e.isSameNode(doc.getElementById("w"))) + confirm(not a1.isId) + confirm(a2.isId) + confirm(not a3.isId) + confirm(doc.getElementById("v") is None) + # renaming an attribute should not affect it's ID-ness: + doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") + confirm(e.isSameNode(doc.getElementById("w")) + and a2.isId) + + def testSetIdAttributeNode(): + NS1 = "http://xml.python.org/ns1" + NS2 = "http://xml.python.org/ns2" + doc = parseString("") + e = doc.documentElement + a1 = e.getAttributeNodeNS(NS1, "a1") + a2 = e.getAttributeNodeNS(NS2, "a2") + confirm(doc.getElementById("v") is None + and not a1.isId + and not a2.isId) + e.setIdAttributeNode(a1) + confirm(e.isSameNode(doc.getElementById("v")) + and a1.isId + and not a2.isId) + e.setIdAttributeNode(a2) + confirm(e.isSameNode(doc.getElementById("v")) + and e.isSameNode(doc.getElementById("w")) + and a1.isId + and a2.isId) + # replace the a1 node; the new node should *not* be an ID + a3 = doc.createAttributeNS(NS1, "a1") + a3.value = "v" + e.setAttributeNode(a3) + confirm(e.isSameNode(doc.getElementById("w"))) + confirm(not a1.isId) + confirm(a2.isId) + confirm(not a3.isId) + confirm(doc.getElementById("v") is None) + # renaming an attribute should not affect it's ID-ness: + doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") + confirm(e.isSameNode(doc.getElementById("w")) + and a2.isId) + + def testPickledDocument(): + doc = parseString("\n" + "\n" + " \n" + "]> text\n" + " ") + s = pickle.dumps(doc) + doc2 = pickle.loads(s) + stack = [(doc, doc2)] + while stack: + n1, n2 = stack.pop() + confirm(n1.nodeType == n2.nodeType + and len(n1.childNodes) == len(n2.childNodes) + and n1.nodeName == n2.nodeName + and not n1.isSameNode(n2) + and not n2.isSameNode(n1)) + if n1.nodeType == Node.DOCUMENT_TYPE_NODE: + len(n1.entities) + len(n2.entities) + len(n1.notations) + len(n2.notations) + confirm(len(n1.entities) == len(n2.entities) + and len(n1.notations) == len(n2.notations)) + for i in range(len(n1.notations)): + no1 = n1.notations.item(i) + no2 = n1.notations.item(i) + confirm(no1.name == no2.name + and no1.publicId == no2.publicId + and no1.systemId == no2.systemId) + statck.append((no1, no2)) + for i in range(len(n1.entities)): + e1 = n1.entities.item(i) + e2 = n2.entities.item(i) + confirm(e1.notationName == e2.notationName + and e1.publicId == e2.publicId + and e1.systemId == e2.systemId) + stack.append((e1, e2)) + if n1.nodeType != Node.DOCUMENT_NODE: + confirm(n1.ownerDocument.isSameNode(doc) + and n2.ownerDocument.isSameNode(doc2)) + for i in range(len(n1.childNodes)): + stack.append((n1.childNodes[i], n2.childNodes[i])) + # --- MAIN PROGRAM From rhettinger@users.sourceforge.net Sat Jan 25 21:46:55 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 25 Jan 2003 13:46:55 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib liblogging.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv31084 Modified Files: liblogging.tex Log Message: Fix minor typos. Index: liblogging.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liblogging.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** liblogging.tex 25 Jan 2003 21:29:41 -0000 1.4 --- liblogging.tex 25 Jan 2003 21:46:53 -0000 1.5 *************** *** 258,262 **** \constant{ALL} has been set using \method{setLevel()}, it is returned. Otherwise, the hierarchy is traversed towards the root until a value ! other than \constant{ALL} is found,and that value is returned. \end{methoddesc} --- 258,262 ---- \constant{ALL} has been set using \method{setLevel()}, it is returned. Otherwise, the hierarchy is traversed towards the root until a value ! other than \constant{ALL} is found, and that value is returned. \end{methoddesc} *************** *** 433,437 **** \var{sys.stdout}, \var{sys.stderr} or any file-like object (or, more precisely, any object which supports \method{write()} and \method{flush()} ! methods. \begin{classdesc}{StreamHandler}{\optional{strm}} --- 433,437 ---- \var{sys.stdout}, \var{sys.stderr} or any file-like object (or, more precisely, any object which supports \method{write()} and \method{flush()} ! methods). \begin{classdesc}{StreamHandler}{\optional{strm}} *************** *** 550,554 **** \begin{methoddesc}{send}{packet} ! Send a pickled string \var{packe} to the socket. This function allows for partial sends which can happen when the network is busy. \end{methoddesc} --- 550,554 ---- \begin{methoddesc}{send}{packet} ! Send a pickled string \var{packet} to the socket. This function allows for partial sends which can happen when the network is busy. \end{methoddesc} *************** *** 718,722 **** \begin{methoddesc}{flush}{} ! You can override this to implement custom flushing behaviour. This version just zaps the buffer to empty. \end{methoddesc} --- 718,722 ---- \begin{methoddesc}{flush}{} ! You can override this to implement custom flushing behavior. This version just zaps the buffer to empty. \end{methoddesc} *************** *** 744,748 **** For a \class{MemoryHandler}, flushing means just sending the buffered records to the target, if there is one. Override if you want ! different behaviour. \end{methoddesc} --- 744,748 ---- For a \class{MemoryHandler}, flushing means just sending the buffered records to the target, if there is one. Override if you want ! different behavior. \end{methoddesc} *************** *** 832,836 **** wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the ! basic behaviour is as follows: if \var{datefmt} (a string) is specified, it is used with \method{time.strftime()} to format the creation time of the record. Otherwise, the ISO8601 format is used. The resulting --- 832,836 ---- wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the ! basic behavior is as follows: if \var{datefmt} (a string) is specified, it is used with \method{time.strftime()} to format the creation time of the record. Otherwise, the ISO8601 format is used. The resulting From loewis@users.sourceforge.net Sat Jan 25 22:02:55 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:02:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_minidom.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv7751 Modified Files: test_minidom.py Log Message: Synchronize with PyXML's 1.33: Import missing modules. Index: test_minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_minidom.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** test_minidom.py 25 Jan 2003 21:39:09 -0000 1.37 --- test_minidom.py 25 Jan 2003 22:02:52 -0000 1.38 *************** *** 3,14 **** import os import sys import traceback ! from test.test_support import verbose import xml.dom import xml.parsers.expat from xml.dom.minidom import parse, Node, Document, parseString if __name__ == "__main__": --- 3,18 ---- import os import sys + import pickle import traceback ! from StringIO import StringIO from test.test_support import verbose import xml.dom + import xml.dom.minidom import xml.parsers.expat from xml.dom.minidom import parse, Node, Document, parseString + from xml.dom.minidom import getDOMImplementation + if __name__ == "__main__": *************** *** 25,29 **** def testParseFromFile(): - from StringIO import StringIO dom = parse(StringIO(open(tstfile).read())) dom.unlink() --- 29,32 ---- *************** *** 1330,1334 **** Node.allnodes except AttributeError: ! # We don't actually have the minidom from teh standard library, # but are picking up the PyXML version from site-packages. def check_allnodes(): --- 1333,1337 ---- Node.allnodes except AttributeError: ! # We don't actually have the minidom from the standard library, # but are picking up the PyXML version from site-packages. def check_allnodes(): From tim_one@users.sourceforge.net Sat Jan 25 22:32:10 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:32:10 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv26127 Modified Files: pickletools.py Log Message: Fleshed out the 6 ways to pickle ints. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pickletools.py 25 Jan 2003 20:58:52 -0000 1.1 --- pickletools.py 25 Jan 2003 22:32:08 -0000 1.2 *************** *** 17,21 **** # program to generate XML from the objects. ! # Some pickle opcodes have an argument, following the opcode in the # bytestream. An argument is of a specific type, described by an instance --- 17,21 ---- # program to generate XML from the objects. ! ############################################################################## # Some pickle opcodes have an argument, following the opcode in the # bytestream. An argument is of a specific type, described by an instance *************** *** 69,73 **** n=1, reader=read_uint1, ! doc="one-byte unsigned integer") --- 69,73 ---- n=1, reader=read_uint1, ! doc="One-byte unsigned integer.") *************** *** 90,94 **** n=2, reader=read_uint2, ! doc="two-byte unsigned integer, little-endian") --- 90,94 ---- n=2, reader=read_uint2, ! doc="Two-byte unsigned integer, little-endian.") *************** *** 111,118 **** n=4, reader=read_int4, ! doc="four-byte signed integer, little-endian") ! def read_stringnl(f): """ >>> import StringIO --- 111,118 ---- n=4, reader=read_int4, ! doc="Four-byte signed integer, little-endian, 2's complement.") ! def read_stringnl(f, decode=True): """ >>> import StringIO *************** *** 139,143 **** # I'm not sure when 'string_escape' was added to the std codecs; it's # crazy not to use it if it's there. ! return data.decode('string_escape') stringnl = ArgumentDescriptor( --- 139,145 ---- # I'm not sure when 'string_escape' was added to the std codecs; it's # crazy not to use it if it's there. ! if decode: ! data = data.decode('string_escape') ! return data stringnl = ArgumentDescriptor( *************** *** 151,154 **** --- 153,273 ---- + def read_decimalnl_short(f): + """ + >>> import StringIO + >>> read_decimalnl_short(StringIO.StringIO("1234\\n56")) + 1234 + + >>> read_decimalnl_short(StringIO.StringIO("1234L\\n56")) + Traceback (most recent call last): + ... + ValueError: trailing 'L' not allowed in '1234L' + """ + + s = read_stringnl(f, decode=False) + if s.endswith("L"): + raise ValueError("trailing 'L' not allowed in %r" % s) + + # It's not necessarily true that the result fits in a Python short int: + # the pickle may have been written on a 64-bit box. + try: + return int(s) + except OverflowError: + return long(s) + + def read_decimalnl_long(f): + """ + >>> import StringIO + + >>> read_decimalnl_long(StringIO.StringIO("1234\\n56")) + Traceback (most recent call last): + ... + ValueError: trailing 'L' required in '1234' + + Someday the trailing 'L' will probably go away from this output. + + >>> read_decimalnl_long(StringIO.StringIO("1234L\\n56")) + 1234L + + >>> read_decimalnl_long(StringIO.StringIO("123456789012345678901234L\\n6")) + 123456789012345678901234L + """ + + s = read_stringnl(f, decode=False) + if not s.endswith("L"): + raise ValueError("trailing 'L' required in %r" % s) + return long(s) + + + decimalnl_short = ArgumentDescriptor( + name='decimalnl_short', + n=None, + reader=read_decimalnl_short, + doc="""A newline-terminated decimal integer literal. + + This never has a trailing 'L', and the integer fit + in a short Python int on the box where the pickle + was written -- but there's no guarantee it will fit + in a short Python int on the box where the pickle + is read. + """) + + decimalnl_long = ArgumentDescriptor( + name='decimalnl_short', + n=None, + reader=read_decimalnl_long, + doc="""A newline-terminated decimal integer literal. + + This has a trailing 'L', and can represent integers + of any size. + """) + + ############################################################################## + # Python object descriptors. The stack used by the pickle machine holds + # Python objects, and in the stack_before and stack_after attributes of + # OpcodeInfo descriptors we need names to describe the various types + # of Python objects that can appear on the stack. + + class PythonObject(object): + __slots__ = ( + # name of descriptor record, also a module global name; a string + 'name', + + # type of object, or tuple of type objects (meaning the object can + # be of any type in the tuple) + 'obtype', + + # human-readable docs for this arg descriptor; a string + 'doc', + ) + + def __init__(self, name, obtype, doc): + assert isinstance(name, str) + self.name = name + + assert isinstance(obtype, type) or isinstance(obtype, tuple) + self.obtype = obtype + + assert isinstance(doc, str) + self.doc = doc + + + pyint = PythonObject( + name='int', + obtype=int, + doc="A short (as opposed to long) Python integer object.") + + pylong = PythonObject( + name='long', + obtype=long, + doc="A long (as opposed to short) Python integer object.") + + pyinteger = PythonObject( + name='integer', + obtype=(int, long), + doc="A Python integer object, short or long.") + + + ############################################################################## # Descriptors for pickle opcodes. *************** *** 160,164 **** # the code used in a bytestream to represent the opcode; a string, ! # usually one letter 'code', --- 279,283 ---- # the code used in a bytestream to represent the opcode; a string, ! # usually one character 'code', *************** *** 196,200 **** self.stack_after = stack_after ! assert isinstance(proto, int) self.proto = proto --- 315,319 ---- self.stack_after = stack_after ! assert isinstance(proto, int) and 0 <= proto <= 2 self.proto = proto *************** *** 204,264 **** I = OpcodeInfo opcodes = [ ! I(name='MARK', ! code='(', ! args=[], stack_before=[], ! stack_after=[], proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), ! I(name='STOP', ! code='.', ! args=[], stack_before=[], ! stack_after=[], proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), ! I(name='POP', ! code='0', ! args=[], stack_before=[], ! stack_after=[], ! proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), ! I(name='POP_MARK', ! code='1', ! args=[], stack_before=[], ! stack_after=[], ! proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), ! I(name='DUP', ! code='2', ! args=[], stack_before=[], ! stack_after=[], ! proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), ! I(name='FLOAT', ! code='F', args=[], stack_before=[], --- 323,399 ---- I = OpcodeInfo opcodes = [ ! ! # Six ways to spell integers. ! ! I(name='INT', ! code='I', ! args=[decimalnl_short], stack_before=[], ! stack_after=[pyinteger], proto=0, ! doc="""Newline-terminated decimal integer literal. ! The intent may have been that this always fit in a short Python int, ! but INT can be generated in pickles written on a 64-bit box that ! require a Python long on a 32-bit box. The difference between this ! and LONG then is that INT skips a trailing 'L', and produces a short ! int whenever possible. """), ! I(name='LONG', ! code='L', ! args=[decimalnl_long], stack_before=[], ! stack_after=[pylong], proto=0, ! doc="""Newline-terminated decimal integer literal. ! The same as INT, except that the literal ends with 'L', and always ! unpickles to a Python long. There doesn't seem a real purpose to the ! trailing 'L'. """), ! I(name='BININT', ! code='J', ! args=[int4], stack_before=[], ! stack_after=[pyint], ! proto=1, ! doc="""Four-byte signed integer. ! This handles the full range of Python (short) integers on a 32-bit ! box, directly as binary bytes (1 for the opcode and 4 for the integer). ! If the integer is non-negative and fits in 1 or 2 bytes, pickling via ! BININT1 or BININT2 saves space. """), ! I(name='BININT1', ! code='K', ! args=[uint1], stack_before=[], ! stack_after=[pyint], ! proto=1, ! doc="""One-byte unsigned integer. ! This is a space optimization for pickling very small non-negative ints, ! in range(256). """), ! I(name='BININT2', ! code='M', ! args=[uint2], stack_before=[], ! stack_after=[pyint], ! proto=1, ! doc="""Two-byte unsigned integer. ! This is a space optimization for pickling small positive ints, in ! range(1, 2**16). """), ! # XXX opcodes below this point haven't been done yet. ! ! I(name='MARK', ! code='(', args=[], stack_before=[], *************** *** 270,275 **** """), ! I(name='INT', ! code='I', args=[], stack_before=[], --- 405,410 ---- """), ! I(name='STOP', ! code='.', args=[], stack_before=[], *************** *** 281,286 **** """), ! I(name='BININT', ! code='J', args=[], stack_before=[], --- 416,421 ---- """), ! I(name='POP', ! code='0', args=[], stack_before=[], *************** *** 292,297 **** """), ! I(name='BININT1', ! code='K', args=[], stack_before=[], --- 427,432 ---- """), ! I(name='POP_MARK', ! code='1', args=[], stack_before=[], *************** *** 303,308 **** """), ! I(name='LONG', ! code='L', args=[], stack_before=[], --- 438,443 ---- """), ! I(name='DUP', ! code='2', args=[], stack_before=[], *************** *** 314,319 **** """), ! I(name='BININT2', ! code='M', args=[], stack_before=[], --- 449,454 ---- """), ! I(name='FLOAT', ! code='F', args=[], stack_before=[], From rhettinger@users.sourceforge.net Sat Jan 25 22:35:44 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:35:44 -0800 Subject: [Python-checkins] python/dist/src/Misc cheatsheet,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv28209 Modified Files: cheatsheet Log Message: Part II of Python2.3 update Index: cheatsheet =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/cheatsheet,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** cheatsheet 25 Jan 2003 21:22:52 -0000 1.3 --- cheatsheet 25 Jan 2003 22:35:42 -0000 1.4 *************** *** 227,231 **** Most operators are overridable. ! Many of binary operators support augmented assignment: x += 1 # Same as x = x + 1 --- 227,231 ---- Most operators are overridable. ! Many binary operators also support augmented assignment: x += 1 # Same as x = x + 1 *************** *** 250,254 **** method __cmp__. The above comparisions return True or False which are of type bool ! (a subclass of int) and behave exactly as 1 or 0 except their type and that they print as True or False instead of 1 or 0. (1) X < Y < Z < W has expected meaning, unlike C --- 250,254 ---- method __cmp__. The above comparisions return True or False which are of type bool ! (a subclass of int) and behave exactly as 1 or 0 except for their type and that they print as True or False instead of 1 or 0. (1) X < Y < Z < W has expected meaning, unlike C *************** *** 509,513 **** [,deletechars]) table. s.upper() return a copy of s converted to uppercase. ! s.zfill(width) return a string padded with zeroes on the left and sliding a minus sign left if necessary. never truncates. --- 509,513 ---- [,deletechars]) table. s.upper() return a copy of s converted to uppercase. ! s.zfill(width) return a string padded with zeroes on the left side and sliding a minus sign left if necessary. never truncates. *************** *** 1805,1815 **** binhex Macintosh binhex compression/decompression. bisect List bisection algorithms. calendar Calendar printing functions. cgi Wraps the WWW Forms Common Gateway Interface (CGI). CGIHTTPServer CGI http services. cmd A generic class to build line-oriented command interpreters. ! [DEL:cmp:DEL] [DEL:Efficiently compare files, boolean outcome only.:DEL] ! [DEL:cmpcache: [DEL:Same, but caches 'stat' results for speed.:DEL] ! DEL] code Utilities needed to emulate Python's interactive interpreter codecs Lookup existing Unicode encodings and register new ones. --- 1805,1815 ---- binhex Macintosh binhex compression/decompression. bisect List bisection algorithms. + bz2 Support for bz2 compression/decompression. calendar Calendar printing functions. cgi Wraps the WWW Forms Common Gateway Interface (CGI). + cgitb Utility for handling CGI tracebacks. CGIHTTPServer CGI http services. cmd A generic class to build line-oriented command interpreters. ! datetime Basic date and time types. code Utilities needed to emulate Python's interactive interpreter codecs Lookup existing Unicode encodings and register new ones. *************** *** 1823,1831 **** --- 1823,1834 ---- dircache Sorted list of files in a dir, using a cache. [DEL:dircmp:DEL] [DEL:Defines a class to build directory diff tools on.:DEL] + difflib Tool for creating delta between sequences. dis Bytecode disassembler. distutils Package installation system. + doctest Tool for running and verifying tests inside doc strings. dospath Common operations on DOS pathnames. dumbdbm A dumb and slow but simple dbm clone. [DEL:dump:DEL] [DEL:Print python code that reconstructs a variable.:DEL] + email Comprehensive support for internet email. exceptions Class based built-in exception hierarchy. filecmp File comparison. *************** *** 1846,1851 **** --- 1849,1857 ---- [DEL:grep:DEL] [DEL:'grep' utilities.:DEL] gzip Read & write gzipped files. + heapq Priority queue implemented using lists organized as heaps. + HMAC Keyed-Hashing for Message Authentication -- RFC 2104. htmlentitydefs Proposed entity definitions for HTML. htmllib HTML parsing utilities. + HTMLParser A parser for HTML and XHTML. httplib HTTP client class. ihooks Hooks into the "import" mechanism. *************** *** 1853,1856 **** --- 1859,1863 ---- imghdr Recognizing image files based on their first few bytes. imputil Privides a way of writing customised import hooks. + inspect Tool for probing live Python objects. keyword List of Python keywords. knee A Python re-implementation of hierarchical module import. *************** *** 1859,1862 **** --- 1866,1870 ---- locale Support for number formatting using the current locale settings. + logging Python logging facility. macpath Pathname (or related) operations for the Macintosh. macurl2path Mac specific module for conversion between pathnames and URLs. *************** *** 1876,1879 **** --- 1884,1888 ---- ntpath Common operations on DOS pathnames. nturl2path Mac specific module for conversion between pathnames and URLs. + optparse A comprehensive tool for processing command line options. os Either mac, dos or posix depending system. [DEL:packmail: [DEL:Create a self-unpacking shell archive.:DEL] *************** *** 1883,1887 **** Cimplementation exists in built-in module: cPickle). pipes Conversion pipeline templates. ! [DEL:poly:DEL] [DEL:Polynomials.:DEL] popen2 variations on pipe open. poplib A POP3 client class. Based on the J. Myers POP3 draft. --- 1892,1896 ---- Cimplementation exists in built-in module: cPickle). pipes Conversion pipeline templates. ! pkgunil Utilities for working with Python packages. popen2 variations on pipe open. poplib A POP3 client class. Based on the J. Myers POP3 draft. *************** *** 1892,1895 **** --- 1901,1905 ---- profile Class for profiling python code. pstats Class for printing reports on profiled python code. + pydoc Utility for generating documentation from source files. pty Pseudo terminal utilities. pyexpat Interface to the Expay XML parser. *************** *** 1899,1909 **** quopri Conversions to/from quoted-printable transport encoding. rand Don't use unless you want compatibility with C's rand(). ! random Random variable generators (obsolete, use whrandom) re Regular Expressions. reconvert Convert old ("regex") regular expressions to new syntax ("re"). - regex_syntax Flags for regex.set_syntax(). - regexp Backward compatibility for module "regexp" using "regex". - regsub Regular expression subroutines. repr Redo repr() but with limits on most sizes. rexec Restricted execution facilities ("safe" exec, eval, etc). --- 1909,1916 ---- quopri Conversions to/from quoted-printable transport encoding. rand Don't use unless you want compatibility with C's rand(). ! random Random variable generators re Regular Expressions. reconvert Convert old ("regex") regular expressions to new syntax ("re"). repr Redo repr() but with limits on most sizes. rexec Restricted execution facilities ("safe" exec, eval, etc). *************** *** 1912,1915 **** --- 1919,1923 ---- robotparser Parse robot.txt files, useful for web spiders. sched A generally useful event scheduler class. + sets Module for a set datatype. sgmllib A parser for SGML. shelve Manage shelves of pickled objects. *************** *** 1933,1938 **** --- 1941,1948 ---- symbol Non-terminal symbols of Python grammar (from "graminit.h"). tabnanny,/font> Check Python source for ambiguous indentation. + tarfile Facility for reading and writing to the *nix tarfile format. telnetlib TELNET client class. Based on RFC 854. tempfile Temporary file name allocation. + textwrap Object for wrapping and filling text. threading Proposed new higher-level threading interfaces threading_api (doc of the threading module) *************** *** 1954,1963 **** [DEL:util:DEL] [DEL:some useful functions that don't fit elsewhere !!:DEL] uu UUencode/UUdecode. wave Stuff to parse WAVE files. webbrowser Platform independent URL launcher. [DEL:whatsound: [DEL:Several routines that help recognizing sound files.:DEL] DEL] whichdb Guess which db package to use to open a db file. - whrandom Wichmann-Hill random number generator. xdrlib Implements (a subset of) Sun XDR (eXternal Data Representation) --- 1964,1974 ---- [DEL:util:DEL] [DEL:some useful functions that don't fit elsewhere !!:DEL] uu UUencode/UUdecode. + unittest Utilities for implementing unit testing. wave Stuff to parse WAVE files. + weakref Tools for creating and managing weakly referenced objects. webbrowser Platform independent URL launcher. [DEL:whatsound: [DEL:Several routines that help recognizing sound files.:DEL] DEL] whichdb Guess which db package to use to open a db file. xdrlib Implements (a subset of) Sun XDR (eXternal Data Representation) *************** *** 1965,1968 **** --- 1976,1980 ---- xml.dom Classes for processing XML using the Document Object Model. xml.sax Classes for processing XML using the SAX API. + xmlrpclib Support for remote procedure calls using XML. zipfile Read & write PK zipped files. [DEL:zmod:DEL] [DEL:Demonstration of abstruse mathematical concepts.:DEL] From loewis@users.sourceforge.net Sat Jan 25 22:41:31 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:41:31 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.136,1.137 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv31347 Modified Files: setup.py Log Message: Incorporate Expat 1.95.6. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.136 retrieving revision 1.137 diff -C2 -d -r1.136 -r1.137 *** setup.py 21 Jan 2003 21:01:37 -0000 1.136 --- setup.py 25 Jan 2003 22:41:27 -0000 1.137 *************** *** 691,697 **** # if sys.byteorder == "little": ! xmlbo = "12" else: ! xmlbo = "21" expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat') exts.append(Extension('pyexpat', --- 691,697 ---- # if sys.byteorder == "little": ! xmlbo = "1234" else: ! xmlbo = "4321" expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat') exts.append(Extension('pyexpat', *************** *** 703,710 **** ], define_macros = [ - ('HAVE_EXPAT_H',None), ('XML_NS', '1'), ('XML_DTD', '1'), ! ('XML_BYTE_ORDER', xmlbo), ('XML_CONTEXT_BYTES','1024'), ], --- 703,709 ---- ], define_macros = [ ('XML_NS', '1'), ('XML_DTD', '1'), ! ('BYTEORDER', xmlbo), ('XML_CONTEXT_BYTES','1024'), ], From loewis@users.sourceforge.net Sat Jan 25 22:41:32 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:41:32 -0800 Subject: [Python-checkins] python/dist/src/Modules/expat internal.h,NONE,1.1 ascii.h,1.1.1.1,1.2 expat.h,1.3,1.4 xmlparse.c,1.2,1.3 xmlrole.c,1.3,1.4 xmlrole.h,1.1.1.1,1.2 xmltok.c,1.2,1.3 xmltok.h,1.1.1.1,1.2 xmltok_impl.c,1.1.1.1,1.2 xmltok_ns.c,1.1.1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules/expat In directory sc8-pr-cvs1:/tmp/cvs-serv31347/Modules/expat Modified Files: ascii.h expat.h xmlparse.c xmlrole.c xmlrole.h xmltok.c xmltok.h xmltok_impl.c xmltok_ns.c Added Files: internal.h Log Message: Incorporate Expat 1.95.6. --- NEW FILE: internal.h --- /* internal.h Internal definitions used by Expat. This is not needed to compile client code. The following calling convention macros are defined for frequently called functions: FASTCALL - Used for those internal functions that have a simple body and a low number of arguments and local variables. PTRCALL - Used for functions called though function pointers. PTRFASTCALL - Like PTRCALL, but for low number of arguments. inline - Used for selected internal functions for which inlining may improve performance on some platforms. Note: Use of these macros is based on judgement, not hard rules, and therefore subject to change. */ #if defined(__GNUC__) /* Instability reported with egcs on a RedHat Linux 7.3. Let's comment it out: #define FASTCALL __attribute__((stdcall, regparm(3))) and let's try this: */ #define FASTCALL __attribute__((regparm(3))) #define PTRCALL #define PTRFASTCALL __attribute__((regparm(3))) #elif defined(WIN32) /* Using __fastcall seems to have an unexpected negative effect under MS VC++, especially for function pointers, so we won't use it for now on that platform. It may be reconsidered for a future release if it can be made more effective. Likely reason: __fastcall on Windows is like stdcall, therefore the compiler cannot perform stack optimizations for call clusters. */ #define FASTCALL #define PTRCALL #define PTRFASTCALL #endif #ifndef FASTCALL #define FASTCALL #endif #ifndef PTRCALL #define PTRCALL #endif #ifndef PTRFASTCALL #define PTRFASTCALL #endif #ifndef XML_MIN_SIZE #if !defined(__cplusplus) && !defined(inline) #ifdef __GNUC__ #define inline __inline #endif /* __GNUC__ */ #endif #endif /* XML_MIN_SIZE */ #ifdef __cplusplus #define inline inline #else #ifndef inline #define inline #endif #endif Index: ascii.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/ascii.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** ascii.h 11 Feb 2002 23:13:05 -0000 1.1.1.1 --- ascii.h 25 Jan 2003 22:41:29 -0000 1.2 *************** *** 1,5 **** ! /* ! Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ --- 1,4 ---- ! /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ *************** *** 70,74 **** #define ASCII_TAB 0x09 ! #define ASCII_SPACE 0x20 #define ASCII_EXCL 0x21 #define ASCII_QUOT 0x22 --- 69,73 ---- #define ASCII_TAB 0x09 ! #define ASCII_SPACE 0x20 #define ASCII_EXCL 0x21 #define ASCII_QUOT 0x22 Index: expat.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/expat.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** expat.h 8 May 2002 07:16:37 -0000 1.3 --- expat.h 25 Jan 2003 22:41:29 -0000 1.4 *************** *** 1,5 **** ! /* ! Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ --- 1,4 ---- ! /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ [...1432 lines suppressed...] ! typedef struct { ! enum XML_FeatureEnum feature; ! const XML_LChar *name; ! long int value; ! } XML_Feature; + XMLPARSEAPI(const XML_Feature *) + XML_GetFeatureList(void); + + + /* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. + */ #define XML_MAJOR_VERSION 1 #define XML_MINOR_VERSION 95 ! #define XML_MICRO_VERSION 6 #ifdef __cplusplus Index: xmlparse.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmlparse.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** xmlparse.c 11 Feb 2002 23:16:32 -0000 1.2 --- xmlparse.c 25 Jan 2003 22:41:29 -0000 1.3 *************** *** 1,19 **** ! /* ! Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ #ifdef COMPILED_FROM_DSP ! # include "winconfig.h" ! # define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl ! # include "expat.h" ! # undef XMLPARSEAPI [...9033 lines suppressed...] ! const char *end) { ! DTD * const dtd = _dtd; /* save one level of indirection */ ! const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); ELEMENT_TYPE *ret; ! if (!name) ! return NULL; ! ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); ! if (!ret) ! return NULL; if (ret->name != name) ! poolDiscard(&dtd->pool); else { ! poolFinish(&dtd->pool); if (!setElementTypePrefix(parser, ret)) ! return NULL; } return ret; ! } Index: xmlrole.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmlrole.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** xmlrole.c 17 Jul 2002 14:45:33 -0000 1.3 --- xmlrole.c 25 Jan 2003 22:41:29 -0000 1.4 *************** *** 1,15 **** ! /* ! Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ #ifdef COMPILED_FROM_DSP ! # include "winconfig.h" #else ! #ifdef HAVE_CONFIG_H ! # include [...2195 lines suppressed...] --- 1305,1309 ---- state->documentEntity = 1; state->includeLevel = 0; + state->inEntityValue = 0; #endif /* XML_DTD */ } *************** *** 1265,1269 **** #ifdef XML_DTD ! void XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { state->handler = externalSubset0; --- 1311,1316 ---- #ifdef XML_DTD ! void ! XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { state->handler = externalSubset0; Index: xmlrole.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmlrole.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** xmlrole.h 11 Feb 2002 23:13:07 -0000 1.1.1.1 --- xmlrole.h 25 Jan 2003 22:41:29 -0000 1.2 *************** *** 1,5 **** ! /* ! Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ --- 1,4 ---- ! /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ *************** *** 7,10 **** --- 6,15 ---- #define XmlRole_INCLUDED 1 + #ifdef __VMS + /* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ + #define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt + #endif + #include "xmltok.h" *************** *** 18,21 **** --- 23,27 ---- XML_ROLE_XML_DECL, XML_ROLE_INSTANCE_START, + XML_ROLE_DOCTYPE_NONE, XML_ROLE_DOCTYPE_NAME, XML_ROLE_DOCTYPE_SYSTEM_ID, *************** *** 25,28 **** --- 31,35 ---- XML_ROLE_GENERAL_ENTITY_NAME, XML_ROLE_PARAM_ENTITY_NAME, + XML_ROLE_ENTITY_NONE, XML_ROLE_ENTITY_VALUE, XML_ROLE_ENTITY_SYSTEM_ID, *************** *** 30,33 **** --- 37,41 ---- XML_ROLE_ENTITY_COMPLETE, XML_ROLE_ENTITY_NOTATION_NAME, + XML_ROLE_NOTATION_NONE, XML_ROLE_NOTATION_NAME, XML_ROLE_NOTATION_SYSTEM_ID, *************** *** 45,48 **** --- 53,57 ---- XML_ROLE_ATTRIBUTE_ENUM_VALUE, XML_ROLE_ATTRIBUTE_NOTATION_VALUE, + XML_ROLE_ATTLIST_NONE, XML_ROLE_ATTLIST_ELEMENT_NAME, XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, *************** *** 50,53 **** --- 59,63 ---- XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, XML_ROLE_FIXED_ATTRIBUTE_VALUE, + XML_ROLE_ELEMENT_NONE, XML_ROLE_ELEMENT_NAME, XML_ROLE_CONTENT_ANY, *************** *** 65,68 **** --- 75,80 ---- XML_ROLE_CONTENT_ELEMENT_OPT, XML_ROLE_CONTENT_ELEMENT_PLUS, + XML_ROLE_PI, + XML_ROLE_COMMENT, #ifdef XML_DTD XML_ROLE_TEXT_DECL, *************** *** 74,86 **** typedef struct prolog_state { ! int (*handler)(struct prolog_state *state, ! int tok, ! const char *ptr, ! const char *end, ! const ENCODING *enc); unsigned level; #ifdef XML_DTD unsigned includeLevel; int documentEntity; #endif /* XML_DTD */ } PROLOG_STATE; --- 86,100 ---- typedef struct prolog_state { ! int (PTRCALL *handler) (struct prolog_state *state, ! int tok, ! const char *ptr, ! const char *end, ! const ENCODING *enc); unsigned level; + int role_none; #ifdef XML_DTD unsigned includeLevel; int documentEntity; + int inEntityValue; #endif /* XML_DTD */ } PROLOG_STATE; Index: xmltok.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmltok.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** xmltok.c 11 Feb 2002 23:16:32 -0000 1.2 --- xmltok.c 25 Jan 2003 22:41:29 -0000 1.3 *************** *** 1,15 **** ! /* ! Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ #ifdef COMPILED_FROM_DSP ! # include "winconfig.h" #else ! #ifdef HAVE_CONFIG_H ! # include [...1891 lines suppressed...] ! return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } break; *************** *** 1556,1562 **** ENCODING * XmlInitUnknownEncodingNS(void *mem, ! int *table, ! int (*convert)(void *userData, const char *p), ! void *userData) { ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); --- 1622,1628 ---- ENCODING * XmlInitUnknownEncodingNS(void *mem, ! int *table, ! CONVERTER convert, ! void *userData) { ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); Index: xmltok.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmltok.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** xmltok.h 11 Feb 2002 23:13:07 -0000 1.1.1.1 --- xmltok.h 25 Jan 2003 22:41:29 -0000 1.2 *************** *** 1,5 **** ! /* ! Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ --- 1,4 ---- ! /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ *************** *** 12,28 **** /* The following token may be returned by XmlContentTok */ ! #define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of ! illegal ]]> sequence */ ! /* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ ! #define XML_TOK_NONE -4 /* The string to be scanned is empty */ ! #define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; ! might be part of CRLF sequence */ ! #define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ ! #define XML_TOK_PARTIAL -1 /* only part of a token */ #define XML_TOK_INVALID 0 /* The following tokens are returned by XmlContentTok; some are also ! returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */ ! #define XML_TOK_START_TAG_WITH_ATTS 1 #define XML_TOK_START_TAG_NO_ATTS 2 --- 11,29 ---- /* The following token may be returned by XmlContentTok */ ! #define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be ! start of illegal ]]> sequence */ ! /* The following tokens may be returned by both XmlPrologTok and ! XmlContentTok. ! */ ! #define XML_TOK_NONE -4 /* The string to be scanned is empty */ ! #define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; ! might be part of CRLF sequence */ ! #define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ ! #define XML_TOK_PARTIAL -1 /* only part of a token */ #define XML_TOK_INVALID 0 /* The following tokens are returned by XmlContentTok; some are also ! returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok. ! */ #define XML_TOK_START_TAG_WITH_ATTS 1 #define XML_TOK_START_TAG_NO_ATTS 2 *************** *** 34,53 **** #define XML_TOK_CDATA_SECT_OPEN 8 #define XML_TOK_ENTITY_REF 9 ! #define XML_TOK_CHAR_REF 10 /* numeric character reference */ ! /* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ ! #define XML_TOK_PI 11 /* processing instruction */ ! #define XML_TOK_XML_DECL 12 /* XML decl or text decl */ #define XML_TOK_COMMENT 13 ! #define XML_TOK_BOM 14 /* Byte order mark */ /* The following tokens are returned only by XmlPrologTok */ #define XML_TOK_PROLOG_S 15 ! #define XML_TOK_DECL_OPEN 16 /* */ #define XML_TOK_NAME 18 #define XML_TOK_NMTOKEN 19 ! #define XML_TOK_POUND_NAME 20 /* #name */ ! #define XML_TOK_OR 21 /* | */ #define XML_TOK_PERCENT 22 #define XML_TOK_OPEN_PAREN 23 --- 35,56 ---- #define XML_TOK_CDATA_SECT_OPEN 8 #define XML_TOK_ENTITY_REF 9 ! #define XML_TOK_CHAR_REF 10 /* numeric character reference */ ! /* The following tokens may be returned by both XmlPrologTok and ! XmlContentTok. ! */ ! #define XML_TOK_PI 11 /* processing instruction */ ! #define XML_TOK_XML_DECL 12 /* XML decl or text decl */ #define XML_TOK_COMMENT 13 ! #define XML_TOK_BOM 14 /* Byte order mark */ /* The following tokens are returned only by XmlPrologTok */ #define XML_TOK_PROLOG_S 15 ! #define XML_TOK_DECL_OPEN 16 /* */ #define XML_TOK_NAME 18 #define XML_TOK_NMTOKEN 19 ! #define XML_TOK_POUND_NAME 20 /* #name */ ! #define XML_TOK_OR 21 /* | */ #define XML_TOK_PERCENT 22 #define XML_TOK_OPEN_PAREN 23 *************** *** 60,71 **** /* The following occur only in element type declarations */ ! #define XML_TOK_NAME_QUESTION 30 /* name? */ ! #define XML_TOK_NAME_ASTERISK 31 /* name* */ ! #define XML_TOK_NAME_PLUS 32 /* name+ */ ! #define XML_TOK_COND_SECT_OPEN 33 /* */ ! #define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ ! #define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ ! #define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ #define XML_TOK_COMMA 38 --- 63,74 ---- /* The following occur only in element type declarations */ ! #define XML_TOK_NAME_QUESTION 30 /* name? */ ! #define XML_TOK_NAME_ASTERISK 31 /* name* */ ! #define XML_TOK_NAME_PLUS 32 /* name+ */ ! #define XML_TOK_COND_SECT_OPEN 33 /* */ ! #define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ ! #define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ ! #define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ #define XML_TOK_COMMA 38 *************** *** 76,81 **** #define XML_TOK_CDATA_SECT_CLOSE 40 ! /* With namespace processing this is returned by XmlPrologTok ! for a name with a colon. */ #define XML_TOK_PREFIXED_NAME 41 --- 79,85 ---- #define XML_TOK_CDATA_SECT_CLOSE 40 ! /* With namespace processing this is returned by XmlPrologTok for a ! name with a colon. ! */ #define XML_TOK_PREFIXED_NAME 41 *************** *** 122,160 **** typedef struct encoding ENCODING; struct encoding { ! int (*scanners[XML_N_STATES])(const ENCODING *, ! const char *, ! const char *, ! const char **); ! int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *, ! const char *, ! const char *, ! const char **); ! int (*sameName)(const ENCODING *, ! const char *, const char *); ! int (*nameMatchesAscii)(const ENCODING *, ! const char *, const char *, const char *); ! int (*nameLength)(const ENCODING *, const char *); ! const char *(*skipS)(const ENCODING *, const char *); ! int (*getAtts)(const ENCODING *enc, const char *ptr, ! int attsMax, ATTRIBUTE *atts); ! int (*charRefNumber)(const ENCODING *enc, const char *ptr); ! int (*predefinedEntityName)(const ENCODING *, const char *, const char *); ! void (*updatePosition)(const ENCODING *, ! const char *ptr, ! const char *end, ! POSITION *); ! int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end, ! const char **badPtr); ! void (*utf8Convert)(const ENCODING *enc, ! const char **fromP, ! const char *fromLim, ! char **toP, ! const char *toLim); ! void (*utf16Convert)(const ENCODING *enc, ! const char **fromP, ! const char *fromLim, ! unsigned short **toP, ! const unsigned short *toLim); int minBytesPerChar; char isUtf8; --- 126,172 ---- typedef struct encoding ENCODING; + typedef int (PTRCALL *SCANNER)(const ENCODING *, + const char *, + const char *, + const char **); + struct encoding { ! SCANNER scanners[XML_N_STATES]; ! SCANNER literalScanners[XML_N_LITERAL_TYPES]; ! int (PTRCALL *sameName)(const ENCODING *, ! const char *, ! const char *); ! int (PTRCALL *nameMatchesAscii)(const ENCODING *, ! const char *, ! const char *, ! const char *); ! int (PTRFASTCALL *nameLength)(const ENCODING *, const char *); ! const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); ! int (PTRCALL *getAtts)(const ENCODING *enc, ! const char *ptr, ! int attsMax, ! ATTRIBUTE *atts); ! int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); ! int (PTRCALL *predefinedEntityName)(const ENCODING *, ! const char *, ! const char *); ! void (PTRCALL *updatePosition)(const ENCODING *, ! const char *ptr, ! const char *end, ! POSITION *); ! int (PTRCALL *isPublicId)(const ENCODING *enc, ! const char *ptr, ! const char *end, ! const char **badPtr); ! void (PTRCALL *utf8Convert)(const ENCODING *enc, ! const char **fromP, ! const char *fromLim, ! char **toP, ! const char *toLim); ! void (PTRCALL *utf16Convert)(const ENCODING *enc, ! const char **fromP, ! const char *fromLim, ! unsigned short **toP, ! const unsigned short *toLim); int minBytesPerChar; char isUtf8; *************** *** 162,183 **** }; ! /* ! Scan the string starting at ptr until the end of the next complete token, ! but do not scan past eptr. Return an integer giving the type of token. ! Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. ! Return XML_TOK_PARTIAL when the string does not contain a complete token; ! nextTokPtr will not be set. ! Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr ! will be set to point to the character which made the token invalid. ! Otherwise the string starts with a valid token; nextTokPtr will be set to point ! to the character following the end of that token. ! Each data character counts as a single token, but adjacent data characters ! may be returned together. Similarly for characters in the prolog outside ! literals, comments and processing instructions. */ --- 174,196 ---- }; ! /* Scan the string starting at ptr until the end of the next complete ! token, but do not scan past eptr. Return an integer giving the ! type of token. ! Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. ! Return XML_TOK_PARTIAL when the string does not contain a complete ! token; nextTokPtr will not be set. ! Return XML_TOK_INVALID when the string does not start a valid ! token; nextTokPtr will be set to point to the character which made ! the token invalid. ! Otherwise the string starts with a valid token; nextTokPtr will be ! set to point to the character following the end of that token. ! Each data character counts as a single token, but adjacent data ! characters may be returned together. Similarly for characters in ! the prolog outside literals, comments and processing instructions. */ *************** *** 202,208 **** #endif /* XML_DTD */ ! /* This is used for performing a 2nd-level tokenization on ! the content of a literal that has already been returned by XmlTok. */ ! #define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) --- 215,221 ---- #endif /* XML_DTD */ ! /* This is used for performing a 2nd-level tokenization on the content ! of a literal that has already been returned by XmlTok. ! */ #define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) *************** *** 251,296 **** } INIT_ENCODING; ! int XmlParseXmlDecl(int isGeneralTextEntity, ! const ENCODING *enc, ! const char *ptr, ! const char *end, ! const char **badPtr, ! const char **versionPtr, ! const char **versionEndPtr, ! const char **encodingNamePtr, ! const ENCODING **namedEncodingPtr, ! int *standalonePtr); ! int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); ! const ENCODING *XmlGetUtf8InternalEncoding(void); ! const ENCODING *XmlGetUtf16InternalEncoding(void); ! int XmlUtf8Encode(int charNumber, char *buf); ! int XmlUtf16Encode(int charNumber, unsigned short *buf); ! int XmlSizeOfUnknownEncoding(void); ! ENCODING * XmlInitUnknownEncoding(void *mem, ! int *table, ! int (*conv)(void *userData, const char *p), ! void *userData); ! int XmlParseXmlDeclNS(int isGeneralTextEntity, ! const ENCODING *enc, ! const char *ptr, ! const char *end, ! const char **badPtr, ! const char **versionPtr, ! const char **versionEndPtr, ! const char **encodingNamePtr, ! const ENCODING **namedEncodingPtr, ! int *standalonePtr); ! int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); ! const ENCODING *XmlGetUtf8InternalEncodingNS(void); ! const ENCODING *XmlGetUtf16InternalEncodingNS(void); ! ENCODING * XmlInitUnknownEncodingNS(void *mem, ! int *table, ! int (*conv)(void *userData, const char *p), ! void *userData); #ifdef __cplusplus } --- 264,312 ---- } INIT_ENCODING; ! int XmlParseXmlDecl(int isGeneralTextEntity, ! const ENCODING *enc, ! const char *ptr, ! const char *end, ! const char **badPtr, ! const char **versionPtr, ! const char **versionEndPtr, ! const char **encodingNamePtr, ! const ENCODING **namedEncodingPtr, ! int *standalonePtr); ! int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); ! const ENCODING *XmlGetUtf8InternalEncoding(void); ! const ENCODING *XmlGetUtf16InternalEncoding(void); ! int FASTCALL XmlUtf8Encode(int charNumber, char *buf); ! int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); ! int XmlSizeOfUnknownEncoding(void); ! typedef int (*CONVERTER)(void *userData, const char *p); ! ! ENCODING * XmlInitUnknownEncoding(void *mem, ! int *table, ! CONVERTER convert, ! void *userData); ! int XmlParseXmlDeclNS(int isGeneralTextEntity, ! const ENCODING *enc, ! const char *ptr, ! const char *end, ! const char **badPtr, ! const char **versionPtr, ! const char **versionEndPtr, ! const char **encodingNamePtr, ! const ENCODING **namedEncodingPtr, ! int *standalonePtr); ! ! int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); ! const ENCODING *XmlGetUtf8InternalEncodingNS(void); ! const ENCODING *XmlGetUtf16InternalEncodingNS(void); ! ENCODING * XmlInitUnknownEncodingNS(void *mem, ! int *table, ! CONVERTER convert, ! void *userData); #ifdef __cplusplus } Index: xmltok_impl.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmltok_impl.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** xmltok_impl.c 11 Feb 2002 23:13:08 -0000 1.1.1.1 --- xmltok_impl.c 25 Jan 2003 22:41:29 -0000 1.2 *************** *** 1,5 **** ! /* ! Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ --- 1,4 ---- ! /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd ! See the file COPYING for copying permission. */ [...2084 lines suppressed...] while (ptr != end) { *************** *** 1749,1753 **** ptr += MINBPC(enc); if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) ! ptr += MINBPC(enc); pos->columnNumber = (unsigned)-1; break; --- 1759,1763 ---- ptr += MINBPC(enc); if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) ! ptr += MINBPC(enc); pos->columnNumber = (unsigned)-1; break; *************** *** 1767,1768 **** --- 1777,1779 ---- #undef CHECK_NMSTRT_CASE #undef CHECK_NMSTRT_CASES + Index: xmltok_ns.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmltok_ns.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** xmltok_ns.c 11 Feb 2002 23:13:08 -0000 1.1.1.1 --- xmltok_ns.c 25 Jan 2003 22:41:29 -0000 1.2 *************** *** 1,21 **** ! const ENCODING *NS(XmlGetUtf8InternalEncoding)(void) { return &ns(internal_utf8_encoding).enc; } ! const ENCODING *NS(XmlGetUtf16InternalEncoding)(void) { ! #if XML_BYTE_ORDER == 12 return &ns(internal_little2_encoding).enc; ! #elif XML_BYTE_ORDER == 21 return &ns(internal_big2_encoding).enc; #else const short n = 1; ! return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc; #endif } ! static ! const ENCODING *NS(encodings)[] = { &ns(latin1_encoding).enc, &ns(ascii_encoding).enc, --- 1,24 ---- ! const ENCODING * ! NS(XmlGetUtf8InternalEncoding)(void) { return &ns(internal_utf8_encoding).enc; } ! const ENCODING * ! NS(XmlGetUtf16InternalEncoding)(void) { ! #if BYTEORDER == 1234 return &ns(internal_little2_encoding).enc; ! #elif BYTEORDER == 4321 return &ns(internal_big2_encoding).enc; #else const short n = 1; ! return (*(const char *)&n ! ? &ns(internal_little2_encoding).enc ! : &ns(internal_big2_encoding).enc); #endif } ! static const ENCODING *NS(encodings)[] = { &ns(latin1_encoding).enc, &ns(ascii_encoding).enc, *************** *** 27,45 **** }; ! static ! int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, ! const char **nextTokPtr) { ! return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr); } ! static ! int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, ! const char **nextTokPtr) { ! return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr); } ! int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name) { int i = getEncodingIndex(name); --- 30,52 ---- }; ! static int PTRCALL ! NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, ! const char **nextTokPtr) { ! return initScan(NS(encodings), (const INIT_ENCODING *)enc, ! XML_PROLOG_STATE, ptr, end, nextTokPtr); } ! static int PTRCALL ! NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, ! const char **nextTokPtr) { ! return initScan(NS(encodings), (const INIT_ENCODING *)enc, ! XML_CONTENT_STATE, ptr, end, nextTokPtr); } ! int ! NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, ! const char *name) { int i = getEncodingIndex(name); *************** *** 55,60 **** } ! static ! const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { #define ENCODING_MAX 128 --- 62,67 ---- } ! static const ENCODING * ! NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { #define ENCODING_MAX 128 *************** *** 74,98 **** } ! int NS(XmlParseXmlDecl)(int isGeneralTextEntity, ! const ENCODING *enc, ! const char *ptr, ! const char *end, ! const char **badPtr, ! const char **versionPtr, ! const char **versionEndPtr, ! const char **encodingName, ! const ENCODING **encoding, ! int *standalone) { return doParseXmlDecl(NS(findEncoding), ! isGeneralTextEntity, ! enc, ! ptr, ! end, ! badPtr, ! versionPtr, ! versionEndPtr, ! encodingName, ! encoding, ! standalone); } --- 81,106 ---- } ! int ! NS(XmlParseXmlDecl)(int isGeneralTextEntity, ! const ENCODING *enc, ! const char *ptr, ! const char *end, ! const char **badPtr, ! const char **versionPtr, ! const char **versionEndPtr, ! const char **encodingName, ! const ENCODING **encoding, ! int *standalone) { return doParseXmlDecl(NS(findEncoding), ! isGeneralTextEntity, ! enc, ! ptr, ! end, ! badPtr, ! versionPtr, ! versionEndPtr, ! encodingName, ! encoding, ! standalone); } From loewis@users.sourceforge.net Sat Jan 25 22:46:13 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:46:13 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.624,1.625 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv753/Misc Modified Files: NEWS Log Message: Patch #636005: Filter unicode into unicode. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.624 retrieving revision 1.625 diff -C2 -d -r1.624 -r1.625 *** NEWS 24 Jan 2003 22:36:31 -0000 1.624 --- NEWS 25 Jan 2003 22:46:11 -0000 1.625 *************** *** 13,16 **** --- 13,18 ---- ----------------- + - filter returns now Unicode results for Unicode arguments. + - raw_input can now return Unicode objects. From loewis@users.sourceforge.net Sat Jan 25 22:46:13 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:46:13 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_builtin.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv753/Lib/test Modified Files: test_builtin.py Log Message: Patch #636005: Filter unicode into unicode. Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_builtin.py 19 Jan 2003 16:23:58 -0000 1.3 --- test_builtin.py 25 Jan 2003 22:46:11 -0000 1.4 *************** *** 366,369 **** --- 366,375 ---- raise ValueError self.assertRaises(ValueError, filter, lambda x: x >="3", badstr("1234")) + if have_unicode: + # test biltinmodule.c::filterstring() + self.assertEqual(filter(None, unicode("12")), unicode("12")) + self.assertEqual(filter(lambda x: x>="3", unicode("1234")), unicode("34")) + self.assertRaises(TypeError, filter, 42, unicode("12")) + self.assertRaises(ValueError, filter, lambda x: x >="3", badstr(unicode("1234"))) def test_float(self): From loewis@users.sourceforge.net Sat Jan 25 22:46:14 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:46:14 -0800 Subject: [Python-checkins] python/dist/src/Python bltinmodule.c,2.270,2.271 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv753/Python Modified Files: bltinmodule.c Log Message: Patch #636005: Filter unicode into unicode. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.270 retrieving revision 2.271 diff -C2 -d -r2.270 -r2.271 *** bltinmodule.c 4 Jan 2003 02:16:22 -0000 2.270 --- bltinmodule.c 25 Jan 2003 22:46:11 -0000 2.271 *************** *** 25,28 **** --- 25,31 ---- /* Forward */ static PyObject *filterstring(PyObject *, PyObject *); + #ifdef Py_USING_UNICODE + static PyObject *filterunicode(PyObject *, PyObject *); + #endif static PyObject *filtertuple (PyObject *, PyObject *); *************** *** 133,136 **** --- 136,143 ---- if (PyString_Check(seq)) return filterstring(func, seq); + #ifdef Py_USING_UNICODE + if (PyUnicode_Check(seq)) + return filterunicode(func, seq); + #endif if (PyTuple_Check(seq)) return filtertuple(func, seq); *************** *** 1927,1928 **** --- 1934,1990 ---- return NULL; } + + #ifdef Py_USING_UNICODE + /* Helper for filter(): filter a Unicode object through a function */ + + static PyObject * + filterunicode(PyObject *func, PyObject *strobj) + { + PyObject *result; + register int i, j; + int len = PyUnicode_GetSize(strobj); + + if (func == Py_None) { + /* No character is ever false -- share input string */ + Py_INCREF(strobj); + return strobj; + } + if ((result = PyUnicode_FromUnicode(NULL, len)) == NULL) + return NULL; + + for (i = j = 0; i < len; ++i) { + PyObject *item, *arg, *good; + int ok; + + item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i); + if (item == NULL) + goto Fail_1; + arg = Py_BuildValue("(O)", item); + if (arg == NULL) { + Py_DECREF(item); + goto Fail_1; + } + good = PyEval_CallObject(func, arg); + Py_DECREF(arg); + if (good == NULL) { + Py_DECREF(item); + goto Fail_1; + } + ok = PyObject_IsTrue(good); + Py_DECREF(good); + if (ok) + PyUnicode_AS_UNICODE((PyStringObject *)result)[j++] = + PyUnicode_AS_UNICODE((PyStringObject *)item)[0]; + Py_DECREF(item); + } + + if (j < len) + PyUnicode_Resize(&result, j); + + return result; + + Fail_1: + Py_DECREF(result); + return NULL; + } + #endif From loewis@users.sourceforge.net Sat Jan 25 22:48:54 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 25 Jan 2003 14:48:54 -0800 Subject: [Python-checkins] python/dist/src/Modules/expat xmlrole.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules/expat In directory sc8-pr-cvs1:/tmp/cvs-serv1363/Modules/expat Modified Files: xmlrole.c Log Message: Uncomment usage of expat_config.h Index: xmlrole.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmlrole.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** xmlrole.c 25 Jan 2003 22:41:29 -0000 1.4 --- xmlrole.c 25 Jan 2003 22:48:51 -0000 1.5 *************** *** 8,12 **** --- 8,14 ---- #include "macconfig.h" #else + /* Unused - MvL #include + */ #endif /* ndef COMPILED_FROM_DSP */ From tim_one@users.sourceforge.net Sat Jan 25 23:44:22 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 15:44:22 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv17068 Modified Files: pickletools.py Log Message: Fleshed out the two ways to pickle floats. It's best not to think too much about all the ways this can screw up <0.6 wink>. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pickletools.py 25 Jan 2003 22:32:08 -0000 1.2 --- pickletools.py 25 Jan 2003 23:44:19 -0000 1.3 *************** *** 223,226 **** --- 223,283 ---- """) + + def read_floatnl(f): + """ + >>> import StringIO + >>> read_floatnl(StringIO.StringIO("-1.25\\n6")) + -1.25 + """ + s = read_stringnl(f, decode=False) + return float(s) + + floatnl = ArgumentDescriptor( + name='floatnl', + n=None, + reader=read_floatnl, + doc="""A newline-terminated decimal floating literal. + + In general this requires 17 significant digits for roundtrip + identity, and pickling then unpickling infinities, NaNs, and + minus zero doesn't work across boxes, or on some boxes even + on itself (e.g., Windows can't read the strings it produces + for infinities or NaNs). + """) + + def read_float8(f): + """ + >>> import StringIO, struct + >>> raw = struct.pack(">d", -1.25) + >>> raw + '\\xbf\\xf4\\x00\\x00\\x00\\x00\\x00\\x00' + >>> read_float8(StringIO.StringIO(raw + "\\n")) + -1.25 + """ + + data = f.read(8) + if len(data) == 8: + return _unpack(">d", data)[0] + raise ValueError("not enough data in stream to read float8") + + + float8 = ArgumentDescriptor( + name='float8', + n=8, + reader=read_float8, + doc="""An 8-byte binary representation of a float, big-endian. + + The format is unique to Python, and shared with the struct + module (format string '>d') "in theory" (the struct and cPickle + implementations don't share the code -- they should). It's + strongly related to the IEEE-754 double format, and, in normal + cases, is in fact identical to the big-endian 754 double format. + On other boxes the dynamic range is limited to that of a 754 + double, and "add a half and chop" rounding is used to reduce + the precision to 53 bits. However, even on a 754 box, + infinities, NaNs, and minus zero may not be handled correctly + (may not survive roundtrip pickling intact). + """) + ############################################################################## # Python object descriptors. The stack used by the pickle machine holds *************** *** 268,271 **** --- 325,332 ---- doc="A Python integer object, short or long.") + pyfloat = PythonObject( + name='float', + obtype=float, + doc="A Python float object.") ############################################################################## *************** *** 392,395 **** --- 453,494 ---- """), + # Two ways to spell floats. + + I(name='FLOAT', + code='F', + args=[floatnl], + stack_before=[], + stack_after=[pyfloat], + proto=0, + doc="""Newline-terminated decimal float literal. + + The argument is repr(a_float), and in general requires 17 significant + digits for roundtrip conversion to be an identity (this is so for + IEEE-754 double precision values, which is what Python float maps to + on most boxes). + + In general, FLOAT cannot be used to transport infinities, NaNs, or + minus zero across boxes (or even on a single box, if the platform C + library can't read the strings it produces for such things -- Windows + is like that), but may do less damage than BINFLOAT on boxes with + greater precision or dynamic range than IEEE-754 double. + """), + + I(name='BINFLOAT', + code='G', + args=[float8], + stack_before=[], + stack_after=[pyfloat], + proto=1, + doc="""Float stored in binary form, with 8 bytes of data. + + This generally requires less than half the space of FLOAT encoding. + In general, BINFLOAT cannot be used to transport infinities, NaNs, or + minus zero, raises an exception if the exponent exceeds the range of + an IEEE-754 double, and retains no more than 53 bits of precision (if + there are more than that, "add a half and chop" rounding is used to + cut it back to 53 significant bits). + """), + # XXX opcodes below this point haven't been done yet. *************** *** 449,463 **** """), - I(name='FLOAT', - code='F', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - I(name='NONE', code='N', --- 548,551 ---- *************** *** 770,784 **** I(name='SETITEMS', code='u', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='BINFLOAT', - code='G', args=[], stack_before=[], --- 858,861 ---- From tim_one@users.sourceforge.net Sat Jan 25 23:45:50 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 15:45:50 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv17698 Modified Files: pickletools.py Log Message: Typo repair. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pickletools.py 25 Jan 2003 23:44:19 -0000 1.3 --- pickletools.py 25 Jan 2003 23:45:48 -0000 1.4 *************** *** 214,218 **** decimalnl_long = ArgumentDescriptor( ! name='decimalnl_short', n=None, reader=read_decimalnl_long, --- 214,218 ---- decimalnl_long = ArgumentDescriptor( ! name='decimalnl_long', n=None, reader=read_decimalnl_long, From nnorwitz@users.sourceforge.net Sun Jan 26 02:14:25 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sat, 25 Jan 2003 18:14:25 -0800 Subject: [Python-checkins] python/dist/src/Lib/logging handlers.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1:/tmp/cvs-serv24327/Lib/logging Modified Files: handlers.py Log Message: SF #642974, logging SysLogHandler proto type wrong Syslog uses UDP (SOCK_DGRAM) Index: handlers.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/handlers.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** handlers.py 13 Nov 2002 16:18:29 -0000 1.2 --- handlers.py 26 Jan 2003 02:14:23 -0000 1.3 *************** *** 349,353 **** self.facility = facility if type(address) == types.StringType: ! self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.socket.connect(address) self.unixsocket = 1 --- 349,353 ---- self.facility = facility if type(address) == types.StringType: ! self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) self.socket.connect(address) self.unixsocket = 1 From tim_one@users.sourceforge.net Sun Jan 26 02:43:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 18:43:40 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv32471 Modified Files: pickletools.py Log Message: s/PythonObject/StackObject/g. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pickletools.py 25 Jan 2003 23:45:48 -0000 1.4 --- pickletools.py 26 Jan 2003 02:43:38 -0000 1.5 *************** *** 281,290 **** ############################################################################## ! # Python object descriptors. The stack used by the pickle machine holds ! # Python objects, and in the stack_before and stack_after attributes of ! # OpcodeInfo descriptors we need names to describe the various types ! # of Python objects that can appear on the stack. ! class PythonObject(object): __slots__ = ( # name of descriptor record, also a module global name; a string --- 281,290 ---- ############################################################################## ! # Object descriptors. The stack used by the pickle machine holds objects, ! # and in the stack_before and stack_after attributes of OpcodeInfo ! # descriptors we need names to describe the various types of objects that can ! # appear on the stack. ! class StackObject(object): __slots__ = ( # name of descriptor record, also a module global name; a string *************** *** 304,307 **** --- 304,310 ---- assert isinstance(obtype, type) or isinstance(obtype, tuple) + if isinstance(obtype, tuple): + for contained in obtype: + assert isinstance(contained, type) self.obtype = obtype *************** *** 310,329 **** ! pyint = PythonObject( name='int', obtype=int, doc="A short (as opposed to long) Python integer object.") ! pylong = PythonObject( name='long', obtype=long, doc="A long (as opposed to short) Python integer object.") ! pyinteger = PythonObject( name='integer', obtype=(int, long), doc="A Python integer object, short or long.") ! pyfloat = PythonObject( name='float', obtype=float, --- 313,332 ---- ! pyint = StackObject( name='int', obtype=int, doc="A short (as opposed to long) Python integer object.") ! pylong = StackObject( name='long', obtype=long, doc="A long (as opposed to short) Python integer object.") ! pyinteger = StackObject( name='integer', obtype=(int, long), doc="A Python integer object, short or long.") ! pyfloat = StackObject( name='float', obtype=float, *************** *** 368,377 **** --- 371,386 ---- assert isinstance(args, list) + for x in args: + assert isinstance(x, ArgumentDescriptor) self.args = args assert isinstance(stack_before, list) + for x in stack_before: + assert isinstance(x, StackObject) self.stack_before = stack_before assert isinstance(stack_after, list) + for x in stack_after: + assert isinstance(x, StackObject) self.stack_after = stack_after From nnorwitz@users.sourceforge.net Sun Jan 26 02:45:50 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sat, 25 Jan 2003 18:45:50 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.625,1.626 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv642/Misc Modified Files: NEWS Log Message: SF #642974, logging SysLogHandler proto type wrong Syslog uses UDP (SOCK_DGRAM) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.625 retrieving revision 1.626 diff -C2 -d -r1.625 -r1.626 *** NEWS 25 Jan 2003 22:46:11 -0000 1.625 --- NEWS 26 Jan 2003 02:45:47 -0000 1.626 *************** *** 148,151 **** --- 148,154 ---- the gain value which is passed to Tk. SF bug# 602259. + - Fix logging.handlers.SysLogHandler protocol when using UNIX domain sockets. + See SF patch #642974. + Tools/Demos ----------- From tim_one@users.sourceforge.net Sun Jan 26 03:06:48 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 19:06:48 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv6684 Modified Files: pickletools.py Log Message: Did the stack manipulation opcodes. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pickletools.py 26 Jan 2003 02:43:38 -0000 1.5 --- pickletools.py 26 Jan 2003 03:06:46 -0000 1.6 *************** *** 333,336 **** --- 333,373 ---- doc="A Python float object.") + anyobject = StackObject( + name='any', + obtype=object, + doc="Any kind of object whatsoever.") + + markobject = StackObject( + name="mark", + obtype=StackObject, + doc="""'The mark' is a unique object. + + Opcodes that operate on a variable number of objects + generally don't embed the count of objects in the opcode, + or pull it off the stack. Instead the MARK opcode is used + to push a special marker object on the stack, and then + some other opcodes grab all the objects from the top of + the stack down to (but not including) the topmost marker + object. + """) + + stackslice = StackObject( + name="stackslice", + obtype=StackObject, + doc="""An object representing a contiguous slice of the stack. + + This is used in conjuction with markobject, to represent all + of the stack following the topmost markobject. For example, + the POP_MARK opcode changes the stack from + + [..., markobject, stackslice] + to + [...] + + No matter how many object are on the stack after the topmost + markobject, POP_MARK gets rid of all of them (including the + topmost markobject too). + """) + ############################################################################## # Descriptors for pickle opcodes. *************** *** 500,536 **** """), ! # XXX opcodes below this point haven't been done yet. ! I(name='MARK', ! code='(', args=[], ! stack_before=[], stack_after=[], proto=0, ! doc="""XXX One-line description goes here. ! ! XXX Doc body goes here. ! """), ! I(name='STOP', ! code='.', args=[], ! stack_before=[], ! stack_after=[], proto=0, ! doc="""XXX One-line description goes here. ! ! XXX Doc body goes here. ! """), ! I(name='POP', ! code='0', args=[], stack_before=[], ! stack_after=[], proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), --- 537,569 ---- """), ! # Stack manipulation. ! I(name='POP', ! code='0', args=[], ! stack_before=[anyobject], stack_after=[], proto=0, ! doc="Discard the top stack item."), ! I(name='DUP', ! code='2', args=[], ! stack_before=[anyobject], ! stack_after=[anyobject, anyobject], proto=0, ! doc="Push the top stack item onto the stack again, duplicating it."), ! I(name='MARK', ! code='(', args=[], stack_before=[], ! stack_after=[markobject], proto=0, ! doc="""Push a marker object onto the stack. ! The marker is a unique object, used by other opcodes to identify a ! region of the stack containing a variable number of objects for them ! to work on. See markobject.doc for more detail. """), *************** *** 538,551 **** code='1', args=[], ! stack_before=[], stack_after=[], proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), ! I(name='DUP', ! code='2', args=[], stack_before=[], --- 571,588 ---- code='1', args=[], ! stack_before=[markobject, stackslice], stack_after=[], proto=0, ! doc="""Pop all the stack objects at and above the topmost marker object. ! When an opcode using a variable number of stack objects is done, ! POP_MARK is used to remove those objects, and to remove the marker ! object that delimited their starting position on the stack. """), ! # XXX opcodes below this point haven't been done yet. ! ! I(name='STOP', ! code='.', args=[], stack_before=[], From rhettinger@users.sourceforge.net Sun Jan 26 03:29:18 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 25 Jan 2003 19:29:18 -0800 Subject: [Python-checkins] python/dist/src/Misc cheatsheet,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv12621 Modified Files: cheatsheet Log Message: Part 3 of Py2.3 update Index: cheatsheet =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/cheatsheet,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** cheatsheet 25 Jan 2003 22:35:42 -0000 1.4 --- cheatsheet 26 Jan 2003 03:29:15 -0000 1.5 *************** *** 209,213 **** +x, -x, ~x Unary operators x**y Power ! x*y x/y x%y mult, division, modulo x+y x-y addition, substraction x<>y Bit shifting --- 209,213 ---- +x, -x, ~x Unary operators x**y Power ! x*y x/y x%y x//y mult, division, modulo, floor division x+y x-y addition, substraction x<>y Bit shifting *************** *** 333,336 **** --- 333,338 ---- ZeroDivisionError raised when zero second argument of div or modulo op + FloatingPointError + raised when a floating point operation fails Operations on all sequence types (lists, tuples, strings) *************** *** 338,343 **** Operations on all sequence types Operation Result Notes ! x in s 1 if an item of s is equal to x, else 0 ! x not in s 0 if an item of s is equal to x, else 1 for x in s: loops over the sequence s + t the concatenation of s and t --- 340,345 ---- Operations on all sequence types Operation Result Notes ! x in s True if an item of s is equal to x, else False ! x not in s False if an item of s is equal to x, else True for x in s: loops over the sequence s + t the concatenation of s and t *************** *** 369,373 **** s.append(x) same as s[len(s) : len(s)] = [x] s.count(x) return number of i's for which s[i] == x ! s.extend(x) same as s[len(s):len(s)]= x s.index(x) return smallest i such that s[i] == x (1) s.insert(i, x) same as s[i:i] = [x] if i >= 0 --- 371,375 ---- s.append(x) same as s[len(s) : len(s)] = [x] s.count(x) return number of i's for which s[i] == x ! s.extend(x) same as s[len(s):len(s)]= x s.index(x) return smallest i such that s[i] == x (1) s.insert(i, x) same as s[i:i] = [x] if i >= 0 *************** *** 405,409 **** d.copy() a shallow copy of d d.get(k,defaultval) the item of d with key k (4) ! d.has_key(k) 1 if d has key k, else 0 d.items() a copy of d's list of (key, item) pairs (2) d.iteritems() an iterator over (key, value) pairs (7) --- 407,411 ---- d.copy() a shallow copy of d d.get(k,defaultval) the item of d with key k (4) ! d.has_key(k) True if d has key k, else False d.items() a copy of d's list of (key, item) pairs (2) d.iteritems() an iterator over (key, value) pairs (7) *************** *** 600,604 **** f.fileno() Get fileno (fd) for file f. f.flush() Flush file f's internal buffer. ! f.isatty() 1 if file f is connected to a tty-like dev, else 0. f.read([size]) Read at most size bytes from file f and return as a string object. If size omitted, read to EOF. --- 602,606 ---- f.fileno() Get fileno (fd) for file f. f.flush() Flush file f's internal buffer. ! f.isatty() True if file f is connected to a tty-like dev, else False. f.read([size]) Read at most size bytes from file f and return as a string object. If size omitted, read to EOF. *************** *** 620,624 **** tty). IOError ! Other I/O-related I/O operation failure --- 622,628 ---- tty). IOError ! Other I/O-related I/O operation failure. ! OSError ! OS system call failed. *************** *** 718,721 **** --- 722,729 ---- return [result] -- Exits from function (or method) and returns result (use a tuple to return more than one value). If no result given, then returns None. + yield result -- Freezes the execution frame of a generator and returns the result + to the iterator's .next() method. Upon the next call to next(), + resumes execution at the frozen point with all of the local variables + still intact. Exception Statements *************** *** 920,925 **** apply(f, args[, Calls func/method f with arguments args and optional keywords]) keywords. ! callable(x) Returns 1 if x callable, else 0. chr(i) Returns one-character string whose ASCII code isinteger i cmp(x,y) Returns negative, 0, positive if x <, ==, > to y coerce(x,y) Returns a tuple of the two numeric arguments converted to a --- 928,937 ---- apply(f, args[, Calls func/method f with arguments args and optional keywords]) keywords. ! bool(x) Returns True when the argument x is true and False otherwise. ! buffer(obj) Creates a buffer reference to an object. ! callable(x) Returns True if x callable, else False. chr(i) Returns one-character string whose ASCII code isinteger i + classmethod(f) Converts a function f, into a method with the class as the + first argument. Useful for creating alternative constructors. cmp(x,y) Returns negative, 0, positive if x <, ==, > to y coerce(x,y) Returns a tuple of the two numeric arguments converted to a *************** *** 935,942 **** --- 947,956 ---- delattr(obj, name) deletes attribute named name of object obj <=> del obj.name If no args, returns the list of names in current + dict([items]) Create a new dictionary from the specified item list. dir([object]) localsymbol table. With a module, class or class instanceobject as arg, returns list of names in its attr. dict. divmod(a,b) Returns tuple of (a/b, a%b) + enumerate(seq) Return a iterator giving: (0, seq[0]), (1, seq[1]), ... eval(s[, globals[, Eval string s in (optional) globals, locals contexts.s must locals]]) have no NUL's or newlines. s can also be acode object. *************** *** 944,947 **** --- 958,962 ---- execfile(file[, Executes a file without creating a new module, unlike globals[, locals]]) import. + file() Synonym for open(). filter(function, Constructs a list from those elements of sequence for which sequence) function returns true. function takes one parameter. *************** *** 954,957 **** --- 969,973 ---- name) hash(object) Returns the hash value of the object (if it has one) + help(f) Display documentation on object f. hex(x) Converts a number x to a hexadecimal string. id(object) Returns a unique 'identity' integer for an object. *************** *** 967,970 **** --- 983,987 ---- class2) Returns the length (the number of items) of an object + iter(collection) Returns an iterator over the collection. len(obj) (sequence, dictionary, or instance of class implementing __len__). *************** *** 988,992 **** --- 1005,1014 ---- ord(c) Returns integer ASCII value of c (a string of len 1). Works with Unicode char. + object() Create a base type. Used as a superclass for new-style objects. + open(name Open a file. + [, mode + [, buffering]]) pow(x, y [, z]) Returns x to power y [modulo z]. See also ** operator. + property() Created a property with access controlled by functions. range(start [,end Returns list of ints from >= start and < end.With 1 arg, [, step]]) list from 0..arg-1With 2 args, list from start..end-1With 3 *************** *** 1013,1018 **** --- 1035,1045 ---- [, step]) Oattributes: start, stop, step. Returns a string containing a nicely + staticmethod() Convert a function to method with no self or class + argument. Useful for methods associated with a class that + do not need access to an object's internal state. str(object) printablerepresentation of an object. Class overridable (__str__).See also repr(). + super(type) Create an unbound super object. Used to call cooperative + superclass methods. tuple(sequence) Creates a tuple with same elements as sequence. If already a tuple, return itself (not a copy). *************** *** 1046,1049 **** --- 1073,1078 ---- SystemExit On 'sys.exit()' + StopIteration + Signal the end from iterator.next() StandardError Base class for all built-in exceptions; derived from Exception *************** *** 1100,1103 **** --- 1129,1140 ---- ValueError On arg error not covered by TypeError or more precise + Warning + UserWarning + DeprecationWarning + PendingDeprecationWarning + SyntaxWarning + OverflowWarning + RuntimeWarning + FutureWarning *************** *** 1123,1127 **** Implements >, <, == etc... __hash__(s) Compute a 32 bit hash code; hash() and dictionary ops ! __nonzero__(s) Returns 0 or 1 for truth value testing __getattr__(s, name) called when attr lookup doesn't find __setattr__(s, name, val) called when setting an attr --- 1160,1164 ---- Implements >, <, == etc... __hash__(s) Compute a 32 bit hash code; hash() and dictionary ops ! __nonzero__(s) Returns False or True for truth value testing __getattr__(s, name) called when attr lookup doesn't find __setattr__(s, name, val) called when setting an attr *************** *** 1189,1195 **** Special informative state attributes for some types: - Lists & Dictionaries: - __methods__ (list, R/O): list of method names of the object - Modules: __doc__ (string/None, R/O): doc string (<=> __dict__['__doc__']) --- 1226,1229 ---- *************** *** 1198,1205 **** __file__(string/undefined, R/O): pathname of .pyc, .pyo or .pyd (undef for modules statically linked to the interpreter) - __path__(string/undefined, R/O): fully qualified package name when applies. Classes: [in bold: writable since 1.5.2] __doc__ (string/None, R/W): doc string (<=> __dict__['__doc__']) __name__(string, R/W): class name (also in __dict__['__name__']) __bases__ (tuple, R/W): parent classes --- 1232,1239 ---- __file__(string/undefined, R/O): pathname of .pyc, .pyo or .pyd (undef for modules statically linked to the interpreter) Classes: [in bold: writable since 1.5.2] __doc__ (string/None, R/W): doc string (<=> __dict__['__doc__']) + __module__ is the module name in which the class was defined __name__(string, R/W): class name (also in __dict__['__name__']) __bases__ (tuple, R/W): parent classes *************** *** 1209,1212 **** --- 1243,1247 ---- __class__ (class, R/W): instance's class __dict__ (dict, R/W): attributes + User-defined functions: [bold: writable since 1.5.2] __doc__ (string/None, R/W): doc string *************** *** 1217,1220 **** --- 1252,1260 ---- func_code (code, R/W): code object representing the compiled function body func_globals (dict, R/O): ref to dictionary of func global variables + func_dict (dict, R/W): same as __dict__ contains the namespace supporting + arbitrary function attributes + func_closure (R/O): None or a tuple of cells that contain bindings + for the function's free variables. + User-defined Methods: *************** *** 1224,1232 **** im_self (instance/None, R/O): target instance object (None if unbound) im_func (function, R/O): function object Built-in Functions & methods: __doc__ (string/None, R/O): doc string __name__ (string, R/O): function name __self__ : [methods only] target object ! __members__ = list of attr names: ['__doc__','__name__','__self__']) Codes: co_name (string, R/O): function name --- 1264,1273 ---- im_self (instance/None, R/O): target instance object (None if unbound) im_func (function, R/O): function object + Built-in Functions & methods: __doc__ (string/None, R/O): doc string __name__ (string, R/O): function name __self__ : [methods only] target object ! Codes: co_name (string, R/O): function name *************** *** 1234,1237 **** --- 1275,1281 ---- co_nlocals (int, R/O): number of local vars (including args) co_varnames (tuple, R/O): names of local vars (starting with args) + co_cellvars (tuple, R/O)) the names of local variables referenced by + nested functions + co_freevars (tuple, R/O)) names of free variables co_code (string, R/O): sequence of bytecode instructions co_consts (tuple, R/O): litterals used by the bytecode, 1st one is *************** *** 1242,1246 **** co_lnotab (string, R/O): string encoding bytecode offsets to line numbers. co_stacksize (int, R/O): required stack size (including local vars) - co_firstlineno (int, R/O): first line number of the function co_flags (int, R/O): flags for the interpreter bit 2 set if fct uses "*arg" syntax --- 1286,1289 ---- *************** *** 1275,1280 **** real (float, R/O): real part imag (float, R/O): imaginary part - XRanges: - tolist (Built-in method, R/O): ? --- 1318,1321 ---- *************** *** 1317,1325 **** exit(n) Exits with status n. Raises SystemExit exception.(Hence can be caught and ignored by program) ! getrefcount(object Returns the reference count of the object. Generally 1 ! ) higherthan you might expect, because of object arg temp reference. setcheckinterval( Sets the interpreter's thread switching interval (in number ! interval) ofvirtualcode instructions, default:10). settrace(func) Sets a trace function: called before each line ofcode is exited. --- 1358,1366 ---- exit(n) Exits with status n. Raises SystemExit exception.(Hence can be caught and ignored by program) ! getrefcount(object Returns the reference count of the object. Generally one ! ) higher than you might expect, because of object arg temp reference. setcheckinterval( Sets the interpreter's thread switching interval (in number ! interval) of virtual code instructions, default:10). settrace(func) Sets a trace function: called before each line ofcode is exited. *************** *** 1328,1332 **** (exc_type, exc_value, exc_traceback).Warning: assigning the exc_info() traceback return value to a loca variable in a ! functionhandling an exception will cause a circular reference. setdefaultencoding Change default Unicode encoding - defaults to 7-bit ASCII. --- 1369,1373 ---- (exc_type, exc_value, exc_traceback).Warning: assigning the exc_info() traceback return value to a loca variable in a ! function handling an exception will cause a circular reference. setdefaultencoding Change default Unicode encoding - defaults to 7-bit ASCII. *************** *** 1755,1758 **** --- 1796,1800 ---- cos(x) cosh(x) + degrees(x) exp(x) fabs(x) *************** *** 1761,1768 **** frexp(x) -- Unlike C: (float, int) = frexp(float) ldexp(x, y) ! log(x) log10(x) modf(x) -- Unlike C: (float, float) = modf(float) pow(x, y) sin(x) sinh(x) --- 1803,1811 ---- frexp(x) -- Unlike C: (float, int) = frexp(float) ldexp(x, y) ! log(x [,base]) log10(x) modf(x) -- Unlike C: (float, float) = modf(float) pow(x, y) + radians(x) sin(x) sinh(x) *************** *** 1805,1815 **** binhex Macintosh binhex compression/decompression. bisect List bisection algorithms. ! bz2 Support for bz2 compression/decompression. calendar Calendar printing functions. cgi Wraps the WWW Forms Common Gateway Interface (CGI). ! cgitb Utility for handling CGI tracebacks. CGIHTTPServer CGI http services. cmd A generic class to build line-oriented command interpreters. ! datetime Basic date and time types. code Utilities needed to emulate Python's interactive interpreter codecs Lookup existing Unicode encodings and register new ones. --- 1848,1858 ---- binhex Macintosh binhex compression/decompression. bisect List bisection algorithms. ! bz2 Support for bz2 compression/decompression. calendar Calendar printing functions. cgi Wraps the WWW Forms Common Gateway Interface (CGI). ! cgitb Utility for handling CGI tracebacks. CGIHTTPServer CGI http services. cmd A generic class to build line-oriented command interpreters. ! datetime Basic date and time types. code Utilities needed to emulate Python's interactive interpreter codecs Lookup existing Unicode encodings and register new ones. *************** *** 1823,1834 **** dircache Sorted list of files in a dir, using a cache. [DEL:dircmp:DEL] [DEL:Defines a class to build directory diff tools on.:DEL] ! difflib Tool for creating delta between sequences. dis Bytecode disassembler. distutils Package installation system. ! doctest Tool for running and verifying tests inside doc strings. dospath Common operations on DOS pathnames. dumbdbm A dumb and slow but simple dbm clone. [DEL:dump:DEL] [DEL:Print python code that reconstructs a variable.:DEL] ! email Comprehensive support for internet email. exceptions Class based built-in exception hierarchy. filecmp File comparison. --- 1866,1877 ---- dircache Sorted list of files in a dir, using a cache. [DEL:dircmp:DEL] [DEL:Defines a class to build directory diff tools on.:DEL] ! difflib Tool for creating delta between sequences. dis Bytecode disassembler. distutils Package installation system. ! doctest Tool for running and verifying tests inside doc strings. dospath Common operations on DOS pathnames. dumbdbm A dumb and slow but simple dbm clone. [DEL:dump:DEL] [DEL:Print python code that reconstructs a variable.:DEL] ! email Comprehensive support for internet email. exceptions Class based built-in exception hierarchy. filecmp File comparison. *************** *** 1849,1857 **** [DEL:grep:DEL] [DEL:'grep' utilities.:DEL] gzip Read & write gzipped files. ! heapq Priority queue implemented using lists organized as heaps. ! HMAC Keyed-Hashing for Message Authentication -- RFC 2104. htmlentitydefs Proposed entity definitions for HTML. htmllib HTML parsing utilities. ! HTMLParser A parser for HTML and XHTML. httplib HTTP client class. ihooks Hooks into the "import" mechanism. --- 1892,1900 ---- [DEL:grep:DEL] [DEL:'grep' utilities.:DEL] gzip Read & write gzipped files. ! heapq Priority queue implemented using lists organized as heaps. ! HMAC Keyed-Hashing for Message Authentication -- RFC 2104. htmlentitydefs Proposed entity definitions for HTML. htmllib HTML parsing utilities. ! HTMLParser A parser for HTML and XHTML. httplib HTTP client class. ihooks Hooks into the "import" mechanism. *************** *** 1859,1863 **** imghdr Recognizing image files based on their first few bytes. imputil Privides a way of writing customised import hooks. ! inspect Tool for probing live Python objects. keyword List of Python keywords. knee A Python re-implementation of hierarchical module import. --- 1902,1906 ---- imghdr Recognizing image files based on their first few bytes. imputil Privides a way of writing customised import hooks. ! inspect Tool for probing live Python objects. keyword List of Python keywords. knee A Python re-implementation of hierarchical module import. *************** *** 1866,1870 **** locale Support for number formatting using the current locale settings. ! logging Python logging facility. macpath Pathname (or related) operations for the Macintosh. macurl2path Mac specific module for conversion between pathnames and URLs. --- 1909,1913 ---- locale Support for number formatting using the current locale settings. ! logging Python logging facility. macpath Pathname (or related) operations for the Macintosh. macurl2path Mac specific module for conversion between pathnames and URLs. *************** *** 1884,1888 **** ntpath Common operations on DOS pathnames. nturl2path Mac specific module for conversion between pathnames and URLs. ! optparse A comprehensive tool for processing command line options. os Either mac, dos or posix depending system. [DEL:packmail: [DEL:Create a self-unpacking shell archive.:DEL] --- 1927,1931 ---- ntpath Common operations on DOS pathnames. nturl2path Mac specific module for conversion between pathnames and URLs. ! optparse A comprehensive tool for processing command line options. os Either mac, dos or posix depending system. [DEL:packmail: [DEL:Create a self-unpacking shell archive.:DEL] *************** *** 1892,1896 **** Cimplementation exists in built-in module: cPickle). pipes Conversion pipeline templates. ! pkgunil Utilities for working with Python packages. popen2 variations on pipe open. poplib A POP3 client class. Based on the J. Myers POP3 draft. --- 1935,1939 ---- Cimplementation exists in built-in module: cPickle). pipes Conversion pipeline templates. ! pkgunil Utilities for working with Python packages. popen2 variations on pipe open. poplib A POP3 client class. Based on the J. Myers POP3 draft. *************** *** 1901,1905 **** profile Class for profiling python code. pstats Class for printing reports on profiled python code. ! pydoc Utility for generating documentation from source files. pty Pseudo terminal utilities. pyexpat Interface to the Expay XML parser. --- 1944,1948 ---- profile Class for profiling python code. pstats Class for printing reports on profiled python code. ! pydoc Utility for generating documentation from source files. pty Pseudo terminal utilities. pyexpat Interface to the Expay XML parser. *************** *** 1919,1923 **** robotparser Parse robot.txt files, useful for web spiders. sched A generally useful event scheduler class. ! sets Module for a set datatype. sgmllib A parser for SGML. shelve Manage shelves of pickled objects. --- 1962,1966 ---- robotparser Parse robot.txt files, useful for web spiders. sched A generally useful event scheduler class. ! sets Module for a set datatype. sgmllib A parser for SGML. shelve Manage shelves of pickled objects. *************** *** 1941,1948 **** symbol Non-terminal symbols of Python grammar (from "graminit.h"). tabnanny,/font> Check Python source for ambiguous indentation. ! tarfile Facility for reading and writing to the *nix tarfile format. telnetlib TELNET client class. Based on RFC 854. tempfile Temporary file name allocation. ! textwrap Object for wrapping and filling text. threading Proposed new higher-level threading interfaces threading_api (doc of the threading module) --- 1984,1991 ---- symbol Non-terminal symbols of Python grammar (from "graminit.h"). tabnanny,/font> Check Python source for ambiguous indentation. ! tarfile Facility for reading and writing to the *nix tarfile format. telnetlib TELNET client class. Based on RFC 854. tempfile Temporary file name allocation. ! textwrap Object for wrapping and filling text. threading Proposed new higher-level threading interfaces threading_api (doc of the threading module) *************** *** 1964,1970 **** [DEL:util:DEL] [DEL:some useful functions that don't fit elsewhere !!:DEL] uu UUencode/UUdecode. ! unittest Utilities for implementing unit testing. wave Stuff to parse WAVE files. ! weakref Tools for creating and managing weakly referenced objects. webbrowser Platform independent URL launcher. [DEL:whatsound: [DEL:Several routines that help recognizing sound files.:DEL] --- 2007,2013 ---- [DEL:util:DEL] [DEL:some useful functions that don't fit elsewhere !!:DEL] uu UUencode/UUdecode. ! unittest Utilities for implementing unit testing. wave Stuff to parse WAVE files. ! weakref Tools for creating and managing weakly referenced objects. webbrowser Platform independent URL launcher. [DEL:whatsound: [DEL:Several routines that help recognizing sound files.:DEL] *************** *** 1976,1980 **** xml.dom Classes for processing XML using the Document Object Model. xml.sax Classes for processing XML using the SAX API. ! xmlrpclib Support for remote procedure calls using XML. zipfile Read & write PK zipped files. [DEL:zmod:DEL] [DEL:Demonstration of abstruse mathematical concepts.:DEL] --- 2019,2023 ---- xml.dom Classes for processing XML using the Document Object Model. xml.sax Classes for processing XML using the SAX API. ! xmlrpclib Support for remote procedure calls using XML. zipfile Read & write PK zipped files. [DEL:zmod:DEL] [DEL:Demonstration of abstruse mathematical concepts.:DEL] *************** *** 1982,1987 **** - (following list not revised) - * Built-ins * --- 2025,2028 ---- *************** *** 1991,1995 **** array Obj efficiently representing arrays of basic values math Math functions of C standard ! time Time-related functions regex Regular expression matching operations marshal Read and write some python values in binary format --- 2032,2036 ---- array Obj efficiently representing arrays of basic values math Math functions of C standard ! time Time-related functions (also the newer datetime module) regex Regular expression matching operations marshal Read and write some python values in binary format *************** *** 2002,2006 **** re Functions useful for working with regular expressions string Useful string and characters functions and exceptions ! whrandom Wichmann-Hill pseudo-random number generator thread Low-level primitives for working with process threads threading idem, new recommanded interface. --- 2043,2047 ---- re Functions useful for working with regular expressions string Useful string and characters functions and exceptions ! random Mersenne Twister pseudo-random number generator thread Low-level primitives for working with process threads threading idem, new recommanded interface. *************** *** 2031,2035 **** md5 Interface to RSA's MD5 message digest algorithm mpz Interface to int part of GNU multiple precision library ! rotor Implementation of a rotor-based encryption algorithm * Stdwin * Standard Window System --- 2072,2077 ---- md5 Interface to RSA's MD5 message digest algorithm mpz Interface to int part of GNU multiple precision library ! rotor Implementation of a rotor-based encryption algorithm ! HMAC Keyed-Hashing for Message Authentication -- RFC 2104. * Stdwin * Standard Window System *************** *** 2061,2066 **** dir() list functions, variables in dir() get object keys, defaults to local name space - X.__methods__ list of methods supported by X (if any) - X.__members__ List of X's data attributes if __name__ == '__main__': main() invoke main if running as script map(None, lst1, lst2, ...) merge lists --- 2103,2106 ---- *************** *** 2108,2111 **** --- 2148,2153 ---- C-c ! starts a Python interpreter window; this will be used by subsequent C-c C-c or C-c | commands + C-c C-w runs PyChecker + VARIABLES py-indent-offset indentation increment *************** *** 2170,2173 **** --- 2212,2217 ---- c, continue continue until next breakpoint + j, jump lineno + Set the next line that will be executed a, args print args to current function From tim_one@users.sourceforge.net Sun Jan 26 03:58:08 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 19:58:08 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv20206 Modified Files: pickletools.py Log Message: Added general blurbs about the pickle machine, and about pickle protocols. Added an UP_TO_NEWLINE "number of bytes" value, for use in ArgumentDescriptor objects. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pickletools.py 26 Jan 2003 03:06:46 -0000 1.6 --- pickletools.py 26 Jan 2003 03:58:06 -0000 1.7 *************** *** 12,15 **** --- 12,98 ---- + """ + "A pickle" is a program for a virtual pickle machine (PM, but more accurately + called an unpickling machine). It's a sequence of opcodes, interpreted by the + PM, building an arbitrarily complex Python object. + + For the most part, the PM is very simple: there are no looping, testing, or + conditional instructions, no arithmetic and no function calls. Opcodes are + executed once each, from first to last, until a STOP opcode is reached. + + The PM has two data areas, "the stack" and "the memo". + + Many opcodes push Python objects onto the stack; e.g., INT pushes a Python + integer object on the stack, whose value is gotten from a decimal string + literal immediately following the INT opcode in the pickle bytestream. Other + opcodes take Python objects off the stack. The result of unpickling is + whatever object is left on the stack when the final STOP opcode is executed. + + The memo is simply an array of objects, or it can be implemented as a dict + mapping little integers to objects. The memo serves as the PM's "long term + memory", and the little integers indexing the memo are akin to variable + names. Some opcodes pop a stack object into the memo at a given index, + and others push a memo object at a given index onto the stack again. + + At heart, that's all the PM has. Subtleties arise for these reasons: + + + Object identity. Objects can be arbitrarily complex, and subobjects + may be shared (for example, the list [a, a] refers to the same object a + twice). It can be vital that unpickling recreate an isomorphic object + graph, faithfully reproducing sharing. + + + Recursive objects. For example, after "L = []; L.append(L)", L is a + list, and L[0] is the same list. This is related to the object identity + point, and some sequences of pickle opcodes are subtle in order to + get the right result in all cases. + + + Things pickle doesn't know everything about. Examples of things pickle + does know everything about are Python's builtin scalar and container + types, like ints and tuples. They generally have opcodes dedicated to + them. For things like module references and instances of user-defined + classes, pickle's knowledge is limited. Historically, many enhancements + have been made to the pickle protocol in order to do a better (faster, + and/or more compact) job on those. + + + Backward compatibility and micro-optimization. As explained below, + pickle opcodes never go away, not even when better ways to do a thing + get invented. The repertoire of the PM just keeps growing over time. + So, e.g., there are now six distinct opcodes for building a Python integer, + five of them devoted to "short" integers. Even so, the only way to pickle + a Python long int takes time quadratic in the number of digits, for both + pickling and unpickling. This isn't so much a subtlety as a source of + wearying complication. + + + Pickle protocols: + + For compatibility, the meaning of a pickle opcode never changes. Instead new + pickle opcodes get added, and each version's unpickler can handle all the + pickle opcodes in all protocol versions to date. So old pickles continue to + be readable forever. The pickler can generally be told to restrict itself to + the subset of opcodes available under previous protocol versions too, so that + users can create pickles under the current version readable by older + versions. However, a pickle does not contain its version number embedded + within it. If an older unpickler tries to read a pickle using a later + protocol, the result is most likely an exception due to seeing an unknown (in + the older unpickler) opcode. + + The original pickle used what's now called "protocol 0", and what was called + "text mode" before Python 2.3. The entire pickle bytestream is made up of + printable 7-bit ASCII characters, plus the newline character, in protocol 0. + That's why it was called text mode. + + The second major set of additions is now called "protocol 1", and was called + "binary mode" before Python 2.3. This added many opcodes with arguments + consisting of arbitrary bytes, including NUL bytes and unprintable "high bit" + bytes. Binary mode pickles can be substantially smaller than equivalent + text mode pickles, and sometimes faster too; e.g., BININT represents a 4-byte + int as 4 bytes following the opcode, which is cheaper to unpickle than the + (perhaps) 11-character decimal string attached to INT. + + The third major set of additions came in Python 2.3, and is called "protocol + 2". XXX Write a short blurb when Guido figures out what they are . XXX + """ + # Meta-rule: Descriptions are stored in instances of descriptor objects, # with plain constructors. No meta-language is defined from which *************** *** 20,24 **** # Some pickle opcodes have an argument, following the opcode in the # bytestream. An argument is of a specific type, described by an instance ! # of ArgumentDescriptor. class ArgumentDescriptor(object): --- 103,112 ---- # Some pickle opcodes have an argument, following the opcode in the # bytestream. An argument is of a specific type, described by an instance ! # of ArgumentDescriptor. These are not to be confused with arguments taken ! # off the stack -- ArgumentDescriptor applie only to arguments embedded in ! # the opcode stream, immediately following an opcode. ! ! UP_TO_NEWLINE = -1 # represents the "number of bytes" consumed by an ! # argument delimited by the next newline character class ArgumentDescriptor(object): *************** *** 27,31 **** 'name', ! # length of argument, in bytes; an int; or None means variable-length 'n', --- 115,120 ---- 'name', ! # length of argument, in bytes; an int; UP_TO_NEWLINE means variable- ! # length, ending at the next occurrence of a newline character 'n', *************** *** 43,47 **** self.name = name ! assert n is None or (isinstance(n, int) and n >= 0) self.n = n --- 132,136 ---- self.name = name ! assert isinstance(n, int) and (n >= 0 or n is UP_TO_NEWLINE) self.n = n *************** *** 145,149 **** stringnl = ArgumentDescriptor( name='stringnl', ! n=None, reader=read_stringnl, doc="""A newline-terminated string. --- 234,238 ---- stringnl = ArgumentDescriptor( name='stringnl', ! n=UP_TO_NEWLINE, reader=read_stringnl, doc="""A newline-terminated string. *************** *** 202,206 **** decimalnl_short = ArgumentDescriptor( name='decimalnl_short', ! n=None, reader=read_decimalnl_short, doc="""A newline-terminated decimal integer literal. --- 291,295 ---- decimalnl_short = ArgumentDescriptor( name='decimalnl_short', ! n=UP_TO_NEWLINE, reader=read_decimalnl_short, doc="""A newline-terminated decimal integer literal. *************** *** 215,219 **** decimalnl_long = ArgumentDescriptor( name='decimalnl_long', ! n=None, reader=read_decimalnl_long, doc="""A newline-terminated decimal integer literal. --- 304,308 ---- decimalnl_long = ArgumentDescriptor( name='decimalnl_long', ! n=UP_TO_NEWLINE, reader=read_decimalnl_long, doc="""A newline-terminated decimal integer literal. *************** *** 235,239 **** floatnl = ArgumentDescriptor( name='floatnl', ! n=None, reader=read_floatnl, doc="""A newline-terminated decimal floating literal. --- 324,328 ---- floatnl = ArgumentDescriptor( name='floatnl', ! n=UP_TO_NEWLINE, reader=read_floatnl, doc="""A newline-terminated decimal floating literal. From tim_one@users.sourceforge.net Sun Jan 26 04:03:30 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 20:03:30 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv22432 Modified Files: pickletools.py Log Message: Added None. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pickletools.py 26 Jan 2003 03:58:06 -0000 1.7 --- pickletools.py 26 Jan 2003 04:03:27 -0000 1.8 *************** *** 422,425 **** --- 422,430 ---- doc="A Python float object.") + pynone = StackObject( + name="None", + obtype=type(None), + doc="The Python None object.") + anyobject = StackObject( name='any', *************** *** 626,629 **** --- 631,644 ---- """), + # A way to spell None. + + I(name='NONE', + code='N', + args=[], + stack_before=[], + stack_after=[pynone], + proto=0, + doc="Push None on the stack"), + # Stack manipulation. *************** *** 674,688 **** I(name='STOP', code='.', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='NONE', - code='N', args=[], stack_before=[], --- 689,692 ---- From tim_one@users.sourceforge.net Sun Jan 26 04:27:06 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 20:27:06 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv31194 Modified Files: pickletools.py Log Message: TRUE and FALSE aren't really opcodes -- got rid of them, and documented the trick in the INT opcode. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pickletools.py 26 Jan 2003 04:03:27 -0000 1.8 --- pickletools.py 26 Jan 2003 04:27:03 -0000 1.9 *************** *** 259,263 **** # It's not necessarily true that the result fits in a Python short int: ! # the pickle may have been written on a 64-bit box. try: return int(s) --- 259,269 ---- # It's not necessarily true that the result fits in a Python short int: ! # the pickle may have been written on a 64-bit box. There's also a hack ! # for True and False here. ! if s == "00": ! return False ! elif s == "01": ! return True ! try: return int(s) *************** *** 412,419 **** doc="A long (as opposed to short) Python integer object.") ! pyinteger = StackObject( ! name='integer', ! obtype=(int, long), ! doc="A Python integer object, short or long.") pyfloat = StackObject( --- 418,426 ---- doc="A long (as opposed to short) Python integer object.") ! pyinteger_or_bool = StackObject( ! name='int_or_bool', ! obtype=(int, long, bool), ! doc="A Python integer object (short or long), or " ! "a Python bool.") pyfloat = StackObject( *************** *** 531,535 **** args=[decimalnl_short], stack_before=[], ! stack_after=[pyinteger], proto=0, doc="""Newline-terminated decimal integer literal. --- 538,542 ---- args=[decimalnl_short], stack_before=[], ! stack_after=[pyinteger_or_bool], proto=0, doc="""Newline-terminated decimal integer literal. *************** *** 540,543 **** --- 547,558 ---- and LONG then is that INT skips a trailing 'L', and produces a short int whenever possible. + + Another difference is due to that, when bool was introduced as a + distinct type in 2.3, builtin int singletons True and False were + also added to 2.2.2. For compatibility in both directions, True gets + pickled as INT + "I01\\n", and False as INT + "I00\\n". Leading zeroes + are never produced for a genuine integer. The 2.3 (and later) + unpicklers special-case these and return bool instead; earlier + unpicklers ignore the leading "0" and return the int. """), *************** *** 639,643 **** stack_after=[pynone], proto=0, ! doc="Push None on the stack"), # Stack manipulation. --- 654,658 ---- stack_after=[pynone], proto=0, ! doc="Push None on the stack."), # Stack manipulation. *************** *** 997,1022 **** I(name='SETITEMS', code='u', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='TRUE', - code='I01\n', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='FALSE', - code='I00\n', args=[], stack_before=[], --- 1012,1015 ---- From tim_one@users.sourceforge.net Sun Jan 26 05:09:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 21:09:36 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv12571 Modified Files: pickletools.py Log Message: Add the 3 string spellings. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pickletools.py 26 Jan 2003 04:27:03 -0000 1.9 --- pickletools.py 26 Jan 2003 05:09:34 -0000 1.10 *************** *** 107,112 **** # the opcode stream, immediately following an opcode. ! UP_TO_NEWLINE = -1 # represents the "number of bytes" consumed by an ! # argument delimited by the next newline character class ArgumentDescriptor(object): --- 107,117 ---- # the opcode stream, immediately following an opcode. ! # Represents the number of bytes consumed by an argument delimited by the ! # next newline character. ! UP_TO_NEWLINE = -1 ! ! # Represents the number of bytes consumed by a two-argument opcode where ! # the first argument gives the number of bytes in the second argument. ! TAKEN_FROM_ARGUMENT = -2 class ArgumentDescriptor(object): *************** *** 132,136 **** self.name = name ! assert isinstance(n, int) and (n >= 0 or n is UP_TO_NEWLINE) self.n = n --- 137,144 ---- self.name = name ! assert isinstance(n, int) and (n >= 0 or ! n is UP_TO_NEWLINE or ! n is TAKEN_FROM_ARGUMENT) ! self.n = n *************** *** 203,216 **** ! def read_stringnl(f, decode=True): """ >>> import StringIO ! >>> read_stringnl(StringIO.StringIO("abcd\\nefg\\n")) 'abcd' >>> read_stringnl(StringIO.StringIO("\\n")) '' ! >>> read_stringnl(StringIO.StringIO("abcd")) Traceback (most recent call last): ... --- 211,232 ---- ! def read_stringnl(f, decode=True, stripquotes=True): """ >>> import StringIO ! >>> read_stringnl(StringIO.StringIO("'abcd'\\nefg\\n")) 'abcd' >>> read_stringnl(StringIO.StringIO("\\n")) + Traceback (most recent call last): + ... + ValueError: no string quotes around '' + + >>> read_stringnl(StringIO.StringIO("\\n"), stripquotes=False) '' ! >>> read_stringnl(StringIO.StringIO("''\\n")) ! '' ! ! >>> read_stringnl(StringIO.StringIO('"abcd"')) Traceback (most recent call last): ... *************** *** 218,222 **** Embedded escapes are undone in the result. ! >>> read_stringnl(StringIO.StringIO("a\\\\nb\\x00c\\td\\ne")) 'a\\nb\\x00c\\td' """ --- 234,238 ---- Embedded escapes are undone in the result. ! >>> read_stringnl(StringIO.StringIO("'a\\\\nb\\x00c\\td'\\n'e'")) 'a\\nb\\x00c\\td' """ *************** *** 226,229 **** --- 242,257 ---- raise ValueError("no newline found when trying to read stringnl") data = data[:-1] # lose the newline + + if stripquotes: + for q in "'\"": + if data.startswith(q): + if not data.endswith(q): + raise ValueError("strinq quote %r not found at both " + "ends of %r" % (q, data)) + data = data[1:-1] + break + else: + raise ValueError("no string quotes around %r" % data) + # I'm not sure when 'string_escape' was added to the std codecs; it's # crazy not to use it if it's there. *************** *** 238,245 **** doc="""A newline-terminated string. ! This is a repr-style string, with embedded escapes. """) def read_decimalnl_short(f): """ --- 266,336 ---- doc="""A newline-terminated string. ! This is a repr-style string, with embedded escapes, and ! bracketing quotes. """) + def read_string4(f): + """ + >>> import StringIO + >>> read_string4(StringIO.StringIO("\\x00\\x00\\x00\\x00abc")) + '' + >>> read_string4(StringIO.StringIO("\\x03\\x00\\x00\\x00abcdef")) + 'abc' + >>> read_string4(StringIO.StringIO("\\x00\\x00\\x00\\x03abcdef")) + Traceback (most recent call last): + ... + ValueError: expected 50331648 bytes in a string4, but only 6 remain + """ + + n = read_int4(f) + if n < 0: + raise ValueError("string4 byte count < 0: %d" % n) + data = f.read(n) + if len(data) == n: + return data + raise ValueError("expected %d bytes in a string4, but only %d remain" % + (n, len(data))) + + string4 = ArgumentDescriptor( + name="string4", + n=TAKEN_FROM_ARGUMENT, + reader=read_string4, + doc="""A counted string. + + The first argument is a 4-byte little-endian signed int giving + the number of bytes in the string, and the second argument is + that many bytes. + """) + + + def read_string1(f): + """ + >>> import StringIO + >>> read_string1(StringIO.StringIO("\\x00")) + '' + >>> read_string1(StringIO.StringIO("\\x03abcdef")) + 'abc' + """ + + n = read_uint1(f) + assert n >= 0 + data = f.read(n) + if len(data) == n: + return data + raise ValueError("expected %d bytes in a string1, but only %d remain" % + (n, len(data))) + + string1 = ArgumentDescriptor( + name="string1", + n=TAKEN_FROM_ARGUMENT, + reader=read_string1, + doc="""A counted string. + + The first argument is a 1-byte unsigned int giving the number + of bytes in the string, and the second argument is that many + bytes. + """) + def read_decimalnl_short(f): """ *************** *** 254,258 **** """ ! s = read_stringnl(f, decode=False) if s.endswith("L"): raise ValueError("trailing 'L' not allowed in %r" % s) --- 345,349 ---- """ ! s = read_stringnl(f, decode=False, stripquotes=False) if s.endswith("L"): raise ValueError("trailing 'L' not allowed in %r" % s) *************** *** 289,293 **** """ ! s = read_stringnl(f, decode=False) if not s.endswith("L"): raise ValueError("trailing 'L' required in %r" % s) --- 380,384 ---- """ ! s = read_stringnl(f, decode=False, stripquotes=False) if not s.endswith("L"): raise ValueError("trailing 'L' required in %r" % s) *************** *** 325,329 **** -1.25 """ ! s = read_stringnl(f, decode=False) return float(s) --- 416,420 ---- -1.25 """ ! s = read_stringnl(f, decode=False, stripquotes=False) return float(s) *************** *** 429,432 **** --- 520,533 ---- doc="A Python float object.") + pystring = StackObject( + name='str', + obtype=str, + doc="A Python string object.") + + pyunicode = StackObject( + name='unicode', + obtype=unicode, + doc="A Python Unicode string object.") + pynone = StackObject( name="None", *************** *** 532,536 **** opcodes = [ ! # Six ways to spell integers. I(name='INT', --- 633,637 ---- opcodes = [ ! # Ways to spell integers. I(name='INT', *************** *** 540,544 **** stack_after=[pyinteger_or_bool], proto=0, ! doc="""Newline-terminated decimal integer literal. The intent may have been that this always fit in a short Python int, --- 641,645 ---- stack_after=[pyinteger_or_bool], proto=0, ! doc="""Push an integer or bool. The argument is a decimal literal string. The intent may have been that this always fit in a short Python int, *************** *** 549,558 **** Another difference is due to that, when bool was introduced as a ! distinct type in 2.3, builtin int singletons True and False were ! also added to 2.2.2. For compatibility in both directions, True gets ! pickled as INT + "I01\\n", and False as INT + "I00\\n". Leading zeroes ! are never produced for a genuine integer. The 2.3 (and later) ! unpicklers special-case these and return bool instead; earlier ! unpicklers ignore the leading "0" and return the int. """), --- 650,659 ---- Another difference is due to that, when bool was introduced as a ! distinct type in 2.3, builtin names True and False were also added to ! 2.2.2, mapping to ints 1 and 0. For compatibility in both directions, ! True gets pickled as INT + "I01\\n", and False as INT + "I00\\n". ! Leading zeroes are never produced for a genuine integer. The 2.3 ! (and later) unpicklers special-case these and return bool instead; ! earlier unpicklers ignore the leading "0" and return the int. """), *************** *** 563,567 **** stack_after=[pylong], proto=0, ! doc="""Newline-terminated decimal integer literal. The same as INT, except that the literal ends with 'L', and always --- 664,668 ---- stack_after=[pylong], proto=0, ! doc="""Push a long integer. The argument is a decimal literal string. The same as INT, except that the literal ends with 'L', and always *************** *** 576,580 **** stack_after=[pyint], proto=1, ! doc="""Four-byte signed integer. This handles the full range of Python (short) integers on a 32-bit --- 677,681 ---- stack_after=[pyint], proto=1, ! doc="""Push a four-byte signed integer. This handles the full range of Python (short) integers on a 32-bit *************** *** 590,594 **** stack_after=[pyint], proto=1, ! doc="""One-byte unsigned integer. This is a space optimization for pickling very small non-negative ints, --- 691,695 ---- stack_after=[pyint], proto=1, ! doc="""Push a one-byte unsigned integer. This is a space optimization for pickling very small non-negative ints, *************** *** 602,606 **** stack_after=[pyint], proto=1, ! doc="""Two-byte unsigned integer. This is a space optimization for pickling small positive ints, in --- 703,707 ---- stack_after=[pyint], proto=1, ! doc="""Push a two-byte unsigned integer. This is a space optimization for pickling small positive ints, in *************** *** 608,612 **** """), ! # Two ways to spell floats. I(name='FLOAT', --- 709,713 ---- """), ! # Ways to spell floats. I(name='FLOAT', *************** *** 646,649 **** --- 747,791 ---- """), + # Ways to spell strings (8-bit, not Unicode). + + I(name='STRING', + code='S', + args=[stringnl], + stack_before=[], + stack_after=[pystring], + proto=0, + doc="""Push a Python string object. + + The argument is a repr-style string, with bracketing quote characters, + and perhaps embedded escapes. The argument extends until the next + newline character. + """), + + I(name='BINSTRING', + code='T', + args=[string4], + stack_before=[], + stack_after=[pystring], + proto=1, + doc="""Push a Python string object. + + There are two arguments: the first is a 4-byte little-endian signed int + giving the number of bytes in the string, and the second is that many + bytes, which are taken literally as the string content. + """), + + I(name='SHORT_BINSTRING', + code='U', + args=[string1], + stack_before=[], + stack_after=[pystring], + proto=1, + doc="""Push a Python string object. + + There are two arguments: the first is a 1-byte unsigned int giving + the number of bytes in the string, and the second is that many bytes, + which are taken literally as the string content. + """), + # A way to spell None. *************** *** 737,773 **** I(name='REDUCE', code='R', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='STRING', - code='S', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='BINSTRING', - code='T', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='SHORT_BINSTRING', - code='U', args=[], stack_before=[], --- 879,882 ---- From tim_one@users.sourceforge.net Sun Jan 26 05:33:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 21:33:13 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv20897 Modified Files: pickletools.py Log Message: Added the 6 memo manipulators. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** pickletools.py 26 Jan 2003 05:09:34 -0000 1.10 --- pickletools.py 26 Jan 2003 05:33:11 -0000 1.11 *************** *** 842,845 **** --- 842,921 ---- """), + # Memo manipulation. There are really only two operations (get and put). + + I(name='GET', + code='g', + args=[decimalnl_short], + stack_before=[], + stack_after=[anyobject], + proto=0, + doc="""Push a memo object on the stack. + + The index of the memo object to push is given by the newline-teriminated + decimal string following. BINGET and LONG_BINGET are space-optimized + versions. + """), + + I(name='BINGET', + code='h', + args=[uint1], + stack_before=[], + stack_after=[anyobject], + proto=1, + doc="""Push a memo object on the stack. + + The index of the memo object to push is given by the 1-byte unsigned + integer following. + """), + + I(name='LONG_BINGET', + code='j', + args=[int4], + stack_before=[], + stack_after=[anyobject], + proto=1, + doc="""Push a memo object on the stack. + + The index of the memo object to push is given by the 4-byte signed + little-endian integer following. + """), + + I(name='PUT', + code='p', + args=[decimalnl_short], + stack_before=[], + stack_after=[], + proto=0, + doc="""Store the stack top into the memo. The stack is not popped. + + The index of the memo location to write into is given by the newline- + terminated decimal string following. BINPUT and LONG_BINPUT are + space-optimized versions. + """), + + I(name='BINPUT', + code='q', + args=[uint1], + stack_before=[], + stack_after=[], + proto=1, + doc="""Store the stack top into the memo. The stack is not popped. + + The index of the memo location to write into is given by the 1-byte + unsigned integer following. + """), + + I(name='LONG_BINPUT', + code='r', + args=[int4], + stack_before=[], + stack_after=[], + proto=1, + doc="""Store the stack top into the memo. The stack is not popped. + + The index of the memo location to write into is given by the 4-byte + signed little-endian integer following. + """), + # XXX opcodes below this point haven't been done yet. *************** *** 976,1001 **** """), - I(name='GET', - code='g', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='BINGET', - code='h', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - I(name='INST', code='i', --- 1052,1055 ---- *************** *** 1009,1023 **** """), - I(name='LONG_BINGET', - code='j', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - I(name='LIST', code='l', --- 1063,1066 ---- *************** *** 1044,1080 **** I(name='OBJ', code='o', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='PUT', - code='p', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='BINPUT', - code='q', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='LONG_BINPUT', - code='r', args=[], stack_before=[], --- 1087,1090 ---- From tim_one@users.sourceforge.net Sun Jan 26 05:36:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 21:36:39 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv22288 Modified Files: pickletools.py Log Message: Added STOP. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pickletools.py 26 Jan 2003 05:33:11 -0000 1.11 --- pickletools.py 26 Jan 2003 05:36:37 -0000 1.12 *************** *** 918,933 **** """), ! # XXX opcodes below this point haven't been done yet. I(name='STOP', code='.', args=[], ! stack_before=[], stack_after=[], proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), I(name='PERSID', --- 918,937 ---- """), ! # Machine control. I(name='STOP', code='.', args=[], ! stack_before=[anyobject], stack_after=[], proto=0, ! doc="""Stop the unpickling machine. ! Every pickle ends with this opcode. The object at the top of the stack ! is popped, and that's the result of unpickling. The stack should be ! empty then. """), + + # XXX opcodes below this point haven't been done yet. I(name='PERSID', From tim_one@users.sourceforge.net Sun Jan 26 05:41:30 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 21:41:30 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv23944 Modified Files: pickletools.py Log Message: Added the empty-container opcodes. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pickletools.py 26 Jan 2003 05:36:37 -0000 1.12 --- pickletools.py 26 Jan 2003 05:41:28 -0000 1.13 *************** *** 535,538 **** --- 535,553 ---- doc="The Python None object.") + pytuple = StackObject( + name="tuple", + obtype=tuple, + doc="A Python tuple object.") + + pylist = StackObject( + name="list", + obtype=list, + doc="A Python list object.") + + pydict = StackObject( + name="dict", + obtype=dict, + doc="A Python dict object.") + anyobject = StackObject( name='any', *************** *** 918,921 **** --- 933,962 ---- """), + # Empty containers. + + I(name='EMPTY_LIST', + code=']', + args=[], + stack_before=[], + stack_after=[pylist], + proto=0, + doc="Push an empty list."), + + I(name='EMPTY_TUPLE', + code=')', + args=[], + stack_before=[], + stack_after=[pytuple], + proto=0, + doc="Push an empty tuple."), + + I(name='EMPTY_DICT', + code='}', + args=[], + stack_before=[], + stack_after=[pydict], + proto=0, + doc="Push an empty dict."), + # Machine control. *************** *** 1034,1048 **** """), - I(name='EMPTY_DICT', - code='}', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - I(name='APPENDS', code='e', --- 1075,1078 ---- *************** *** 1078,1092 **** """), - I(name='EMPTY_LIST', - code=']', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - I(name='OBJ', code='o', --- 1108,1111 ---- *************** *** 1113,1127 **** I(name='TUPLE', code='t', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='EMPTY_TUPLE', - code=')', args=[], stack_before=[], --- 1132,1135 ---- From tim_one@users.sourceforge.net Sun Jan 26 06:03:05 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 25 Jan 2003 22:03:05 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv32386 Modified Files: pickletools.py Log Message: Misc little cleanups. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pickletools.py 26 Jan 2003 05:41:28 -0000 1.13 --- pickletools.py 26 Jan 2003 06:03:02 -0000 1.14 *************** *** 8,13 **** # - A symbolic pickle disassembler. # ! # - A pickle verifier -- read a pickle and check it exhaustively for # well-formedness. --- 8,16 ---- # - A symbolic pickle disassembler. # ! # - A pickle verifier: read a pickle and check it exhaustively for # well-formedness. + # + # - A protocol identifier: examine a pickle and return its protocol number + # (== the highest .proto attr value among all the opcodes in the pickle). *************** *** 104,108 **** # bytestream. An argument is of a specific type, described by an instance # of ArgumentDescriptor. These are not to be confused with arguments taken ! # off the stack -- ArgumentDescriptor applie only to arguments embedded in # the opcode stream, immediately following an opcode. --- 107,111 ---- # bytestream. An argument is of a specific type, described by an instance # of ArgumentDescriptor. These are not to be confused with arguments taken ! # off the stack -- ArgumentDescriptor applies only to arguments embedded in # the opcode stream, immediately following an opcode. *************** *** 474,478 **** class StackObject(object): __slots__ = ( ! # name of descriptor record, also a module global name; a string 'name', --- 477,481 ---- class StackObject(object): __slots__ = ( ! # name of descriptor record, for info only 'name', *************** *** 481,485 **** 'obtype', ! # human-readable docs for this arg descriptor; a string 'doc', ) --- 484,488 ---- 'obtype', ! # human-readable docs for this kind of stack object; a string 'doc', ) *************** *** 513,517 **** obtype=(int, long, bool), doc="A Python integer object (short or long), or " ! "a Python bool.") pyfloat = StackObject( --- 516,520 ---- obtype=(int, long, bool), doc="A Python integer object (short or long), or " ! "a Python bool.") pyfloat = StackObject( *************** *** 596,601 **** 'name', ! # the code used in a bytestream to represent the opcode; a string, ! # usually one character 'code', --- 599,604 ---- 'name', ! # the code used in a bytestream to represent the opcode; a ! # one-character string 'code', *************** *** 622,625 **** --- 625,629 ---- assert isinstance(code, str) + assert len(code) == 1 self.code = code *************** *** 813,816 **** --- 817,846 ---- doc="Push None on the stack."), + # Empty containers. + + I(name='EMPTY_LIST', + code=']', + args=[], + stack_before=[], + stack_after=[pylist], + proto=0, + doc="Push an empty list."), + + I(name='EMPTY_TUPLE', + code=')', + args=[], + stack_before=[], + stack_after=[pytuple], + proto=0, + doc="Push an empty tuple."), + + I(name='EMPTY_DICT', + code='}', + args=[], + stack_before=[], + stack_after=[pydict], + proto=0, + doc="Push an empty dict."), + # Stack manipulation. *************** *** 932,961 **** signed little-endian integer following. """), - - # Empty containers. - - I(name='EMPTY_LIST', - code=']', - args=[], - stack_before=[], - stack_after=[pylist], - proto=0, - doc="Push an empty list."), - - I(name='EMPTY_TUPLE', - code=')', - args=[], - stack_before=[], - stack_after=[pytuple], - proto=0, - doc="Push an empty tuple."), - - I(name='EMPTY_DICT', - code='}', - args=[], - stack_before=[], - stack_after=[pydict], - proto=0, - doc="Push an empty dict."), # Machine control. --- 962,965 ---- From loewis@users.sourceforge.net Sun Jan 26 08:40:52 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 00:40:52 -0800 Subject: [Python-checkins] python/dist/src/Modules/expat xmlparse.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules/expat In directory sc8-pr-cvs1:/tmp/cvs-serv10557/Modules/expat Modified Files: xmlparse.c Log Message: Undo inclusion of Python.h. Remove HAVE_MEMCPY section. Update Windows command line. Index: xmlparse.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmlparse.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** xmlparse.c 25 Jan 2003 22:41:29 -0000 1.3 --- xmlparse.c 26 Jan 2003 08:40:46 -0000 1.4 *************** *** 3,9 **** */ - /* Added to look for memcpy */ - #include - #include #include /* memset(), memcpy() */ --- 3,6 ---- *************** *** 86,98 **** /* Round up n to be a multiple of sz, where sz is a power of 2. */ #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) - - /* Handle the case where memmove() doesn't exist. */ - #ifndef HAVE_MEMMOVE - #ifdef HAVE_BCOPY - #define memmove(d,s,l) bcopy((s),(d),(l)) - #else - #error memmove does not exist on this platform, nor is a substitute available - #endif /* HAVE_BCOPY */ - #endif /* HAVE_MEMMOVE */ #include "internal.h" --- 83,86 ---- From loewis@users.sourceforge.net Sun Jan 26 08:40:52 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 00:40:52 -0800 Subject: [Python-checkins] python/dist/src/PCbuild pyexpat.dsp,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv10557/PCbuild Modified Files: pyexpat.dsp Log Message: Undo inclusion of Python.h. Remove HAVE_MEMCPY section. Update Windows command line. Index: pyexpat.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pyexpat.dsp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** pyexpat.dsp 23 Jul 2002 06:31:15 -0000 1.10 --- pyexpat.dsp 26 Jan 2003 08:40:50 -0000 1.11 *************** *** 45,49 **** F90=df.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\Include" /I "..\PC" /I "..\Modules\expat" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_EXPAT_H" /D "XML_NS" /D "XML_DTD" /D XML_BYTE_ORDER=12 /D XML_CONTEXT_BYTES=1024 /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 --- 45,49 ---- F90=df.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\Include" /I "..\PC" /I "..\Modules\expat" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /D "XML_DTD" /D BYTEORDER=1234 /D XML_CONTEXT_BYTES=1024 /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 *************** *** 73,77 **** F90=df.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\Include" /I "..\PC" /I "..\Modules\expat" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_EXPAT_H" /D "XML_NS" /D "XML_DTD" /D XML_BYTE_ORDER=12 /D XML_CONTEXT_BYTES=1024 /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 --- 73,77 ---- F90=df.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\Include" /I "..\PC" /I "..\Modules\expat" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_EXPAT_H" /D "XML_NS" /D "XML_DTD" /D BYTEORDER=1234 /D XML_CONTEXT_BYTES=1024 /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 From loewis@users.sourceforge.net Sun Jan 26 08:59:34 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 00:59:34 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/dom minidom.py,1.49,1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory sc8-pr-cvs1:/tmp/cvs-serv17592 Modified Files: minidom.py Log Message: Merge with PyXML 1.82: Correct various typos. Fixes #674700. Set newly created attribute via setNamedItem. Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -d -r1.49 -r1.50 *** minidom.py 25 Jan 2003 15:28:29 -0000 1.49 --- minidom.py 26 Jan 2003 08:59:32 -0000 1.50 *************** *** 17,21 **** import xml.dom ! from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX from xml.dom.minicompat import * from xml.dom.xmlbuilder import DOMImplementationLS, DocumentLS --- 17,21 ---- import xml.dom ! from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE, domreg from xml.dom.minicompat import * from xml.dom.xmlbuilder import DOMImplementationLS, DocumentLS *************** *** 385,392 **** d[name] = value ! def _set_prefix(self, value): nsuri = self.namespaceURI ! if value == "xmlns": ! if self.namespaceURI and self.namespaceURI != XMLNS_NAMESPACE: raise xml.dom.NamespaceErr( "illegal use of 'xmlns' prefix for the wrong namespace") --- 385,392 ---- d[name] = value ! def _set_prefix(self, prefix): nsuri = self.namespaceURI ! if prefix == "xmlns": ! if nsuri and nsuri != XMLNS_NAMESPACE: raise xml.dom.NamespaceErr( "illegal use of 'xmlns' prefix for the wrong namespace") *************** *** 396,400 **** newName = self.localName else: ! newName = "%s:%s" % (value, self.localName) if self.ownerElement: _clear_id_cache(self.ownerElement) --- 396,400 ---- newName = self.localName else: ! newName = "%s:%s" % (prefix, self.localName) if self.ownerElement: _clear_id_cache(self.ownerElement) *************** *** 537,540 **** --- 537,541 ---- node = Attr(attname) node.ownerDocument = self._ownerElement.ownerDocument + self.setNamedItem(node) node.value = value else: *************** *** 1009,1013 **** # Make sure we don't add an instance __dict__ if we don't already # have one, at least when that's possible: ! __slots__ = () nodeType = Node.TEXT_NODE --- 1010,1015 ---- # Make sure we don't add an instance __dict__ if we don't already # have one, at least when that's possible: ! # XXX this does not work, CharacterData is an old-style class ! # __slots__ = () nodeType = Node.TEXT_NODE *************** *** 1133,1137 **** # Make sure we don't add an instance __dict__ if we don't already # have one, at least when that's possible: ! __slots__ = () nodeType = Node.CDATA_SECTION_NODE --- 1135,1140 ---- # Make sure we don't add an instance __dict__ if we don't already # have one, at least when that's possible: ! # XXX this does not work, Text is an old-style class ! # __slots__ = () nodeType = Node.CDATA_SECTION_NODE *************** *** 1213,1217 **** """Mix-in class that supports the publicId and systemId attributes.""" ! __slots__ = 'publicId', 'systemId' def _identified_mixin_init(self, publicId, systemId): --- 1216,1221 ---- """Mix-in class that supports the publicId and systemId attributes.""" ! # XXX this does not work, this is an old-style class ! # __slots__ = 'publicId', 'systemId' def _identified_mixin_init(self, publicId, systemId): From loewis@users.sourceforge.net Sun Jan 26 09:01:32 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 01:01:32 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/dom expatbuilder.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory sc8-pr-cvs1:/tmp/cvs-serv18532 Modified Files: expatbuilder.py Log Message: Merge with PyXML 1.34: Correct typo. Fixes #674700. Index: expatbuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/expatbuilder.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** expatbuilder.py 25 Jan 2003 15:11:07 -0000 1.1 --- expatbuilder.py 26 Jan 2003 09:01:30 -0000 1.2 *************** *** 335,339 **** _append_child(self.curNode, node) if self._filter and self._filter.acceptNode(node) == FILTER_REJECT: ! curNode.removeChild(node) def start_cdata_section_handler(self): --- 335,339 ---- _append_child(self.curNode, node) if self._filter and self._filter.acceptNode(node) == FILTER_REJECT: ! self.curNode.removeChild(node) def start_cdata_section_handler(self): From loewis@users.sourceforge.net Sun Jan 26 09:04:38 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 01:04:38 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/dom domreg.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory sc8-pr-cvs1:/tmp/cvs-serv19715 Modified Files: domreg.py Log Message: Merge with PyXML 1.3: Add support for the DOM Level 3 (draft) DOMImplementationSource interface to the xml.dom and xml.dom.minidom modules. Note API issue: the draft spec says to return null when there is no suitable implementation, while the Python getDOMImplementation() function raises ImportError (minor). Index: domreg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/domreg.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** domreg.py 22 Feb 2001 14:04:09 -0000 1.1 --- domreg.py 26 Jan 2003 09:04:35 -0000 1.2 *************** *** 3,6 **** --- 3,8 ---- registerDOMImplementation should be imported from xml.dom.""" + from xml.dom.minicompat import * # isinstance, StringTypes + # This is a list of well-known implementations. Well-known names # should be published by posting to xml-sig@python.org, and are *************** *** 61,64 **** --- 63,68 ---- # User did not specify a name, try implementations in arbitrary # order, returning the one that has the required features + if isinstance(features, StringTypes): + features = _parse_feature_string(features) for creator in registered.values(): dom = creator() *************** *** 75,76 **** --- 79,99 ---- raise ImportError,"no suitable DOM implementation found" + + def _parse_feature_string(s): + features = [] + parts = s.split() + i = 0 + length = len(parts) + while i < length: + feature = parts[i] + if feature[0] in "0123456789": + raise ValueError, "bad feature name: " + `feature` + i = i + 1 + version = None + if i < length: + v = parts[i] + if v[0] in "0123456789": + i = i + 1 + version = v + features.append((feature, version)) + return tuple(features) From loewis@users.sourceforge.net Sun Jan 26 10:36:35 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 02:36:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml __init__.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml In directory sc8-pr-cvs1:/tmp/cvs-serv16886 Modified Files: __init__.py Log Message: Require PyXML 0.8.2. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/__init__.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** __init__.py 30 Jun 2002 15:08:22 -0000 1.12 --- __init__.py 26 Jan 2003 10:36:33 -0000 1.13 *************** *** 22,26 **** ! _MINIMUM_XMLPLUS_VERSION = (0, 6, 5) --- 22,26 ---- ! _MINIMUM_XMLPLUS_VERSION = (0, 8, 2) From loewis@users.sourceforge.net Sun Jan 26 11:27:18 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 03:27:18 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.137,1.138 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv618 Modified Files: setup.py Log Message: Patch #670715: Universal Unicode Codec for POSIX iconv. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.137 retrieving revision 1.138 diff -C2 -d -r1.137 -r1.138 *** setup.py 25 Jan 2003 22:41:27 -0000 1.137 --- setup.py 26 Jan 2003 11:27:16 -0000 1.138 *************** *** 615,618 **** --- 615,636 ---- libraries = libs) ) + # Hye-Shik Chang's iconv_codec C interface + iconv_incs = find_file('iconv.h', inc_dirs, + ['/usr/local/include', '/usr/pkg/include']) + iconv_libs = find_library_file(self.compiler, 'iconv', lib_dirs, + ['/usr/local/lib', '/usr/pkg/lib']) + + if (iconv_incs is not None): + if iconv_libs is not None: + iconv_libraries = ['iconv'] + else: + iconv_libraries = [] # in libc + + exts.append( Extension('_iconv_codec', + ['_iconv_codec.c'], + include_dirs = iconv_incs, + library_dirs = iconv_libs, + libraries = iconv_libraries), ) + # Curses support, requring the System V version of curses, often # provided by the ncurses library. From loewis@users.sourceforge.net Sun Jan 26 11:27:18 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 03:27:18 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.626,1.627 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv618/Misc Modified Files: NEWS Log Message: Patch #670715: Universal Unicode Codec for POSIX iconv. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.626 retrieving revision 1.627 diff -C2 -d -r1.626 -r1.627 *** NEWS 26 Jan 2003 02:45:47 -0000 1.626 --- NEWS 26 Jan 2003 11:27:16 -0000 1.627 *************** *** 27,30 **** --- 27,33 ---- ----------------- + - A new module _iconv_codec has been added, to expose the iconv(3) + library. + - os/posixmodule has grown the sysexits.h constants (EX_OK and friends). From loewis@users.sourceforge.net Sun Jan 26 11:27:18 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 03:27:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/encodings iconv_codec.py,NONE,1.1 __init__.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory sc8-pr-cvs1:/tmp/cvs-serv618/Lib/encodings Modified Files: __init__.py Added Files: iconv_codec.py Log Message: Patch #670715: Universal Unicode Codec for POSIX iconv. --- NEW FILE: iconv_codec.py --- """ Python 'iconv' Codec Written by Hye-Shik Chang (perky@FreeBSD.org). Copyright(c) Python Software Foundation, All Rights Reserved. NO WARRANTY. """ import _iconv_codec import codecs def lookup(enc): class IconvCodec(_iconv_codec.iconvcodec, codecs.Codec): encoding = enc try: c = IconvCodec() class IconvStreamReader(IconvCodec, codecs.StreamReader): __init__ = codecs.StreamReader.__init__ class IconvStreamWriter(IconvCodec, codecs.StreamWriter): __init__ = codecs.StreamWriter.__init__ return ( c.encode, c.decode, IconvStreamReader, IconvStreamWriter ) except ValueError: return None codecs.register(lookup) # ex: ts=8 sts=4 et Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/__init__.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** __init__.py 24 Dec 2002 18:31:27 -0000 1.14 --- __init__.py 26 Jan 2003 11:27:16 -0000 1.15 *************** *** 121,122 **** --- 121,128 ---- # Register the search_function in the Python codec registry codecs.register(search_function) + + # Register iconv_codec lookup function if available + try: + import iconv_codec + except ImportError: + pass From loewis@users.sourceforge.net Sun Jan 26 11:27:18 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 03:27:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.116,1.117 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv618/Lib/test Modified Files: regrtest.py Log Message: Patch #670715: Universal Unicode Codec for POSIX iconv. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -d -r1.116 -r1.117 *** regrtest.py 8 Jan 2003 16:31:11 -0000 1.116 --- regrtest.py 26 Jan 2003 11:27:16 -0000 1.117 *************** *** 557,560 **** --- 557,561 ---- test_gl test_grp + test_iconv_codec test_imgfile test_largefile *************** *** 612,615 **** --- 613,617 ---- test_gl test_grp + test_iconv_codec test_imgfile test_largefile *************** *** 899,902 **** --- 901,905 ---- test_email_codecs test_gl + test_iconv_codec test_imgfile test_largefile From loewis@users.sourceforge.net Sun Jan 26 11:30:38 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 03:30:38 -0800 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv2026/Modules Added Files: _iconv_codec.c Log Message: Patch #670715: Universal Unicode Codec for POSIX iconv. --- NEW FILE: _iconv_codec.c --- /* * _iconv_codec.c * * libiconv adaptor for Python iconvcodec * * Author : Hye-Shik Chang * Created : 17 January 2003 */ #include "Python.h" #include #include static const char *__version__ = "$Revision: 1.1 $"; #if Py_USING_UNICODE # if Py_UNICODE_SIZE == 2 # ifdef __GNU_LIBRARY__ # define UNICODE_ENCODING "ucs-2" # else # define UNICODE_ENCODING "ucs-2-internal" # endif # define MBENCODED_LENGTH_MAX 4 # elif Py_UNICODE_SIZE == 4 # ifdef __GNU_LIBRARY__ # define UNICODE_ENCODING "ucs-4" # else # define UNICODE_ENCODING "ucs-4-internal" # endif # define MBENCODED_LENGTH_MAX 6 # endif #else # error "Unicode is not available" #endif typedef struct { PyObject_HEAD iconv_t enchdl, dechdl; char *encoding; } iconvcodecObject; PyDoc_STRVAR(iconvcodec_doc, "iconvcodec object"); staticforward PyTypeObject iconvcodec_Type; #define ERROR_STRICT (PyObject *)(1) #define ERROR_IGNORE (PyObject *)(2) #define ERROR_REPLACE (PyObject *)(3) #define ERROR_MAX ERROR_REPLACE #define REPLACEMENT_CHAR_DECODE 0xFFFD #define REPLACEMENT_CHAR_ENCODE '?' #define DEFAULT_ENCODING "utf-8" static PyObject * get_errorcallback(const char *errors) { if (errors == NULL || strcmp(errors, "strict") == 0) return ERROR_STRICT; else if (strcmp(errors, "ignore") == 0) return ERROR_IGNORE; else if (strcmp(errors, "replace") == 0) return ERROR_REPLACE; else return PyCodec_LookupError(errors); } PyDoc_STRVAR(iconvcodec_encode__doc__, "I.encode(unicode, [,errors]) -> (string, length consumed)\n\ \n\ Return an encoded string version of `unicode'. errors may be given to\n\ set a different error handling scheme. Default is 'strict' meaning that\n\ encoding errors raise a UnicodeEncodeError. Other possible values are\n\ 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name\n\ registered with codecs.register_error that can handle UnicodeEncodeErrors."); static PyObject * iconvcodec_encode(iconvcodecObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "input", "errors", NULL }; Py_UNICODE *input; int inputlen; char *errors = NULL/*strict*/, *out, *out_top; const char *inp, *inp_top; size_t inplen, inplen_total, outlen, outlen_total, estep; PyObject *outputobj = NULL, *errorcb = NULL, *exceptionobj = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "u#|s:encode", kwlist, &input, &inputlen, &errors)) return NULL; /* TypeError */ errorcb = get_errorcallback(errors); if (errorcb == NULL) return NULL; /* LookupError or something else from error handler */ inp = inp_top = (char *)input; inplen = inplen_total = (size_t)(inputlen * Py_UNICODE_SIZE); outlen = inputlen * MBENCODED_LENGTH_MAX; if (outlen < 16) outlen = 16; /* for iso-2022 codecs */ outputobj = PyString_FromStringAndSize(NULL, outlen); if (outputobj == NULL) return NULL; out = out_top = PyString_AS_STRING(outputobj); outlen_total = outlen; estep = inputlen * Py_UNICODE_SIZE / 2; #define RESIZE_OUTBUFFER(size) { \ size_t toadd = (size); \ outlen_total += toadd; \ outlen += toadd; \ if (_PyString_Resize(&outputobj, outlen_total) == -1) \ goto errorexit; \ out = PyString_AS_STRING(outputobj) + (out - out_top); \ out_top = PyString_AS_STRING(outputobj); \ } while (inplen > 0) { if (iconv(self->enchdl, &inp, &inplen, &out, &outlen) == -1) { char reason[128]; int errpos; if (errno == E2BIG) { RESIZE_OUTBUFFER(estep); continue; } if (errorcb == ERROR_IGNORE || errorcb == ERROR_REPLACE) { inplen -= Py_UNICODE_SIZE; inp += Py_UNICODE_SIZE; if (errorcb == ERROR_REPLACE) { if (outlen < 1) RESIZE_OUTBUFFER(errno == EINVAL ? 1 : estep); outlen--; *out++ = REPLACEMENT_CHAR_ENCODE; } if (errno == EINVAL) break; else continue; } errpos = (int)(inp - inp_top) / Py_UNICODE_SIZE; sprintf(reason, "Undefined character map from " #if Py_UNICODE_SIZE == 2 "\\u%04x" #elif Py_UNICODE_SIZE == 4 "\\u%08x" #endif , *(Py_UNICODE *)inp); if (exceptionobj == NULL) { if ((exceptionobj = PyUnicodeEncodeError_Create( self->encoding, input, inputlen, errpos, errpos + 1, reason)) == NULL) goto errorexit; } else { if (PyUnicodeEncodeError_SetStart(exceptionobj, errpos) != 0) goto errorexit; if (PyUnicodeEncodeError_SetEnd(exceptionobj, errpos + 1) != 0) goto errorexit; if (PyUnicodeEncodeError_SetReason(exceptionobj, reason) != 0) goto errorexit; } if (errorcb == ERROR_STRICT) { PyCodec_StrictErrors(exceptionobj); goto errorexit; } else { PyObject *argsobj, *retobj, *retuni; long newpos; argsobj = PyTuple_New(1); if (argsobj == NULL) goto errorexit; PyTuple_SET_ITEM(argsobj, 0, exceptionobj); Py_INCREF(exceptionobj); retobj = PyObject_CallObject(errorcb, argsobj); Py_DECREF(argsobj); if (retobj == NULL) goto errorexit; if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) || !PyInt_Check(PyTuple_GET_ITEM(retobj, 1))) { Py_DECREF(retobj); PyErr_SetString(PyExc_ValueError, "encoding error handler " "must return (unicode, int) tuple"); goto errorexit; } if (PyUnicode_GET_SIZE(retuni) > 0) { #define errorexit errorexit_cbpad PyObject *retstr = NULL; int retstrsize; retstr = PyUnicode_AsEncodedString( retuni, self->encoding, NULL); if (retstr == NULL || !PyString_Check(retstr)) goto errorexit; retstrsize = PyString_GET_SIZE(retstr); if (outlen < retstrsize) RESIZE_OUTBUFFER(errno == EINVAL || retstrsize > estep ? retstrsize - outlen : estep); memcpy(out, PyString_AS_STRING(retstr), retstrsize); out += retstrsize; outlen -= retstrsize; #undef errorexit if (0) { errorexit_cbpad: Py_XDECREF(retobj); Py_XDECREF(retstr); goto errorexit; } Py_DECREF(retstr); } newpos = PyInt_AS_LONG(PyTuple_GET_ITEM(retobj, 1)); Py_DECREF(retobj); if (newpos < 0) newpos = inputlen - newpos; if (newpos < 0 || newpos >= inputlen) break; inp = inp_top + Py_UNICODE_SIZE * newpos; inplen = inplen_total - Py_UNICODE_SIZE * newpos; } } else break; } #undef RESIZE_OUTBUFFER { PyObject *rettup; int finalsize; finalsize = (int)(out - out_top); if (finalsize != outlen_total) { if (_PyString_Resize(&outputobj, finalsize) == -1) goto errorexit; } if (errorcb > ERROR_MAX) { Py_DECREF(errorcb); } Py_XDECREF(exceptionobj); rettup = PyTuple_New(2); if (rettup == NULL) { Py_DECREF(outputobj); return NULL; } PyTuple_SET_ITEM(rettup, 0, outputobj); PyTuple_SET_ITEM(rettup, 1, PyInt_FromLong(inputlen)); return rettup; } errorexit: Py_XDECREF(outputobj); if (errorcb > ERROR_MAX) { Py_DECREF(errorcb); } Py_XDECREF(exceptionobj); return NULL; } PyDoc_STRVAR(iconvcodec_decode__doc__, "I.decode(string, [,errors]) -> (unicodeobject, length consumed)\n\ \n\ Decodes `string' using I, an iconvcodec instance. errors may be given\n\ to set a different error handling scheme. Default is 'strict' meaning\n\ that encoding errors raise a UnicodeDecodeError. Other possible values\n\ are 'ignore' and 'replace' as well as any other name registerd with\n\ codecs.register_error that is able to handle UnicodeDecodeErrors."); static PyObject * iconvcodec_decode(iconvcodecObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "input", "errors", NULL }; char *errors = NULL/*strict*/, *out, *out_top; const char *inp, *inp_top; int inplen_int; size_t inplen, inplen_total, outlen, outlen_total, estep; PyObject *outputobj = NULL, *errorcb = NULL, *exceptionobj = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|s:decode", kwlist, &inp, &inplen_int, &errors)) return NULL; /* TypeError */ errorcb = get_errorcallback(errors); if (errorcb == NULL) return NULL; /* LookupError or something else from error handler */ inp_top = inp; inplen_total = inplen = (size_t)inplen_int; outputobj = PyUnicode_FromUnicode(NULL, inplen); if (outputobj == NULL) return NULL; outlen_total = outlen = PyUnicode_GET_DATA_SIZE(outputobj); out = out_top = (char *)PyUnicode_AS_UNICODE(outputobj); estep = outlen / 2; #define RESIZE_OUTBUFFER(size) { \ size_t toadd = (size); \ outlen_total += toadd; \ outlen += toadd; \ if (PyUnicode_Resize(&outputobj, outlen_total/Py_UNICODE_SIZE) == -1) \ goto errorexit; \ out = (char *)PyUnicode_AS_UNICODE(outputobj) + (out - out_top); \ out_top = (char *)PyUnicode_AS_UNICODE(outputobj); \ } while (inplen > 0) { if (iconv(self->dechdl, &inp, &inplen, &out, &outlen) == -1) { char reason[128], *reasonpos = (char *)reason; int errpos; if (errno == E2BIG) { RESIZE_OUTBUFFER(estep); continue; } if (errorcb == ERROR_IGNORE || errorcb == ERROR_REPLACE) { inplen--; inp++; if (errorcb == ERROR_REPLACE) { Py_UNICODE *replp; if (outlen < Py_UNICODE_SIZE) RESIZE_OUTBUFFER( errno == EINVAL || Py_UNICODE_SIZE > estep ? Py_UNICODE_SIZE : estep); /* some compilers hate casted lvalue */ replp = (Py_UNICODE *)out; assert((long)replp % Py_UNICODE_SIZE == 0);/* aligned? */ *replp = REPLACEMENT_CHAR_DECODE; out += Py_UNICODE_SIZE; outlen -= Py_UNICODE_SIZE; } if (errno == EINVAL) break; else continue; } errpos = (int)(inp - inp_top); reasonpos += sprintf(reason, "Invalid multibyte sequence \\x%02x", (unsigned char)*inp); if (inplen > 1) { reasonpos += sprintf(reasonpos, "\\x%02x", (unsigned char)*(inp+1)); if (inplen > 2) sprintf(reasonpos, "\\x%02x", (unsigned char)*(inp+2)); } if (exceptionobj == NULL) { exceptionobj = PyUnicodeDecodeError_Create( self->encoding, inp_top, inplen_total, errpos, errpos + 1, reason); if (exceptionobj == NULL) goto errorexit; } else { if (PyUnicodeDecodeError_SetStart(exceptionobj, errpos) != 0) goto errorexit; if (PyUnicodeDecodeError_SetEnd(exceptionobj, errpos + 1) != 0) goto errorexit; if (PyUnicodeDecodeError_SetReason(exceptionobj, reason) != 0) goto errorexit; } if (errorcb == ERROR_STRICT) { PyCodec_StrictErrors(exceptionobj); goto errorexit; } else { PyObject *argsobj, *retobj, *retuni; long newpos; argsobj = PyTuple_New(1); if (argsobj == NULL) goto errorexit; PyTuple_SET_ITEM(argsobj, 0, exceptionobj); Py_INCREF(exceptionobj); retobj = PyObject_CallObject(errorcb, argsobj); Py_DECREF(argsobj); if (retobj == NULL) goto errorexit; if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) || !PyInt_Check(PyTuple_GET_ITEM(retobj, 1))) { Py_DECREF(retobj); PyErr_SetString(PyExc_ValueError, "decoding error handler " "must return (unicode, int) tuple"); goto errorexit; } if (PyUnicode_GET_SIZE(retuni) > 0) { #define errorexit errorexit_cbpad size_t retunisize; retunisize = PyUnicode_GET_DATA_SIZE(retuni); if (outlen < retunisize) RESIZE_OUTBUFFER(errno == EINVAL || retunisize > estep ? retunisize - outlen : estep); memcpy(out, PyUnicode_AS_DATA(retuni), retunisize); out += retunisize; outlen -= retunisize; #undef errorexit if (0) { errorexit_cbpad: Py_DECREF(retobj); goto errorexit; } } newpos = PyInt_AS_LONG(PyTuple_GET_ITEM(retobj, 1)); Py_DECREF(retobj); if (newpos < 0) newpos = inplen_total - newpos; if (newpos < 0 || newpos >= inplen_total) break; inp = inp_top + newpos; inplen = inplen_total - newpos; } } else break; } #undef RESIZE_OUTBUFFER { PyObject *rettup; int finalsize; finalsize = (int)(out - out_top); if (finalsize != outlen_total) { if (PyUnicode_Resize(&outputobj, finalsize / Py_UNICODE_SIZE) == -1) goto errorexit; } if (errorcb > ERROR_MAX) { Py_DECREF(errorcb); } Py_XDECREF(exceptionobj); rettup = PyTuple_New(2); if (rettup == NULL) { Py_DECREF(outputobj); return NULL; } PyTuple_SET_ITEM(rettup, 0, outputobj); PyTuple_SET_ITEM(rettup, 1, PyInt_FromLong(inplen_total)); return rettup; } errorexit: Py_XDECREF(outputobj); if (errorcb > ERROR_MAX) { Py_DECREF(errorcb); } Py_XDECREF(exceptionobj); return NULL; } static struct PyMethodDef iconvcodec_methods[] = { {"encode", (PyCFunction)iconvcodec_encode, METH_VARARGS | METH_KEYWORDS, iconvcodec_encode__doc__}, {"decode", (PyCFunction)iconvcodec_decode, METH_VARARGS | METH_KEYWORDS, iconvcodec_decode__doc__}, {NULL, NULL}, }; static PyObject * iconvcodec_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *encobj = NULL; iconvcodecObject *new = NULL; new = (iconvcodecObject *)type->tp_alloc(type, 0); if (new == NULL) return NULL; new->encoding = NULL; new->enchdl = new->dechdl = (iconv_t)(-1); encobj = PyObject_GetAttrString((PyObject *)new, "encoding"); if (encobj == NULL) { PyErr_Clear(); new->encoding = PyMem_Malloc(sizeof(DEFAULT_ENCODING)); strcpy(new->encoding, DEFAULT_ENCODING); } else if (!PyString_Check(encobj)) { Py_DECREF(encobj); PyErr_SetString(PyExc_TypeError, "`encoding' attribute must be a string."); goto errorexit; } else { new->encoding = PyMem_Malloc(PyString_GET_SIZE(encobj) + 1); strcpy(new->encoding, PyString_AS_STRING(encobj)); Py_DECREF(encobj); } new->dechdl = iconv_open(UNICODE_ENCODING, new->encoding); if (new->dechdl == (iconv_t)(-1)) { PyErr_SetString(PyExc_ValueError, "unsupported decoding"); goto errorexit; } new->enchdl = iconv_open(new->encoding, UNICODE_ENCODING); if (new->enchdl == (iconv_t)(-1)) { PyErr_SetString(PyExc_ValueError, "unsupported encoding"); iconv_close(new->dechdl); new->dechdl = (iconv_t)(-1); goto errorexit; } return (PyObject *)new; errorexit: Py_XDECREF(new); return NULL; } static void iconvcodec_dealloc(iconvcodecObject *self) { _PyObject_GC_UNTRACK(self); if (self->enchdl != (iconv_t)-1) iconv_close(self->enchdl); if (self->dechdl != (iconv_t)-1) iconv_close(self->dechdl); if (self->encoding != NULL) PyMem_Free(self->encoding); PyObject_GC_Del(self); } static PyObject * iconvcodec_repr(PyObject *self) { return PyString_FromFormat("", ((iconvcodecObject *)self)->encoding); } statichere PyTypeObject iconvcodec_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* Number of items for varobject */ "iconvcodec", /* Name of this type */ sizeof(iconvcodecObject), /* Basic object size */ 0, /* Item size for varobject */ (destructor)iconvcodec_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ iconvcodec_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ iconvcodec_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iterext */ iconvcodec_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ iconvcodec_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; static struct PyMethodDef _iconv_codec_methods[] = { {NULL, NULL}, }; void init_iconv_codec(void) { PyObject *m, *d, *t; m = Py_InitModule("_iconv_codec", _iconv_codec_methods); d = PyModule_GetDict(m); t = PyString_FromString(__version__); PyDict_SetItemString(d, "__version__", t); Py_DECREF(t); PyDict_SetItemString(d, "iconvcodec", (PyObject *)(&iconvcodec_Type)); PyModule_AddStringConstant(m, "internal_encoding", UNICODE_ENCODING); if (PyErr_Occurred()) Py_FatalError("can't initialize the _iconv_codec module"); } /* * ex: ts=8 sts=4 et * $Id: _iconv_codec.c,v 1.1 2003/01/26 11:30:36 loewis Exp $ */ From loewis@users.sourceforge.net Sun Jan 26 11:32:46 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 03:32:46 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_copy_reg.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv2726/Lib/test Modified Files: test_copy_reg.py Log Message: Test that True can be copied. Index: test_copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy_reg.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_copy_reg.py 23 Jul 2002 19:03:46 -0000 1.4 --- test_copy_reg.py 26 Jan 2003 11:32:44 -0000 1.5 *************** *** 22,25 **** --- 22,29 ---- type(1), int, "not a callable") + def test_bool(self): + import copy + self.assertEquals(True, copy.copy(True)) + def test_main(): From loewis@users.sourceforge.net Sun Jan 26 11:48:22 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 03:48:22 -0800 Subject: [Python-checkins] python/dist/src/Modules Setup.dist,1.35,1.36 _iconv_codec.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6818/Modules Modified Files: Setup.dist _iconv_codec.c Log Message: Add _iconv_codec to Setup.dist. Use PyModule_ functions. Index: Setup.dist =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.dist,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** Setup.dist 30 Dec 2002 22:08:03 -0000 1.35 --- Setup.dist 26 Jan 2003 11:48:19 -0000 1.36 *************** *** 475,478 **** --- 475,481 ---- #pyexpat pyexpat.c -DHAVE_EXPAT_H -I$(EXPAT_DIR)/lib -L$(EXPAT_DIR) -lexpat + # Wrapper for iconv(3). This requires either GNU iconv, or a native + # iconv implementation (only Linux, Solaris, and BSD are known to work) + #_iconv_codec _iconv_codec -I$(prefix)/include -L$(exec_prefix)/lib -liconv # Example -- included for reference only: Index: _iconv_codec.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _iconv_codec.c 26 Jan 2003 11:30:36 -0000 1.1 --- _iconv_codec.c 26 Jan 2003 11:48:20 -0000 1.2 *************** *** 604,618 **** init_iconv_codec(void) { ! PyObject *m, *d, *t; m = Py_InitModule("_iconv_codec", _iconv_codec_methods); ! d = PyModule_GetDict(m); ! ! t = PyString_FromString(__version__); ! PyDict_SetItemString(d, "__version__", t); ! Py_DECREF(t); ! ! PyDict_SetItemString(d, "iconvcodec", (PyObject *)(&iconvcodec_Type)); PyModule_AddStringConstant(m, "internal_encoding", UNICODE_ENCODING); --- 604,613 ---- init_iconv_codec(void) { ! PyObject *m; m = Py_InitModule("_iconv_codec", _iconv_codec_methods); ! PyModule_AddStringConstant(m, "__version__", (char*)__version__); ! PyModule_AddObject(m, "iconvcodec", (PyObject *)(&iconvcodec_Type)); PyModule_AddStringConstant(m, "internal_encoding", UNICODE_ENCODING); From loewis@users.sourceforge.net Sun Jan 26 12:17:55 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sun, 26 Jan 2003 04:17:55 -0800 Subject: [Python-checkins] python/dist/src/PCbuild pyexpat.dsp,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv17209 Modified Files: pyexpat.dsp Log Message: Define XML_STATIC. Index: pyexpat.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pyexpat.dsp,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pyexpat.dsp 26 Jan 2003 08:40:50 -0000 1.11 --- pyexpat.dsp 26 Jan 2003 12:17:52 -0000 1.12 *************** *** 45,49 **** F90=df.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\Include" /I "..\PC" /I "..\Modules\expat" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /D "XML_DTD" /D BYTEORDER=1234 /D XML_CONTEXT_BYTES=1024 /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 --- 45,49 ---- F90=df.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\Include" /I "..\PC" /I "..\Modules\expat" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "XML_NS" /D "XML_DTD" /D BYTEORDER=1234 /D XML_CONTEXT_BYTES=1024 /D "XML_STATIC" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 *************** *** 73,77 **** F90=df.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\Include" /I "..\PC" /I "..\Modules\expat" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_EXPAT_H" /D "XML_NS" /D "XML_DTD" /D BYTEORDER=1234 /D XML_CONTEXT_BYTES=1024 /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 --- 73,77 ---- F90=df.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c ! # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\Include" /I "..\PC" /I "..\Modules\expat" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_EXPAT_H" /D "XML_NS" /D "XML_DTD" /D BYTEORDER=1234 /D XML_CONTEXT_BYTES=1024 /D "XML_STATIC" /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 From amk@amk.ca Sun Jan 26 13:26:42 2003 From: amk@amk.ca (A.M. Kuchling) Date: Sun, 26 Jan 2003 08:26:42 -0500 Subject: [Python-checkins] python/dist/src/Lib/logging handlers.py,1.2,1.3 In-Reply-To: ; from nnorwitz@users.sourceforge.net on Sat, Jan 25, 2003 at 06:14:25PM -0800 References: Message-ID: <20030126082642.A18759@amk.ca> On Sat, Jan 25, 2003 at 06:14:25PM -0800, nnorwitz@users.sourceforge.net wrote: >SF #642974, logging SysLogHandler proto type wrong > >Syslog uses UDP (SOCK_DGRAM) Actually it varies; some systems use a datagram socket, but others use a stream. I think it changed between two revisions of Red Hat, for example. A little while ago I accepted a patch to the Medusa syslog support that tries to open /dev/log as a datagram socket first, and if that fails tries it as a stream socket. --amk From tim_one@users.sourceforge.net Sun Jan 26 15:46:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 07:46:56 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv8625 Modified Files: pickletools.py Log Message: Added Unicode opcodes. Rearranged opcode order to list the more-likely scalars (ints and 8-bit strings) first. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** pickletools.py 26 Jan 2003 06:03:02 -0000 1.14 --- pickletools.py 26 Jan 2003 15:46:54 -0000 1.15 *************** *** 336,339 **** --- 336,405 ---- """) + + def read_unicodestringnl(f): + """ + >>> import StringIO + >>> read_unicodestringnl(StringIO.StringIO("abc\\uabcd\\njunk")) + u'abc\\uabcd' + """ + + data = f.readline() + if not data.endswith('\n'): + raise ValueError("no newline found when trying to read " + "unicodestringnl") + data = data[:-1] # lose the newline + return unicode(data, 'raw-unicode-escape') + + unicodestringnl = ArgumentDescriptor( + name='unicodestringnl', + n=UP_TO_NEWLINE, + reader=read_unicodestringnl, + doc="""A newline-terminated Unicode string. + + This is raw-unicode-escape encoded, so consists of + printable ASCII characters, and may contain embedded + escape sequences. + """) + + def read_unicodestring4(f): + """ + >>> import StringIO + >>> s = u'abcd\\uabcd' + >>> enc = s.encode('utf-8') + >>> enc + 'abcd\\xea\\xaf\\x8d' + >>> n = chr(len(enc)) + chr(0) * 3 # little-endian 4-byte length + >>> t = read_unicodestring4(StringIO.StringIO(n + enc + 'junk')) + >>> s == t + True + + >>> read_unicodestring4(StringIO.StringIO(n + enc[:-1])) + Traceback (most recent call last): + ... + ValueError: expected 7 bytes in a unicodestring4, but only 6 remain + """ + + n = read_int4(f) + if n < 0: + raise ValueError("unicodestring4 byte count < 0: %d" % n) + data = f.read(n) + if len(data) == n: + return unicode(data, 'utf-8') + raise ValueError("expected %d bytes in a unicodestring4, but only %d " + "remain" % (n, len(data))) + + unicodestring4 = ArgumentDescriptor( + name="unicodestring4", + n=TAKEN_FROM_ARGUMENT, + reader=read_unicodestring4, + doc="""A counted Unicode string. + + The first argument is a 4-byte little-endian signed int + giving the number of bytes in the string, and the second + argument-- the UTF-8 encoding of the Unicode string -- + contains that many bytes. + """) + + def read_decimalnl_short(f): """ *************** *** 728,769 **** """), - # Ways to spell floats. - - I(name='FLOAT', - code='F', - args=[floatnl], - stack_before=[], - stack_after=[pyfloat], - proto=0, - doc="""Newline-terminated decimal float literal. - - The argument is repr(a_float), and in general requires 17 significant - digits for roundtrip conversion to be an identity (this is so for - IEEE-754 double precision values, which is what Python float maps to - on most boxes). - - In general, FLOAT cannot be used to transport infinities, NaNs, or - minus zero across boxes (or even on a single box, if the platform C - library can't read the strings it produces for such things -- Windows - is like that), but may do less damage than BINFLOAT on boxes with - greater precision or dynamic range than IEEE-754 double. - """), - - I(name='BINFLOAT', - code='G', - args=[float8], - stack_before=[], - stack_after=[pyfloat], - proto=1, - doc="""Float stored in binary form, with 8 bytes of data. - - This generally requires less than half the space of FLOAT encoding. - In general, BINFLOAT cannot be used to transport infinities, NaNs, or - minus zero, raises an exception if the exponent exceeds the range of - an IEEE-754 double, and retains no more than 53 bits of precision (if - there are more than that, "add a half and chop" rounding is used to - cut it back to 53 significant bits). - """), - # Ways to spell strings (8-bit, not Unicode). --- 794,797 ---- *************** *** 807,811 **** """), ! # A way to spell None. I(name='NONE', --- 835,839 ---- """), ! # Ways to spell None. I(name='NONE', *************** *** 817,820 **** --- 845,914 ---- doc="Push None on the stack."), + # Ways to spell Unicode strings. + + I(name='UNICODE', + code='V', + args=[unicodestringnl], + stack_before=[], + stack_after=[pyunicode], + proto=0, # this may be pure-text, but it's a later addition + doc="""Push a Python Unicode string object. + + The argument is a raw-unicode-escape encoding of a Unicode string, + and so may contain embedded escape sequences. The argument extends + until the next newline character. + """), + + I(name='BINUNICODE', + code='X', + args=[], + stack_before=[], + stack_after=[pyunicode], + proto=1, + doc="""Push a Python Unicode string object. + + There are two arguments: the first is a 4-byte little-endian signed int + giving the number of bytes in the string. The second is that many + bytes, and is the UTF-8 encoding of the Unicode string. + """), + + # Ways to spell floats. + + I(name='FLOAT', + code='F', + args=[floatnl], + stack_before=[], + stack_after=[pyfloat], + proto=0, + doc="""Newline-terminated decimal float literal. + + The argument is repr(a_float), and in general requires 17 significant + digits for roundtrip conversion to be an identity (this is so for + IEEE-754 double precision values, which is what Python float maps to + on most boxes). + + In general, FLOAT cannot be used to transport infinities, NaNs, or + minus zero across boxes (or even on a single box, if the platform C + library can't read the strings it produces for such things -- Windows + is like that), but may do less damage than BINFLOAT on boxes with + greater precision or dynamic range than IEEE-754 double. + """), + + I(name='BINFLOAT', + code='G', + args=[float8], + stack_before=[], + stack_after=[pyfloat], + proto=1, + doc="""Float stored in binary form, with 8 bytes of data. + + This generally requires less than half the space of FLOAT encoding. + In general, BINFLOAT cannot be used to transport infinities, NaNs, or + minus zero, raises an exception if the exponent exceeds the range of + an IEEE-754 double, and retains no more than 53 bits of precision (if + there are more than that, "add a half and chop" rounding is used to + cut it back to 53 significant bits). + """), + # Empty containers. *************** *** 887,891 **** """), ! # Memo manipulation. There are really only two operations (get and put). I(name='GET', --- 981,986 ---- """), ! # Memo manipulation. There are really only two operations (get and put), ! # each in all-text, "short binary", and "long binary" flavors. I(name='GET', *************** *** 1004,1029 **** I(name='REDUCE', code='R', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='UNICODE', - code='V', - args=[], - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='BINUNICODE', - code='X', args=[], stack_before=[], --- 1099,1102 ---- From tim_one@users.sourceforge.net Sun Jan 26 15:54:27 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 07:54:27 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv10786 Modified Files: pickletools.py Log Message: Gave up the useless view that a pickle opcode may have more than one embedded (in the bytestream) argument. Each has one argument now, or None. If some case arises in which it's useful to view an opcode as having multiple arguments, that can be modeled by saying it has a single tuple of arguments. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** pickletools.py 26 Jan 2003 15:46:54 -0000 1.15 --- pickletools.py 26 Jan 2003 15:54:25 -0000 1.16 *************** *** 669,674 **** 'code', ! # list of 0 or more argument descriptors ! 'args', # what the stack looks like before this opcode runs; a list --- 669,679 ---- 'code', ! # If the opcode has an argument embedded in the byte string, an ! # instance of ArgumentDescriptor specifying its type. Note that ! # arg.reader(s) can be used to read and decode the argument from ! # the bytestream s, and arg.doc documents the format of the raw ! # argument bytes. If the opcode doesn't have an argument embedded ! # in the bytestream, arg should be None. ! 'arg', # what the stack looks like before this opcode runs; a list *************** *** 685,689 **** ) ! def __init__(self, name, code, args, stack_before, stack_after, proto, doc): assert isinstance(name, str) --- 690,694 ---- ) ! def __init__(self, name, code, arg, stack_before, stack_after, proto, doc): assert isinstance(name, str) *************** *** 694,701 **** self.code = code ! assert isinstance(args, list) ! for x in args: ! assert isinstance(x, ArgumentDescriptor) ! self.args = args assert isinstance(stack_before, list) --- 699,704 ---- self.code = code ! assert arg is None or isinstance(arg, ArgumentDescriptor) ! self.arg = arg assert isinstance(stack_before, list) *************** *** 722,726 **** I(name='INT', code='I', ! args=[decimalnl_short], stack_before=[], stack_after=[pyinteger_or_bool], --- 725,729 ---- I(name='INT', code='I', ! arg=decimalnl_short, stack_before=[], stack_after=[pyinteger_or_bool], *************** *** 745,749 **** I(name='LONG', code='L', ! args=[decimalnl_long], stack_before=[], stack_after=[pylong], --- 748,752 ---- I(name='LONG', code='L', ! arg=decimalnl_long, stack_before=[], stack_after=[pylong], *************** *** 758,762 **** I(name='BININT', code='J', ! args=[int4], stack_before=[], stack_after=[pyint], --- 761,765 ---- I(name='BININT', code='J', ! arg=int4, stack_before=[], stack_after=[pyint], *************** *** 772,776 **** I(name='BININT1', code='K', ! args=[uint1], stack_before=[], stack_after=[pyint], --- 775,779 ---- I(name='BININT1', code='K', ! arg=uint1, stack_before=[], stack_after=[pyint], *************** *** 784,788 **** I(name='BININT2', code='M', ! args=[uint2], stack_before=[], stack_after=[pyint], --- 787,791 ---- I(name='BININT2', code='M', ! arg=uint2, stack_before=[], stack_after=[pyint], *************** *** 798,802 **** I(name='STRING', code='S', ! args=[stringnl], stack_before=[], stack_after=[pystring], --- 801,805 ---- I(name='STRING', code='S', ! arg=stringnl, stack_before=[], stack_after=[pystring], *************** *** 811,815 **** I(name='BINSTRING', code='T', ! args=[string4], stack_before=[], stack_after=[pystring], --- 814,818 ---- I(name='BINSTRING', code='T', ! arg=string4, stack_before=[], stack_after=[pystring], *************** *** 824,828 **** I(name='SHORT_BINSTRING', code='U', ! args=[string1], stack_before=[], stack_after=[pystring], --- 827,831 ---- I(name='SHORT_BINSTRING', code='U', ! arg=string1, stack_before=[], stack_after=[pystring], *************** *** 839,843 **** I(name='NONE', code='N', ! args=[], stack_before=[], stack_after=[pynone], --- 842,846 ---- I(name='NONE', code='N', ! arg=None, stack_before=[], stack_after=[pynone], *************** *** 849,853 **** I(name='UNICODE', code='V', ! args=[unicodestringnl], stack_before=[], stack_after=[pyunicode], --- 852,856 ---- I(name='UNICODE', code='V', ! arg=unicodestringnl, stack_before=[], stack_after=[pyunicode], *************** *** 862,866 **** I(name='BINUNICODE', code='X', ! args=[], stack_before=[], stack_after=[pyunicode], --- 865,869 ---- I(name='BINUNICODE', code='X', ! arg=None, stack_before=[], stack_after=[pyunicode], *************** *** 877,881 **** I(name='FLOAT', code='F', ! args=[floatnl], stack_before=[], stack_after=[pyfloat], --- 880,884 ---- I(name='FLOAT', code='F', ! arg=floatnl, stack_before=[], stack_after=[pyfloat], *************** *** 897,901 **** I(name='BINFLOAT', code='G', ! args=[float8], stack_before=[], stack_after=[pyfloat], --- 900,904 ---- I(name='BINFLOAT', code='G', ! arg=float8, stack_before=[], stack_after=[pyfloat], *************** *** 915,919 **** I(name='EMPTY_LIST', code=']', ! args=[], stack_before=[], stack_after=[pylist], --- 918,922 ---- I(name='EMPTY_LIST', code=']', ! arg=None, stack_before=[], stack_after=[pylist], *************** *** 923,927 **** I(name='EMPTY_TUPLE', code=')', ! args=[], stack_before=[], stack_after=[pytuple], --- 926,930 ---- I(name='EMPTY_TUPLE', code=')', ! arg=None, stack_before=[], stack_after=[pytuple], *************** *** 931,935 **** I(name='EMPTY_DICT', code='}', ! args=[], stack_before=[], stack_after=[pydict], --- 934,938 ---- I(name='EMPTY_DICT', code='}', ! arg=None, stack_before=[], stack_after=[pydict], *************** *** 941,945 **** I(name='POP', code='0', ! args=[], stack_before=[anyobject], stack_after=[], --- 944,948 ---- I(name='POP', code='0', ! arg=None, stack_before=[anyobject], stack_after=[], *************** *** 949,953 **** I(name='DUP', code='2', ! args=[], stack_before=[anyobject], stack_after=[anyobject, anyobject], --- 952,956 ---- I(name='DUP', code='2', ! arg=None, stack_before=[anyobject], stack_after=[anyobject, anyobject], *************** *** 957,961 **** I(name='MARK', code='(', ! args=[], stack_before=[], stack_after=[markobject], --- 960,964 ---- I(name='MARK', code='(', ! arg=None, stack_before=[], stack_after=[markobject], *************** *** 970,974 **** I(name='POP_MARK', code='1', ! args=[], stack_before=[markobject, stackslice], stack_after=[], --- 973,977 ---- I(name='POP_MARK', code='1', ! arg=None, stack_before=[markobject, stackslice], stack_after=[], *************** *** 986,990 **** I(name='GET', code='g', ! args=[decimalnl_short], stack_before=[], stack_after=[anyobject], --- 989,993 ---- I(name='GET', code='g', ! arg=decimalnl_short, stack_before=[], stack_after=[anyobject], *************** *** 999,1003 **** I(name='BINGET', code='h', ! args=[uint1], stack_before=[], stack_after=[anyobject], --- 1002,1006 ---- I(name='BINGET', code='h', ! arg=uint1, stack_before=[], stack_after=[anyobject], *************** *** 1011,1015 **** I(name='LONG_BINGET', code='j', ! args=[int4], stack_before=[], stack_after=[anyobject], --- 1014,1018 ---- I(name='LONG_BINGET', code='j', ! arg=int4, stack_before=[], stack_after=[anyobject], *************** *** 1023,1027 **** I(name='PUT', code='p', ! args=[decimalnl_short], stack_before=[], stack_after=[], --- 1026,1030 ---- I(name='PUT', code='p', ! arg=decimalnl_short, stack_before=[], stack_after=[], *************** *** 1036,1040 **** I(name='BINPUT', code='q', ! args=[uint1], stack_before=[], stack_after=[], --- 1039,1043 ---- I(name='BINPUT', code='q', ! arg=uint1, stack_before=[], stack_after=[], *************** *** 1048,1052 **** I(name='LONG_BINPUT', code='r', ! args=[int4], stack_before=[], stack_after=[], --- 1051,1055 ---- I(name='LONG_BINPUT', code='r', ! arg=int4, stack_before=[], stack_after=[], *************** *** 1062,1066 **** I(name='STOP', code='.', ! args=[], stack_before=[anyobject], stack_after=[], --- 1065,1069 ---- I(name='STOP', code='.', ! arg=None, stack_before=[anyobject], stack_after=[], *************** *** 1077,1081 **** I(name='PERSID', code='P', ! args=[], stack_before=[], stack_after=[], --- 1080,1084 ---- I(name='PERSID', code='P', ! arg=None, stack_before=[], stack_after=[], *************** *** 1088,1092 **** I(name='BINPERSID', code='Q', ! args=[], stack_before=[], stack_after=[], --- 1091,1095 ---- I(name='BINPERSID', code='Q', ! arg=None, stack_before=[], stack_after=[], *************** *** 1099,1103 **** I(name='REDUCE', code='R', ! args=[], stack_before=[], stack_after=[], --- 1102,1106 ---- I(name='REDUCE', code='R', ! arg=None, stack_before=[], stack_after=[], *************** *** 1110,1114 **** I(name='APPEND', code='a', ! args=[], stack_before=[], stack_after=[], --- 1113,1117 ---- I(name='APPEND', code='a', ! arg=None, stack_before=[], stack_after=[], *************** *** 1121,1125 **** I(name='BUILD', code='b', ! args=[], stack_before=[], stack_after=[], --- 1124,1128 ---- I(name='BUILD', code='b', ! arg=None, stack_before=[], stack_after=[], *************** *** 1132,1136 **** I(name='GLOBAL', code='c', ! args=[], stack_before=[], stack_after=[], --- 1135,1139 ---- I(name='GLOBAL', code='c', ! arg=None, stack_before=[], stack_after=[], *************** *** 1143,1147 **** I(name='DICT', code='d', ! args=[], stack_before=[], stack_after=[], --- 1146,1150 ---- I(name='DICT', code='d', ! arg=None, stack_before=[], stack_after=[], *************** *** 1154,1158 **** I(name='APPENDS', code='e', ! args=[], stack_before=[], stack_after=[], --- 1157,1161 ---- I(name='APPENDS', code='e', ! arg=None, stack_before=[], stack_after=[], *************** *** 1165,1169 **** I(name='INST', code='i', ! args=[], stack_before=[], stack_after=[], --- 1168,1172 ---- I(name='INST', code='i', ! arg=None, stack_before=[], stack_after=[], *************** *** 1176,1180 **** I(name='LIST', code='l', ! args=[], stack_before=[], stack_after=[], --- 1179,1183 ---- I(name='LIST', code='l', ! arg=None, stack_before=[], stack_after=[], *************** *** 1187,1191 **** I(name='OBJ', code='o', ! args=[], stack_before=[], stack_after=[], --- 1190,1194 ---- I(name='OBJ', code='o', ! arg=None, stack_before=[], stack_after=[], *************** *** 1198,1202 **** I(name='SETITEM', code='s', ! args=[], stack_before=[], stack_after=[], --- 1201,1205 ---- I(name='SETITEM', code='s', ! arg=None, stack_before=[], stack_after=[], *************** *** 1209,1213 **** I(name='TUPLE', code='t', ! args=[], stack_before=[], stack_after=[], --- 1212,1216 ---- I(name='TUPLE', code='t', ! arg=None, stack_before=[], stack_after=[], *************** *** 1220,1224 **** I(name='SETITEMS', code='u', ! args=[], stack_before=[], stack_after=[], --- 1223,1227 ---- I(name='SETITEMS', code='u', ! arg=None, stack_before=[], stack_after=[], From tim_one@users.sourceforge.net Sun Jan 26 16:10:49 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 08:10:49 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv17052 Modified Files: pickletools.py Log Message: Added list-extenders. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** pickletools.py 26 Jan 2003 15:54:25 -0000 1.16 --- pickletools.py 26 Jan 2003 16:10:46 -0000 1.17 *************** *** 123,128 **** 'name', ! # length of argument, in bytes; an int; UP_TO_NEWLINE means variable- ! # length, ending at the next occurrence of a newline character 'n', --- 123,128 ---- 'name', ! # length of argument, in bytes; an int; UP_TO_NEWLINE and ! # TAKEN_FROM_ARGUMENT are negative values for variable-length cases 'n', *************** *** 143,147 **** n is UP_TO_NEWLINE or n is TAKEN_FROM_ARGUMENT) - self.n = n --- 143,146 ---- *************** *** 940,943 **** --- 939,968 ---- doc="Push an empty dict."), + # Ways to build lists. + + I(name='APPEND', + code='a', + arg=None, + stack_before=[pylist, anyobject], + stack_after=[pylist], + proto=0, + doc="""Append an object to a list. + + Stack before: ... alist anobject + Stack after: ... alist+[anobject] + """), + + I(name='APPENDS', + code='e', + arg=None, + stack_before=[pylist, markobject, stackslice], + stack_after=[pylist], + proto=0, + doc="""Extend a list by a slice of stack objects. + + Stack before: ... alist markobject rest_of_stack + Stack after: ... alist+rest_of_stack + """), + # Stack manipulation. *************** *** 1111,1125 **** """), - I(name='APPEND', - code='a', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - I(name='BUILD', code='b', --- 1136,1139 ---- *************** *** 1146,1160 **** I(name='DICT', code='d', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='APPENDS', - code='e', arg=None, stack_before=[], --- 1160,1163 ---- From nnorwitz@users.sourceforge.net Sun Jan 26 16:15:26 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 26 Jan 2003 08:15:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/logging handlers.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1:/tmp/cvs-serv18306/Lib/logging Modified Files: handlers.py Log Message: amk pointed out that syslog may use UDP or TCP sockets. Update to try UDP, if that fails, try TCP. Index: handlers.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/handlers.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** handlers.py 26 Jan 2003 02:14:23 -0000 1.3 --- handlers.py 26 Jan 2003 16:15:24 -0000 1.4 *************** *** 350,354 **** if type(address) == types.StringType: self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) ! self.socket.connect(address) self.unixsocket = 1 else: --- 350,360 ---- if type(address) == types.StringType: self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) ! # syslog may require either DGRAM or STREAM sockets ! try: ! self.socket.connect(address) ! except socket.error: ! self.socket.close() ! self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) ! self.socket.connect(address) self.unixsocket = 1 else: From nnorwitz@users.sourceforge.net Sun Jan 26 16:26:23 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sun, 26 Jan 2003 08:26:23 -0800 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv22415/Modules Modified Files: _iconv_codec.c Log Message: Get rid of compiler warnings on Redhat Index: _iconv_codec.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _iconv_codec.c 26 Jan 2003 11:48:20 -0000 1.2 --- _iconv_codec.c 26 Jan 2003 16:26:20 -0000 1.3 *************** *** 123,127 **** } while (inplen > 0) { ! if (iconv(self->enchdl, &inp, &inplen, &out, &outlen) == -1) { char reason[128]; int errpos; --- 123,127 ---- } while (inplen > 0) { ! if (iconv(self->enchdl, (char**)&inp, &inplen, &out, &outlen) == -1) { char reason[128]; int errpos; *************** *** 320,324 **** } while (inplen > 0) { ! if (iconv(self->dechdl, &inp, &inplen, &out, &outlen) == -1) { char reason[128], *reasonpos = (char *)reason; int errpos; --- 320,324 ---- } while (inplen > 0) { ! if (iconv(self->dechdl, (char**)&inp, &inplen, &out, &outlen) == -1) { char reason[128], *reasonpos = (char *)reason; int errpos; From tim_one@users.sourceforge.net Sun Jan 26 17:29:49 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 09:29:49 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv12022 Modified Files: pickletools.py Log Message: Ensure this module is defiing the same opcode names, with the same opcode codes, as pickle.py. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** pickletools.py 26 Jan 2003 16:10:46 -0000 1.17 --- pickletools.py 26 Jan 2003 17:29:46 -0000 1.18 *************** *** 1256,1259 **** --- 1256,1310 ---- del name2i, code2i, i, d + ############################################################################## + # Build a code2op dict, mapping opcode characters to OpcodeInfo records. + # Also ensure we've got the same stuff as pickle.py, although the + # introspection here is dicey. + + code2op = {} + for d in opcodes: + code2op[d.code] = d + del d + + def assure_pickle_consistency(verbose=False): + import pickle, re + + copy = code2op.copy() + for name in pickle.__all__: + if not re.match("[A-Z][A-Z0-9_]+$", name): + if verbose: + print "skipping %r: it doesn't look like an opcode name" % name + continue + picklecode = getattr(pickle, name) + if not isinstance(picklecode, str) or len(picklecode) != 1: + if verbose: + print ("skipping %r: value %r doesn't look like a pickle " + "code" % (name, picklecode)) + continue + if picklecode in copy: + if verbose: + print "checking name %r w/ code %r for consistency" % ( + name, picklecode) + d = copy[picklecode] + if d.name != name: + raise ValueError("for pickle code %r, pickle.py uses name %r " + "but we're using name %r" % (picklecode, + name, + d.name)) + # Forget this one. Any left over in copy at the end are a problem + # of a different kind. + del copy[picklecode] + else: + raise ValueError("pickle.py appears to have a pickle opcode with " + "name %r and code %r, but we don't" % + (name, picklecode)) + if copy: + msg = ["we appear to have pickle opcodes that pickle.py doesn't have:"] + for code, d in copy.items(): + msg.append(" name %r with code %r" % (d.name, code)) + raise ValueError("\n".join(msg)) + + assure_pickle_consistency() + + def _test(): import doctest From tim_one@users.sourceforge.net Sun Jan 26 17:45:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 09:45:41 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv18250 Modified Files: pickletools.py Log Message: Minor fiddling to text. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** pickletools.py 26 Jan 2003 17:29:46 -0000 1.18 --- pickletools.py 26 Jan 2003 17:45:37 -0000 1.19 *************** *** 728,732 **** stack_after=[pyinteger_or_bool], proto=0, ! doc="""Push an integer or bool. The argument is a decimal literal string. The intent may have been that this always fit in a short Python int, --- 728,734 ---- stack_after=[pyinteger_or_bool], proto=0, ! doc="""Push an integer or bool. ! ! The argument is a newline-terminated decimal literal string. The intent may have been that this always fit in a short Python int, *************** *** 741,745 **** True gets pickled as INT + "I01\\n", and False as INT + "I00\\n". Leading zeroes are never produced for a genuine integer. The 2.3 ! (and later) unpicklers special-case these and return bool instead; earlier unpicklers ignore the leading "0" and return the int. """), --- 743,747 ---- True gets pickled as INT + "I01\\n", and False as INT + "I00\\n". Leading zeroes are never produced for a genuine integer. The 2.3 ! (and later) unpicklers special-case these and return bool instead; earlier unpicklers ignore the leading "0" and return the int. """), *************** *** 751,755 **** stack_after=[pylong], proto=0, ! doc="""Push a long integer. The argument is a decimal literal string. The same as INT, except that the literal ends with 'L', and always --- 753,757 ---- stack_after=[pylong], proto=0, ! doc="""Push a long integer. The same as INT, except that the literal ends with 'L', and always *************** *** 793,797 **** This is a space optimization for pickling small positive ints, in ! range(1, 2**16). """), --- 795,800 ---- This is a space optimization for pickling small positive ints, in ! range(256, 2**16). Integers in range(256) can also be pickled via ! BININT2, but BININT1 instead saves a byte. """), *************** *** 949,954 **** doc="""Append an object to a list. ! Stack before: ... alist anobject ! Stack after: ... alist+[anobject] """), --- 952,957 ---- doc="""Append an object to a list. ! Stack before: ... pylist anyobject ! Stack after: ... pylist+[anyobject] """), *************** *** 961,966 **** doc="""Extend a list by a slice of stack objects. ! Stack before: ... alist markobject rest_of_stack ! Stack after: ... alist+rest_of_stack """), --- 964,969 ---- doc="""Extend a list by a slice of stack objects. ! Stack before: ... pylist markobject stackslice ! Stack after: ... pylist+stackslice """), *************** *** 973,977 **** stack_after=[], proto=0, ! doc="Discard the top stack item."), I(name='DUP', --- 976,980 ---- stack_after=[], proto=0, ! doc="Discard the top stack item, shrinking the stack by one item."), I(name='DUP', *************** *** 989,995 **** stack_after=[markobject], proto=0, ! doc="""Push a marker object onto the stack. ! The marker is a unique object, used by other opcodes to identify a region of the stack containing a variable number of objects for them to work on. See markobject.doc for more detail. --- 992,998 ---- stack_after=[markobject], proto=0, ! doc="""Push markobject onto the stack. ! markobject is a unique object, used by other opcodes to identify a region of the stack containing a variable number of objects for them to work on. See markobject.doc for more detail. *************** *** 1002,1010 **** stack_after=[], proto=0, ! doc="""Pop all the stack objects at and above the topmost marker object. When an opcode using a variable number of stack objects is done, ! POP_MARK is used to remove those objects, and to remove the marker ! object that delimited their starting position on the stack. """), --- 1005,1013 ---- stack_after=[], proto=0, ! doc="""Pop all the stack objects at and above the topmost markobject. When an opcode using a variable number of stack objects is done, ! POP_MARK is used to remove those objects, and to remove the markobject ! that delimited their starting position on the stack. """), *************** *** 1018,1022 **** stack_after=[anyobject], proto=0, ! doc="""Push a memo object on the stack. The index of the memo object to push is given by the newline-teriminated --- 1021,1025 ---- stack_after=[anyobject], proto=0, ! doc="""Read an object from the memo and push it on the stack. The index of the memo object to push is given by the newline-teriminated *************** *** 1031,1035 **** stack_after=[anyobject], proto=1, ! doc="""Push a memo object on the stack. The index of the memo object to push is given by the 1-byte unsigned --- 1034,1038 ---- stack_after=[anyobject], proto=1, ! doc="""Read an object from the memo and push it on the stack. The index of the memo object to push is given by the 1-byte unsigned *************** *** 1043,1047 **** stack_after=[anyobject], proto=1, ! doc="""Push a memo object on the stack. The index of the memo object to push is given by the 4-byte signed --- 1046,1050 ---- stack_after=[anyobject], proto=1, ! doc="""Read an object from the memo and push it on the stack. The index of the memo object to push is given by the 4-byte signed From tim_one@users.sourceforge.net Sun Jan 26 17:57:15 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 09:57:15 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv22842 Modified Files: pickletools.py Log Message: Added LIST. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** pickletools.py 26 Jan 2003 17:45:37 -0000 1.19 --- pickletools.py 26 Jan 2003 17:57:12 -0000 1.20 *************** *** 968,971 **** --- 968,987 ---- """), + I(name='LIST', + code='l', + arg=None, + stack_before=[markobject, stackslice], + stack_after=[pylist], + proto=0, + doc="""Build a list out of the topmost stack slice, after markobject. + + All the stack entries following the topmost markobject are placed into + a single Python list, which single list object replaces all of the + stack from the topmost markobject onward. For example, + + Stack before: ... markobject 1 2 3 'abc' + Stack after: ... [1, 2, 3, 'abc'] + """), + # Stack manipulation. *************** *** 1174,1188 **** I(name='INST', code='i', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='LIST', - code='l', arg=None, stack_before=[], --- 1190,1193 ---- From tim_one@users.sourceforge.net Sun Jan 26 18:06:08 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 10:06:08 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv26278 Modified Files: pickletools.py Log Message: Added DICT and TUPLE; rearranged to group container-type-specific opcodes by container type. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** pickletools.py 26 Jan 2003 17:57:12 -0000 1.20 --- pickletools.py 26 Jan 2003 18:06:00 -0000 1.21 *************** *** 916,920 **** """), ! # Empty containers. I(name='EMPTY_LIST', --- 916,920 ---- """), ! # Ways to build lists. I(name='EMPTY_LIST', *************** *** 926,947 **** doc="Push an empty list."), - I(name='EMPTY_TUPLE', - code=')', - arg=None, - stack_before=[], - stack_after=[pytuple], - proto=0, - doc="Push an empty tuple."), - - I(name='EMPTY_DICT', - code='}', - arg=None, - stack_before=[], - stack_after=[pydict], - proto=0, - doc="Push an empty dict."), - - # Ways to build lists. - I(name='APPEND', code='a', --- 926,929 ---- *************** *** 984,987 **** --- 966,1022 ---- """), + # Ways to build tuples. + + I(name='EMPTY_TUPLE', + code=')', + arg=None, + stack_before=[], + stack_after=[pytuple], + proto=0, + doc="Push an empty tuple."), + + I(name='TUPLE', + code='t', + arg=None, + stack_before=[markobject, stackslice], + stack_after=[pytuple], + proto=0, + doc="""Build a tuple out of the topmost stack slice, after markobject. + + All the stack entries following the topmost markobject are placed into + a single Python tuple, which single tuple object replaces all of the + stack from the topmost markobject onward. For example, + + Stack before: ... markobject 1 2 3 'abc' + Stack after: ... (1, 2, 3, 'abc') + """), + + # Ways to build dicts. + + I(name='EMPTY_DICT', + code='}', + arg=None, + stack_before=[], + stack_after=[pydict], + proto=0, + doc="Push an empty dict."), + + I(name='DICT', + code='d', + arg=None, + stack_before=[markobject, stackslice], + stack_after=[pydict], + proto=0, + doc="""Build a dict out of the topmost stack slice, after markobject. + + All the stack entries following the topmost markobject are placed into + a single Python dict, which single dict object replaces all of the + stack from the topmost markobject onward. The stack slice alternates + key, value, key, value, .... For example, + + Stack before: ... markobject 1 2 3 'abc' + Stack after: ... {1: 2, 3: 'abc'} + """), + # Stack manipulation. *************** *** 1177,1191 **** """), - I(name='DICT', - code='d', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - I(name='INST', code='i', --- 1212,1215 ---- *************** *** 1212,1226 **** I(name='SETITEM', code='s', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='TUPLE', - code='t', arg=None, stack_before=[], --- 1236,1239 ---- From tim_one@users.sourceforge.net Sun Jan 26 18:17:09 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 10:17:09 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv31724 Modified Files: pickletools.py Log Message: Added SETITEM and SETITEMS. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** pickletools.py 26 Jan 2003 18:06:00 -0000 1.21 --- pickletools.py 26 Jan 2003 18:17:06 -0000 1.22 *************** *** 1019,1022 **** --- 1019,1057 ---- """), + I(name='SETITEM', + code='s', + arg=None, + stack_before=[pydict, anyobject, anyobject], + stack_after=[pydict], + proto=0, + doc="""Add a key+value pair to an existing dict. + + Stack before: ... pydict key value + Stack after: ... pydict + + where pydict has been modified via pydict[key] = value. + """), + + I(name='SETITEMS', + code='u', + arg=None, + stack_before=[pydict, markobject, stackslice], + stack_after=[pydict], + proto=1, + doc="""Add an arbitrary number of key+value pairs to an existing dict. + + The slice of the stack following the topmost markobject is taken as + an alternating sequence of keys and values, added to the dict + immediately under the topmost markobject. Everything at and after the + topmost markobject is popped, leaving the mutated dict at the top + of the stack. + + Stack before: ... pydict markobject key_1 value_1 ... key_n value_n + Stack after: ... pydict + + where pydict has been modified via pydict[key_i] = value_i for i in + 1, 2, ..., n, and in that order. + """), + # Stack manipulation. *************** *** 1225,1250 **** I(name='OBJ', code='o', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='SETITEM', - code='s', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='SETITEMS', - code='u', arg=None, stack_before=[], --- 1260,1263 ---- From tim_one@users.sourceforge.net Sun Jan 26 18:34:31 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 10:34:31 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv6934 Modified Files: pickletools.py Log Message: Added PERSID and BINPERSID. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** pickletools.py 26 Jan 2003 18:17:06 -0000 1.22 --- pickletools.py 26 Jan 2003 18:34:29 -0000 1.23 *************** *** 272,275 **** --- 272,288 ---- """) + def read_stringnl_noescape(f): + return read_stringnl(f, decode=False, stripquotes=False) + + stringnl_noescape = ArgumentDescriptor( + name='stringnl_noescape', + n=UP_TO_NEWLINE, + reader=read_stringnl_noescape, + doc="""A newline-terminated string. + + This is a str-style string, without embedded escapes, + or bracketing quotes. It should consist solely of + printable ASCII characters. + """) def read_string4(f): *************** *** 1190,1204 **** """), ! # XXX opcodes below this point haven't been done yet. I(name='PERSID', code='P', ! arg=None, stack_before=[], ! stack_after=[], proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), --- 1203,1223 ---- """), ! # Ways to deal with persistent IDs. I(name='PERSID', code='P', ! arg=stringnl_noescape, stack_before=[], ! stack_after=[anyobject], proto=0, ! doc="""Push an object identified by a persisent ID. ! The pickle module doesn't define what a persisent ID means. PERSID's ! argument is a newline-terminated str-style (no embedded escapes, no ! bracketing quote characters) string, which *is* "the persistent ID". ! The unpickler passes this string to self.persistent_load(). Whatever ! object that returns is pushed on the stack. There is no implementation ! of persistent_load() in Python's unpickler: it must be supplied by an ! unpickler subclass. """), *************** *** 1206,1216 **** code='Q', arg=None, ! stack_before=[], ! stack_after=[], ! proto=0, ! doc="""XXX One-line description goes here. ! XXX Doc body goes here. """), I(name='REDUCE', --- 1225,1240 ---- code='Q', arg=None, ! stack_before=[anyobject], ! stack_after=[anyobject], ! proto=1, ! doc="""Push an object identified by a persistent ID. ! Like PERSID, except the persistent ID is popped off the stack (instead ! of being a string embedded in the opcode bytestream). The persistent ! ID is passed to self.persistent_load(), and whatever object that ! returns is pushed on the stack. See PERSID for more detail. """), + + # XXX opcodes below this point haven't been done yet. I(name='REDUCE', From tim_one@users.sourceforge.net Sun Jan 26 19:34:20 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 11:34:20 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv6153 Modified Files: pickletools.py Log Message: As a sanity check on where this is going, implemented a generic pickle Walker base class, and a pickle disassembler subclass. I'm very happy with both: the code is extremely simple (given all the hair that came before this!). Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** pickletools.py 26 Jan 2003 18:34:29 -0000 1.23 --- pickletools.py 26 Jan 2003 19:34:17 -0000 1.24 *************** *** 880,884 **** I(name='BINUNICODE', code='X', ! arg=None, stack_before=[], stack_after=[pyunicode], --- 880,884 ---- I(name='BINUNICODE', code='X', ! arg=unicodestring4, stack_before=[], stack_after=[pyunicode], *************** *** 936,940 **** stack_before=[], stack_after=[pylist], ! proto=0, doc="Push an empty list."), --- 936,940 ---- stack_before=[], stack_after=[pylist], ! proto=1, doc="Push an empty list."), *************** *** 986,990 **** stack_before=[], stack_after=[pytuple], ! proto=0, doc="Push an empty tuple."), --- 986,990 ---- stack_before=[], stack_after=[pytuple], ! proto=1, doc="Push an empty tuple."), *************** *** 1012,1016 **** stack_before=[], stack_after=[pydict], ! proto=0, doc="Push an empty dict."), --- 1012,1016 ---- stack_before=[], stack_after=[pydict], ! proto=1, doc="Push an empty dict."), *************** *** 1364,1367 **** --- 1364,1517 ---- assure_pickle_consistency() + ############################################################################## + # A pickle walker base clase. + + class Walker: + def __init__(self, pickle): + """pickle is a file-like object containing a pickle bytestream. + + Inovoking walk() traverses the pickle, calling visit() for each + opcode encouterned, then calling done() once at the end. Subclasses + will want to override visit(), and possibly done(). The default + implementations do nothing. + """ + + self.pickle = pickle + + if hasattr(pickle, 'tell'): + def position(): + return pickle.tell() + else: + def position(): + return None + + self.position = position + + def walk(self): + """"Run" the pickle, from the current position, until a STOP opcode. + + For each opcode encountered, calls + + self.visit(opcode, arg, pos) + + opcode is an OpcodeInfo record, describing the current opcode. + + If the opcode has an argument embedded in the pickle, arg contains + its decoded value, as a Python object. If the opcode doesn't have + an argument, arg is None. + + If the pickle has a tell() method, pos was the value of pickle.tell() + before reading the current opcode. Else pos is None. + + After a STOP opcode triggers a visit() call, self.done() is called + once. + """ + + pickle = self.pickle + position = self.position + while True: + pos = position() + code = pickle.read(1) + opcode = code2op.get(code) + if opcode is None: + if code == "": + raise ValueError("pickle exhausted before seeing STOP") + else: + raise ValueError("at position %s, opcode %r unknown" % ( + pos is None and "" or pos, + code)) + if opcode.arg is None: + arg = None + else: + arg = opcode.arg.reader(pickle) + self.visit(opcode, arg, pos) + if code == '.': + assert opcode.name == 'STOP' + break + self.done() + + def visit(self, opcode, arg, pos): + "Called once per opcode. See the walk() docs for argument details." + pass + + def done(self): + "Called after STOP is passed to visit()." + pass + + class Dis(Walker): + def __init__(self, pickle, out=None): + Walker.__init__(self, pickle) + self.out = out + + def visit(self, opcode, arg, pos): + out = self.out + if pos is not None: + print >> out, "%5d:" % pos, + print opcode.code, + if arg is None: + print >> out, opcode.name + else: + print >> out, "%-10s %r" % (opcode.name, arg) + + _disassembler_test = """ + >>> from StringIO import StringIO + >>> import pickle + >>> x = [1, 2, (3, 4), {'abc': u"def"}] + >>> pik = pickle.dumps(x) + >>> stream = StringIO(pik) + >>> d = Dis(stream) + >>> d.walk() + 0: ( MARK + 1: l LIST + 2: p PUT 0 + 5: I INT 1 + 8: a APPEND + 9: I INT 2 + 12: a APPEND + 13: ( MARK + 14: I INT 3 + 17: I INT 4 + 20: t TUPLE + 21: p PUT 1 + 24: a APPEND + 25: ( MARK + 26: d DICT + 27: p PUT 2 + 30: S STRING 'abc' + 37: p PUT 3 + 40: V UNICODE u'def' + 45: p PUT 4 + 48: s SETITEM + 49: a APPEND + 50: . STOP + + Try again with a "binary" pickle. + >>> pik = pickle.dumps(x, 1) + >>> stream = StringIO(pik) + >>> d = Dis(stream) + >>> d.walk() + 0: ] EMPTY_LIST + 1: q BINPUT 0 + 3: ( MARK + 4: K BININT1 1 + 6: K BININT1 2 + 8: ( MARK + 9: K BININT1 3 + 11: K BININT1 4 + 13: t TUPLE + 14: q BINPUT 1 + 16: } EMPTY_DICT + 17: q BINPUT 2 + 19: U SHORT_BINSTRING 'abc' + 24: q BINPUT 3 + 26: X BINUNICODE u'def' + 34: q BINPUT 4 + 36: s SETITEM + 37: e APPENDS + 38: . STOP + """ + + __test__ = {'dissassembler_test': _disassembler_test, + } def _test(): From tim_one@users.sourceforge.net Sun Jan 26 20:04:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 12:04:41 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv20402 Modified Files: pickletools.py Log Message: Typo repair. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** pickletools.py 26 Jan 2003 19:34:17 -0000 1.24 --- pickletools.py 26 Jan 2003 20:04:35 -0000 1.25 *************** *** 1371,1376 **** """pickle is a file-like object containing a pickle bytestream. ! Inovoking walk() traverses the pickle, calling visit() for each ! opcode encouterned, then calling done() once at the end. Subclasses will want to override visit(), and possibly done(). The default implementations do nothing. --- 1371,1376 ---- """pickle is a file-like object containing a pickle bytestream. ! Invoking walk() traverses the pickle, calling visit() for each ! opcode encountered, then calling done() once at the end. Subclasses will want to override visit(), and possibly done(). The default implementations do nothing. *************** *** 1448,1452 **** if pos is not None: print >> out, "%5d:" % pos, ! print opcode.code, if arg is None: print >> out, opcode.name --- 1448,1452 ---- if pos is not None: print >> out, "%5d:" % pos, ! print >> out, opcode.code, if arg is None: print >> out, opcode.name From jackjansen@users.sourceforge.net Sun Jan 26 20:22:21 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 12:22:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac EasyDialogs.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv26610 Modified Files: EasyDialogs.py Log Message: FSRef and EasyDialogs pathname support was pretty much broken in MacPython-OS9. Fixed. Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/EasyDialogs.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** EasyDialogs.py 21 Jan 2003 22:57:53 -0000 1.6 --- EasyDialogs.py 26 Jan 2003 20:22:18 -0000 1.7 *************** *** 35,38 **** --- 35,39 ---- import macresource import os + import sys __all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel', *************** *** 636,642 **** return tpwanted(rr.selection[0]) if issubclass(tpwanted, str): ! return tpwanted(rr.selection_fsr[0].FSRefMakePath()) if issubclass(tpwanted, unicode): ! return tpwanted(rr.selection_fsr[0].FSRefMakePath(), 'utf8') raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) --- 637,643 ---- return tpwanted(rr.selection[0]) if issubclass(tpwanted, str): ! return tpwanted(rr.selection_fsr[0].as_pathname()) if issubclass(tpwanted, unicode): ! return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8') raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) *************** *** 687,697 **** return tpwanted(rr.selection[0]) if issubclass(tpwanted, (str, unicode)): ! # This is gross, and probably incorrect too ! vrefnum, dirid, name = rr.selection[0].as_tuple() ! pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, '')) ! pardir_fsr = Carbon.File.FSRef(pardir_fss) ! pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8 ! name_utf8 = unicode(name, 'macroman').encode('utf8') ! fullpath = os.path.join(pardir_path, name_utf8) if issubclass(tpwanted, unicode): return unicode(fullpath, 'utf8') --- 688,701 ---- return tpwanted(rr.selection[0]) if issubclass(tpwanted, (str, unicode)): ! if sys.platform == 'mac': ! fullpath = rr.selection[0].as_pathname() ! else: ! # This is gross, and probably incorrect too ! vrefnum, dirid, name = rr.selection[0].as_tuple() ! pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, '')) ! pardir_fsr = Carbon.File.FSRef(pardir_fss) ! pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8 ! name_utf8 = unicode(name, 'macroman').encode('utf8') ! fullpath = os.path.join(pardir_path, name_utf8) if issubclass(tpwanted, unicode): return unicode(fullpath, 'utf8') *************** *** 742,753 **** return tpwanted(rr.selection[0]) if issubclass(tpwanted, str): ! return tpwanted(rr.selection_fsr[0].FSRefMakePath()) if issubclass(tpwanted, unicode): ! return tpwanted(rr.selection_fsr[0].FSRefMakePath(), 'utf8') raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) def test(): ! import time, sys, macfs Message("Testing EasyDialogs.") --- 746,757 ---- return tpwanted(rr.selection[0]) if issubclass(tpwanted, str): ! return tpwanted(rr.selection_fsr[0].as_pathname()) if issubclass(tpwanted, unicode): ! return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8') raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted) def test(): ! import time, macfs Message("Testing EasyDialogs.") From jackjansen@users.sourceforge.net Sun Jan 26 20:22:44 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 12:22:44 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/file _Filemodule.c,1.14,1.15 filesupport.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/file In directory sc8-pr-cvs1:/tmp/cvs-serv26764 Modified Files: _Filemodule.c filesupport.py Log Message: FSRef and EasyDialogs pathname support was pretty much broken in MacPython-OS9. Fixed. Index: _Filemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/_Filemodule.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** _Filemodule.c 19 Jan 2003 22:59:52 -0000 1.14 --- _Filemodule.c 26 Jan 2003 20:22:40 -0000 1.15 *************** *** 1841,1845 **** --- 1841,1864 ---- PyObject *_res = NULL; + #if TARGET_API_MAC_OSX + if (!PyArg_ParseTuple(_args, "")) + return NULL; _res = FSRef_FSRefMakePath(_self, _args); + #else + char strbuf[1024]; + OSErr err; + FSSpec fss; + + if (!PyArg_ParseTuple(_args, "")) + return NULL; + if ( !PyMac_GetFSSpec((PyObject *)_self, &fss)) + return NULL; + err = PyMac_GetFullPathname(&fss, strbuf, sizeof(strbuf)); + if ( err ) { + PyMac_Error(err); + return NULL; + } + _res = PyString_FromString(strbuf); + #endif return _res; *************** *** 3191,3194 **** --- 3210,3214 ---- { OSStatus err; + FSSpec fss; if (FSRef_Check(v)) { *************** *** 3209,3214 **** #endif /* Otherwise we try to go via an FSSpec */ if (FSSpec_Check(v)) { ! if ((err=FSpMakeFSRef(&((FSSpecObject *)v)->ob_itself, fsr)) == 0) return 1; PyMac_Error(err); --- 3229,3239 ---- #endif /* Otherwise we try to go via an FSSpec */ + #if TARGET_API_MAC_OSX if (FSSpec_Check(v)) { ! fss = ((FSSpecObject *)v)->ob_itself; ! #else ! if (PyMac_GetFSSpec(v, &fss)) { ! #endif ! if ((err=FSpMakeFSRef(&fss, fsr)) == 0) return 1; PyMac_Error(err); Index: filesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filesupport.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** filesupport.py 19 Jan 2003 22:59:52 -0000 1.13 --- filesupport.py 26 Jan 2003 20:22:41 -0000 1.14 *************** *** 272,275 **** --- 272,276 ---- { OSStatus err; + FSSpec fss; if (FSRef_Check(v)) { *************** *** 290,295 **** #endif /* Otherwise we try to go via an FSSpec */ if (FSSpec_Check(v)) { ! if ((err=FSpMakeFSRef(&((FSSpecObject *)v)->ob_itself, fsr)) == 0) return 1; PyMac_Error(err); --- 291,301 ---- #endif /* Otherwise we try to go via an FSSpec */ + #if TARGET_API_MAC_OSX if (FSSpec_Check(v)) { ! fss = ((FSSpecObject *)v)->ob_itself; ! #else ! if (PyMac_GetFSSpec(v, &fss)) { ! #endif ! if ((err=FSpMakeFSRef(&fss, fsr)) == 0) return 1; PyMac_Error(err); *************** *** 809,813 **** --- 815,838 ---- FSRef_as_pathname_body = """ + #if TARGET_API_MAC_OSX + if (!PyArg_ParseTuple(_args, "")) + return NULL; _res = FSRef_FSRefMakePath(_self, _args); + #else + char strbuf[1024]; + OSErr err; + FSSpec fss; + + if (!PyArg_ParseTuple(_args, "")) + return NULL; + if ( !PyMac_GetFSSpec((PyObject *)_self, &fss)) + return NULL; + err = PyMac_GetFullPathname(&fss, strbuf, sizeof(strbuf)); + if ( err ) { + PyMac_Error(err); + return NULL; + } + _res = PyString_FromString(strbuf); + #endif return _res; """ From jackjansen@users.sourceforge.net Sun Jan 26 20:33:48 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 12:33:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bgenlocations.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv31328 Modified Files: bgenlocations.py Log Message: Path to default location for Python output has changed. Index: bgenlocations.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bgenlocations.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** bgenlocations.py 30 Dec 2002 22:04:20 -0000 1.1 --- bgenlocations.py 26 Jan 2003 20:33:46 -0000 1.2 *************** *** 27,31 **** # if sys.platform == 'mac': ! _MWERKSDIR="Macintosh HD:Applications (Mac OS 9):Metrowerks CodeWarrior 7.0:Metrowerks CodeWarrior" else: _MWERKSDIR="/Volumes/Moes/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/" --- 27,31 ---- # if sys.platform == 'mac': ! _MWERKSDIR="Moes:Applications (Mac OS 9):Metrowerks CodeWarrior 7.0:Metrowerks CodeWarrior" else: _MWERKSDIR="/Volumes/Moes/Applications (Mac OS 9)/Metrowerks CodeWarrior 7.0/Metrowerks CodeWarrior/" *************** *** 38,44 **** # if sys.platform == 'mac': ! TOOLBOXDIR=os.path.join(sys.prefix, "Mac", "Lib", "Carbon") else: ! TOOLBOXDIR="/Users/jack/src/python/Mac/Lib/Carbon" # Creator for C files: --- 38,44 ---- # if sys.platform == 'mac': ! TOOLBOXDIR=os.path.join(sys.prefix, "Lib", "plat-mac", "Carbon") else: ! TOOLBOXDIR="/Users/jack/src/python/Lib/plat-mac/Carbon" # Creator for C files: From jackjansen@users.sourceforge.net Sun Jan 26 20:35:39 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 12:35:39 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo/example0 checktext.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/example0 In directory sc8-pr-cvs1:/tmp/cvs-serv31970 Modified Files: checktext.py Log Message: Use new file dialogs. Index: checktext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/example0/checktext.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** checktext.py 18 Jul 1996 16:07:05 -0000 1.1 --- checktext.py 26 Jan 2003 20:35:37 -0000 1.2 *************** *** 1,5 **** """checktext - Check that a text file has macintosh-style newlines""" - import macfs import sys import EasyDialogs --- 1,4 ---- *************** *** 7,14 **** def main(): ! fsspec, ok = macfs.PromptGetFile('File to check end-of-lines in:', 'TEXT') ! if not ok: sys.exit(0) - pathname = fsspec.as_pathname() fp = open(pathname, 'rb') try: --- 6,12 ---- def main(): ! pathname = EasyDialogs.AskFileForOpen(message='File to check end-of-lines in:') ! if not pathname: sys.exit(0) fp = open(pathname, 'rb') try: From jackjansen@users.sourceforge.net Sun Jan 26 20:35:50 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 12:35:50 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts BuildApplet.py,1.17,1.18 gensuitemodule.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv32027 Modified Files: BuildApplet.py gensuitemodule.py Log Message: Use new file dialogs. Index: BuildApplet.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplet.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** BuildApplet.py 22 Jan 2003 14:03:11 -0000 1.17 --- BuildApplet.py 26 Jan 2003 20:35:47 -0000 1.18 *************** *** 12,16 **** import os - import macfs import MacOS import EasyDialogs --- 12,15 ---- *************** *** 37,41 **** if not sys.argv[1:]: filename = EasyDialogs.AskFileForOpen(message='Select Python source or applet:', ! fileTypes=('TEXT', 'APPL')) if not filename: return --- 36,40 ---- if not sys.argv[1:]: filename = EasyDialogs.AskFileForOpen(message='Select Python source or applet:', ! typeList=('TEXT', 'APPL')) if not filename: return *************** *** 87,91 **** # Loop over all files to be processed for filename in args: ! cr, tp = MacOS.GetCreatorAndType(macfs.FSRef(filename)) if tp == 'APPL': buildtools.update(template, filename, dstfilename) --- 86,90 ---- # Loop over all files to be processed for filename in args: ! cr, tp = MacOS.GetCreatorAndType(filename) if tp == 'APPL': buildtools.update(template, filename, dstfilename) Index: gensuitemodule.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/gensuitemodule.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** gensuitemodule.py 7 Aug 2002 15:52:44 -0000 1.27 --- gensuitemodule.py 26 Jan 2003 20:35:47 -0000 1.28 *************** *** 8,11 **** --- 8,12 ---- import MacOS + import EasyDialogs import os import string *************** *** 13,17 **** import types import StringIO - import macfs import keyword import macresource --- 14,17 ---- *************** *** 20,24 **** from Carbon.Res import * ! DEFAULT_PACKAGEFOLDER=os.path.join(sys.prefix, 'Mac', 'Lib', 'lib-scriptpackages') def main(): --- 20,24 ---- from Carbon.Res import * ! DEFAULT_PACKAGEFOLDER=os.path.join(sys.prefix, 'Lib', 'plat-mac', 'lib-scriptpackages') def main(): *************** *** 27,34 **** processfile(filename) else: ! fss, ok = macfs.PromptGetFile('Select file with aeut/aete resource:') ! if not ok: sys.exit(0) ! processfile(fss.as_pathname()) def processfile(fullname): --- 27,34 ---- processfile(filename) else: ! filename = EasyDialogs.AskFileForOpen(message='Select file with aeut/aete resource:') ! if not filename: sys.exit(0) ! processfile(filename) def processfile(fullname): *************** *** 232,237 **** [version, language, script, suites] = aete major, minor = divmod(version, 256) ! fss = macfs.FSSpec(fname) ! creatorsignature, dummy = fss.GetCreatorType() packagename = identify(os.path.splitext(os.path.basename(fname))[0]) if language: --- 232,236 ---- [version, language, script, suites] = aete major, minor = divmod(version, 256) ! creatorsignature, dummy = MacOS.GetCreatorAndType(fname) packagename = identify(os.path.splitext(os.path.basename(fname))[0]) if language: *************** *** 241,253 **** if len(packagename) > 27: packagename = packagename[:27] ! macfs.SetFolder(DEFAULT_PACKAGEFOLDER) ! fss, ok = macfs.GetDirectory('Create and select package folder for %s'%packagename) ! if not ok: return - pathname = fss.as_pathname() packagename = os.path.split(os.path.normpath(pathname))[1] ! fss, ok = macfs.GetDirectory('Package folder for base suite (usually StdSuites)') ! if ok: ! dirname, basepkgname = os.path.split(os.path.normpath(fss.as_pathname())) if not dirname in sys.path: sys.path.insert(0, dirname) --- 240,252 ---- if len(packagename) > 27: packagename = packagename[:27] ! pathname = EasyDialogs.AskFolder(message='Create and select package folder for %s'%packagename, ! defaultLocation=DEFAULT_PACKAGEFOLDER) ! if not pathname: return packagename = os.path.split(os.path.normpath(pathname))[1] ! basepkgname = EasyDialogs.AskFolder(message='Package folder for base suite (usually StdSuites)', ! defaultLocation=DEFAULT_PACKAGEFOLDER) ! if basepkgname: ! dirname, basepkgname = os.path.split(os.path.normpath(basepkgname)) if not dirname in sys.path: sys.path.insert(0, dirname) *************** *** 255,277 **** else: basepackage = None - macfs.SetFolder(pathname) suitelist = [] allprecompinfo = [] allsuites = [] for suite in suites: ! code, suite, fss, modname, precompinfo = precompilesuite(suite, basepackage) if not code: continue allprecompinfo = allprecompinfo + precompinfo ! suiteinfo = suite, fss, modname suitelist.append((code, modname)) allsuites.append(suiteinfo) for suiteinfo in allsuites: compilesuite(suiteinfo, major, minor, language, script, fname, basepackage, allprecompinfo) ! fss, ok = macfs.StandardPutFile('Package module', '__init__.py') ! if not ok: return ! fp = open(fss.as_pathname(), 'w') ! fss.SetCreatorType('Pyth', 'TEXT') fp.write('"""\n') fp.write("Package generated from %s\n"%fname) --- 254,276 ---- else: basepackage = None suitelist = [] allprecompinfo = [] allsuites = [] for suite in suites: ! code, suite, pathname, modname, precompinfo = precompilesuite(suite, basepackage) if not code: continue allprecompinfo = allprecompinfo + precompinfo ! suiteinfo = suite, pathname, modname suitelist.append((code, modname)) allsuites.append(suiteinfo) for suiteinfo in allsuites: compilesuite(suiteinfo, major, minor, language, script, fname, basepackage, allprecompinfo) ! initfilename = EasyDialogs.AskFileForSave(message='Package module', ! savedFileName='__init__.py') ! if not initfilename: return ! fp = open(initfilename, 'w') ! MacOS.SetCreatorAndType(initfilename, 'Pyth', 'TEXT') fp.write('"""\n') fp.write("Package generated from %s\n"%fname) *************** *** 340,348 **** if len(modname) > 28: modname = modname[:27] ! fss, ok = macfs.StandardPutFile('Python output file', modname+'.py') ! if not ok: return None, None, None, None, None - pathname = fss.as_pathname() modname = os.path.splitext(os.path.split(pathname)[1])[0] --- 339,347 ---- if len(modname) > 28: modname = modname[:27] ! pathname = EasyDialogs.AskFileForSave(message='Python output file', ! savedFileName=modname+'.py') ! if not pathname: return None, None, None, None, None modname = os.path.splitext(os.path.split(pathname)[1])[0] *************** *** 376,388 **** precompinfo = objc.getprecompinfo(modname) ! return code, suite, fss, modname, precompinfo ! def compilesuite((suite, fss, modname), major, minor, language, script, fname, basepackage, precompinfo): """Generate code for a single suite""" [name, desc, code, level, version, events, classes, comps, enums] = suite ! pathname = fss.as_pathname() ! fp = open(fss.as_pathname(), 'w') ! fss.SetCreatorType('Pyth', 'TEXT') fp.write('"""Suite %s: %s\n' % (ascii(name), ascii(desc))) --- 375,386 ---- precompinfo = objc.getprecompinfo(modname) ! return code, suite, pathname, modname, precompinfo ! def compilesuite((suite, pathname, modname), major, minor, language, script, fname, basepackage, precompinfo): """Generate code for a single suite""" [name, desc, code, level, version, events, classes, comps, enums] = suite ! fp = open(pathname, 'w') ! MacOS.SetCreatorAndType(pathname, 'Pyth', 'TEXT') fp.write('"""Suite %s: %s\n' % (ascii(name), ascii(desc))) *************** *** 677,683 **** def askdefinitionmodule(self, type, code): ! fss, ok = macfs.PromptGetFile('Where is %s %s declared?'%(type, code)) ! if not ok: return ! path, file = os.path.split(fss.as_pathname()) modname = os.path.splitext(file)[0] if not path in sys.path: --- 675,681 ---- def askdefinitionmodule(self, type, code): ! path = EasyDialogs.AskFileForSave(message='Where is %s %s declared?'%(type, code)) ! if not path: return ! path, file = os.path.split(path) modname = os.path.splitext(file)[0] if not path in sys.path: From jackjansen@users.sourceforge.net Sun Jan 26 21:35:48 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 13:35:48 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo/imgbrowse imgbrowse.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/imgbrowse In directory sc8-pr-cvs1:/tmp/cvs-serv23573 Modified Files: imgbrowse.py Log Message: Use new file dialogs. Index: imgbrowse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/imgbrowse/imgbrowse.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** imgbrowse.py 30 Nov 2002 00:01:17 -0000 1.6 --- imgbrowse.py 26 Jan 2003 21:35:45 -0000 1.7 *************** *** 1,3 **** ! GetPortBounds()"""imgbrowse - Display pictures using img""" import FrameWork --- 1,3 ---- ! """imgbrowse - Display pictures using img""" import FrameWork *************** *** 12,16 **** import img import imgformat - import macfs import struct import mac_image --- 12,15 ---- *************** *** 48,56 **** def opendoc(self, *args): ! fss, ok = macfs.StandardGetFile() # Any file type ! if not ok: return bar = EasyDialogs.ProgressBar('Reading and converting...') - pathname = fss.as_pathname() try: rdr = img.reader(imgformat.macrgb16, pathname) --- 47,54 ---- def opendoc(self, *args): ! pathname = EasyDialogs.AskFileForOpen() # Any file type ! if not pathname: return bar = EasyDialogs.ProgressBar('Reading and converting...') try: rdr = img.reader(imgformat.macrgb16, pathname) From jackjansen@users.sourceforge.net Sun Jan 26 21:35:57 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 13:35:57 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo/mlte mlted.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/mlte In directory sc8-pr-cvs1:/tmp/cvs-serv23650 Modified Files: mlted.py Log Message: Use new file dialogs. Index: mlted.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/mlte/mlted.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** mlted.py 30 Nov 2002 00:01:17 -0000 1.5 --- mlted.py 26 Jan 2003 21:35:55 -0000 1.6 *************** *** 12,16 **** from Carbon import Scrap import os - import macfs from Carbon import MacTextEditor from Carbon import Mlte --- 12,15 ---- *************** *** 93,99 **** def menu_save_as(self): ! fss, ok = macfs.StandardPutFile('Save as:') ! if not ok: return ! self.path = fss.as_pathname() self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) --- 92,98 ---- def menu_save_as(self): ! path = EasyDialogs.AskFileForSave(message='Save as:') ! if not path: return ! self.path = path self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) *************** *** 269,276 **** def _open(self, askfile): if askfile: ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: return - path = fss.as_pathname() name = os.path.split(path)[-1] try: --- 268,274 ---- def _open(self, askfile): if askfile: ! path = EasyDialogs.AskFileForOpen(typeList=('TEXT',)) ! if not path: return name = os.path.split(path)[-1] try: From jackjansen@users.sourceforge.net Sun Jan 26 21:36:09 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 13:36:09 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo/quicktime VerySimplePlayer.py,1.6,1.7 MovieInWindow.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/quicktime In directory sc8-pr-cvs1:/tmp/cvs-serv23854 Modified Files: VerySimplePlayer.py MovieInWindow.py Log Message: Use new file dialogs. Index: VerySimplePlayer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/quicktime/VerySimplePlayer.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** VerySimplePlayer.py 30 Nov 2002 00:01:20 -0000 1.6 --- VerySimplePlayer.py 26 Jan 2003 21:36:06 -0000 1.7 *************** *** 12,16 **** from Carbon import Win from Carbon import Windows ! import macfs import sys --- 12,17 ---- from Carbon import Win from Carbon import Windows ! from Carbon import File ! import EasyDialogs import sys *************** *** 24,29 **** # Get the movie file ! fss, ok = macfs.StandardGetFile(QuickTime.MovieFileType) ! if not ok: sys.exit(0) --- 25,30 ---- # Get the movie file ! fss = EasyDialogs.AskFileForOpen(wanted=File.FSSpec) # Was: QuickTime.MovieFileType ! if not fss: sys.exit(0) Index: MovieInWindow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/quicktime/MovieInWindow.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** MovieInWindow.py 30 Nov 2002 00:01:18 -0000 1.6 --- MovieInWindow.py 26 Jan 2003 21:36:06 -0000 1.7 *************** *** 12,16 **** from Carbon import Win from Carbon import Windows ! import macfs import sys --- 12,17 ---- from Carbon import Win from Carbon import Windows ! from Carbon import File ! import EasyDialogs import sys *************** *** 22,27 **** # Get the movie file ! fss, ok = macfs.StandardGetFile() # Was: QuickTime.MovieFileType ! if not ok: sys.exit(0) --- 23,28 ---- # Get the movie file ! fss = EasyDialogs.AskFileForOpen(wanted=File.FSSpec) # Was: QuickTime.MovieFileType ! if not fss: sys.exit(0) From jackjansen@users.sourceforge.net Sun Jan 26 21:36:17 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 13:36:17 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo/textedit ped.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/textedit In directory sc8-pr-cvs1:/tmp/cvs-serv23956 Modified Files: ped.py Log Message: Use new file dialogs. Index: ped.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/textedit/ped.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** ped.py 30 Nov 2002 00:01:21 -0000 1.10 --- ped.py 26 Jan 2003 21:36:15 -0000 1.11 *************** *** 132,138 **** def menu_save_as(self): ! fss, ok = macfs.StandardPutFile('Save as:') ! if not ok: return ! self.path = fss.as_pathname() self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) --- 132,138 ---- def menu_save_as(self): ! path = EasyDialogs.AskFileForSave(message='Save as:') ! if not path: return ! self.path = path self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) *************** *** 266,273 **** def _open(self, askfile): if askfile: ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: return - path = fss.as_pathname() name = os.path.split(path)[-1] try: --- 266,272 ---- def _open(self, askfile): if askfile: ! path = EasyDialogs.AskFileForOpen(typeList=('TEXT',)) ! if not path: return name = os.path.split(path)[-1] try: From jackjansen@users.sourceforge.net Sun Jan 26 21:36:29 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 13:36:29 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo/waste wed.py,1.9,1.10 htmled.py,1.12,1.13 swed.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/waste In directory sc8-pr-cvs1:/tmp/cvs-serv24069 Modified Files: wed.py htmled.py swed.py Log Message: Use new file dialogs. Index: wed.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/waste/wed.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** wed.py 30 Nov 2002 00:01:22 -0000 1.9 --- wed.py 26 Jan 2003 21:36:26 -0000 1.10 *************** *** 13,17 **** from Carbon import Scrap import os ! import macfs UNDOLABELS = [ # Indexed by WEGetUndoInfo() value --- 13,17 ---- from Carbon import Scrap import os ! import EasyDialogs UNDOLABELS = [ # Indexed by WEGetUndoInfo() value *************** *** 182,188 **** def menu_save_as(self): ! fss, ok = macfs.StandardPutFile('Save as:') ! if not ok: return ! self.path = fss.as_pathname() self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) --- 182,188 ---- def menu_save_as(self): ! path = EasyDialogs.AskFileForSave(message='Save as:') ! if not path: return ! self.path = path self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) *************** *** 330,337 **** def _open(self, askfile): if askfile: ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: return - path = fss.as_pathname() name = os.path.split(path)[-1] try: --- 330,336 ---- def _open(self, askfile): if askfile: ! path = EasyDialogs.AskFileForOpen(typeList=('TEXT',)) ! if not path: return name = os.path.split(path)[-1] try: Index: htmled.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/waste/htmled.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** htmled.py 30 Nov 2002 00:01:21 -0000 1.12 --- htmled.py 26 Jan 2003 21:36:26 -0000 1.13 *************** *** 14,19 **** from Carbon import Scrap import os import macfs - import MACFS import string import htmllib --- 14,19 ---- from Carbon import Scrap import os + import EasyDialogs import macfs import string import htmllib *************** *** 244,248 **** rf = Res.FSpOpenResFile(self.path, 3) except Res.Error: ! Res.FSpCreateResFile(self.path, '????', 'TEXT', MACFS.smAllScripts) rf = Res.FSpOpenResFile(self.path, 3) styles = Res.Resource('') --- 244,248 ---- rf = Res.FSpOpenResFile(self.path, 3) except Res.Error: ! Res.FSpCreateResFile(self.path, '????', 'TEXT', macfs.smAllScripts) rf = Res.FSpOpenResFile(self.path, 3) styles = Res.Resource('') *************** *** 257,263 **** def menu_save_as(self): ! fss, ok = macfs.StandardPutFile('Save as:') ! if not ok: return ! self.path = fss.as_pathname() self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) --- 257,263 ---- def menu_save_as(self): ! path = EasyDialogs.AskFileForSave(message='Save as:') ! if not path: return ! self.path = path self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) *************** *** 662,669 **** def _open(self, askfile): if askfile: ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: return - path = fss.as_pathname() name = os.path.split(path)[-1] try: --- 662,668 ---- def _open(self, askfile): if askfile: ! path = EasyDialogs.AskFileForOpen(typeList=('TEXT',)) ! if not path: return name = os.path.split(path)[-1] try: *************** *** 684,691 **** def insertfile(self, *args): if self.active: ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: return - path = fss.as_pathname() try: fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line --- 683,689 ---- def insertfile(self, *args): if self.active: ! path = EasyDialogs.AskFileForOpen(typeList=('TEXT',)) ! if not path: return try: fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line *************** *** 699,706 **** def inserthtml(self, *args): if self.active: ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: return - path = fss.as_pathname() try: fp = open(path, 'r') --- 697,703 ---- def inserthtml(self, *args): if self.active: ! path = EasyDialogs.AskFileForOpen(typeList=('TEXT',)) ! if not path: return try: fp = open(path, 'r') Index: swed.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/waste/swed.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** swed.py 30 Nov 2002 00:01:22 -0000 1.13 --- swed.py 26 Jan 2003 21:36:26 -0000 1.14 *************** *** 15,19 **** import os import macfs - import MACFS UNDOLABELS = [ # Indexed by WEGetUndoInfo() value --- 15,18 ---- *************** *** 214,218 **** rf = Res.FSpOpenResFile(self.path, 3) except Res.Error: ! Res.FSpCreateResFile(self.path, '????', 'TEXT', MACFS.smAllScripts) rf = Res.FSpOpenResFile(self.path, 3) styles = Res.Resource('') --- 213,217 ---- rf = Res.FSpOpenResFile(self.path, 3) except Res.Error: ! Res.FSpCreateResFile(self.path, '????', 'TEXT', macfs.smAllScripts) rf = Res.FSpOpenResFile(self.path, 3) styles = Res.Resource('') *************** *** 227,233 **** def menu_save_as(self): ! fss, ok = macfs.StandardPutFile('Save as:') ! if not ok: return ! self.path = fss.as_pathname() self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) --- 226,232 ---- def menu_save_as(self): ! path = EasyDialogs.AskFileForSave(message='Save as:') ! if not path: return ! self.path = path self.name = os.path.split(self.path)[-1] self.wid.SetWTitle(self.name) *************** *** 522,529 **** def _open(self, askfile): if askfile: ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: return - path = fss.as_pathname() name = os.path.split(path)[-1] try: --- 521,527 ---- def _open(self, askfile): if askfile: ! path = EasyDialogs.AskFileForOpen(typeList=('TEXT',)) ! if not path: return name = os.path.split(path)[-1] try: From jackjansen@users.sourceforge.net Sun Jan 26 21:36:36 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 13:36:36 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/macfreeze macgen_bin.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/macfreeze In directory sc8-pr-cvs1:/tmp/cvs-serv24167 Modified Files: macgen_bin.py Log Message: Use new file dialogs. Index: macgen_bin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/macfreeze/macgen_bin.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** macgen_bin.py 13 Dec 2001 17:11:21 -0000 1.10 --- macgen_bin.py 26 Jan 2003 21:36:34 -0000 1.11 *************** *** 206,213 **** corepath = os.path.join(extpath, corename) if not os.path.exists(corepath): ! fss, ok = macfs.PromptGetFile("Please locate PythonCore:", "shlb") ! if not ok: raise KeyboardInterrupt, "cancelled" - corepath = fss.as_pathname() return resolvealiasfile(corepath) --- 206,213 ---- corepath = os.path.join(extpath, corename) if not os.path.exists(corepath): ! corepath = EasyDialogs.AskFileForOpen(message="Please locate PythonCore:", ! typeList=("shlb",)) ! if not corepath: raise KeyboardInterrupt, "cancelled" return resolvealiasfile(corepath) From jackjansen@users.sourceforge.net Sun Jan 26 21:40:05 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 13:40:05 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts fullbuild.py,1.89,1.90 findgremlins.py,1.1,1.2 fixfiletypes.py,1.6,1.7 EditPythonPrefs.py,1.27,1.28 makeclean.py,1.1,1.2 unshar.py,1.2,1.3 zappycfiles.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv26108 Modified Files: fullbuild.py findgremlins.py fixfiletypes.py EditPythonPrefs.py makeclean.py unshar.py zappycfiles.py Log Message: Use new file dialogs. Index: fullbuild.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fullbuild.py,v retrieving revision 1.89 retrieving revision 1.90 diff -C2 -d -r1.89 -r1.90 *** fullbuild.py 8 Jan 2003 16:27:44 -0000 1.89 --- fullbuild.py 26 Jan 2003 21:40:00 -0000 1.90 *************** *** 411,418 **** def main(): macresource.need('DLOG', DIALOG_ID, 'fullbuild.rsrc') ! dir, ok = macfs.GetDirectory('Python source folder:') ! if not ok: sys.exit(0) - dir = dir.as_pathname() # Set genpluginprojects to use this folder (slight hack) genpluginprojects.PYTHONDIR = dir --- 411,417 ---- def main(): macresource.need('DLOG', DIALOG_ID, 'fullbuild.rsrc') ! dir = EasyDialogs.AskFolder(message='Python source folder:') ! if not dir: sys.exit(0) # Set genpluginprojects to use this folder (slight hack) genpluginprojects.PYTHONDIR = dir Index: findgremlins.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/findgremlins.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** findgremlins.py 3 Feb 1999 12:07:14 -0000 1.1 --- findgremlins.py 26 Jan 2003 21:40:00 -0000 1.2 *************** *** 5,8 **** --- 5,9 ---- By Just, with a little glue by Jack""" + import EasyDialogs import macfs import re *************** *** 44,50 **** def main(): ! fss, ok = macfs.GetDirectory() ! if ok: ! walk(fss.as_pathname()) if __name__ == '__main__': --- 45,51 ---- def main(): ! pathname = EasyDialogs.AskFolder() ! if pathname: ! walk(pathname) if __name__ == '__main__': Index: fixfiletypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fixfiletypes.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** fixfiletypes.py 15 Sep 1996 22:13:58 -0000 1.6 --- fixfiletypes.py 26 Jan 2003 21:40:00 -0000 1.7 *************** *** 10,13 **** --- 10,14 ---- import os import macfs + import EasyDialogs import sys import macostools *************** *** 46,53 **** def run(change): ! fss, ok = macfs.GetDirectory('Folder to search:') ! if not ok: sys.exit(0) ! walktree(fss.as_pathname(), change) if __name__ == '__main__': --- 47,54 ---- def run(change): ! pathname = EasyDialogs.AskFolder(message='Folder to search:') ! if not pathname: sys.exit(0) ! walktree(pathname, change) if __name__ == '__main__': Index: EditPythonPrefs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/EditPythonPrefs.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** EditPythonPrefs.py 1 Sep 2001 22:36:03 -0000 1.27 --- EditPythonPrefs.py 26 Jan 2003 21:40:00 -0000 1.28 *************** *** 160,164 **** ## return [], pythondir if n == DIR_ITEM: ! fss, ok = macfs.GetDirectory('Select python home folder:') if ok: options['dir'] = fss --- 160,165 ---- ## return [], pythondir if n == DIR_ITEM: ! fss = EasyDialogs.AskFolder(message='Select python home folder:', ! wanted=macfs.FSSpec) if ok: options['dir'] = fss Index: makeclean.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/makeclean.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** makeclean.py 7 Feb 1999 16:36:22 -0000 1.1 --- makeclean.py 26 Jan 2003 21:40:00 -0000 1.2 *************** *** 13,16 **** --- 13,17 ---- import macfs + import EasyDialogs import os import sys *************** *** 54,59 **** ! fss, ok = macfs.GetDirectory("Please locate the Python home directory") ! if ok: ! walk(fss.as_pathname()) sys.exit(1) # so we see the results --- 55,60 ---- ! pathname = EasyDialogs.AskFolder(message="Please locate the Python home directory") ! if pathname: ! walk(pathname) sys.exit(1) # so we see the results Index: unshar.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/unshar.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** unshar.py 23 Dec 1996 16:54:51 -0000 1.2 --- unshar.py 26 Jan 2003 21:40:00 -0000 1.3 *************** *** 7,10 **** --- 7,11 ---- import string + import EasyDialogs def unshar(fp, verbose=0, overwrite=0): *************** *** 83,95 **** else: import macfs ! fss, ok = macfs.StandardGetFile('TEXT') ! if not ok: sys.exit(0) - fname = fss.as_pathname() fp = open(fname, 'r') ! fss, ok = macfs.GetDirectory('Folder to save files in:') ! if not ok: sys.exit(0) ! os.chdir(fss.as_pathname()) unshar(fp) --- 84,95 ---- else: import macfs ! fname = EasyDialogs.AskFileForOpen() ! if not fname: sys.exit(0) fp = open(fname, 'r') ! dirname = EasyDialogs.AskFolder(message='Folder to save files in:') ! if not dirname: sys.exit(0) ! os.chdir(dirname) unshar(fp) Index: zappycfiles.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/zappycfiles.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** zappycfiles.py 6 Sep 2002 20:23:09 -0000 1.3 --- zappycfiles.py 26 Jan 2003 21:40:00 -0000 1.4 *************** *** 3,6 **** --- 3,7 ---- import os import sys + import EasyDialogs # set doit true to actually delete files *************** *** 12,19 **** if os.name == 'mac': import macfs ! fss, ok = macfs.GetDirectory('Directory to zap pyc files in') ! if not ok: sys.exit(0) - dir = fss.as_pathname() zappyc(dir) else: --- 13,19 ---- if os.name == 'mac': import macfs ! dir = EasyDialogs.AskFolder(message='Directory to zap pyc files in') ! if not dir: sys.exit(0) zappyc(dir) else: From jackjansen@users.sourceforge.net Sun Jan 26 22:15:13 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 14:15:13 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts EditPythonPrefs.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv22378 Modified Files: EditPythonPrefs.py Log Message: Fix an omission in the previous checkin. Index: EditPythonPrefs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/EditPythonPrefs.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** EditPythonPrefs.py 26 Jan 2003 21:40:00 -0000 1.28 --- EditPythonPrefs.py 26 Jan 2003 22:15:10 -0000 1.29 *************** *** 162,166 **** fss = EasyDialogs.AskFolder(message='Select python home folder:', wanted=macfs.FSSpec) ! if ok: options['dir'] = fss elif n == HELP_ITEM and Help: --- 162,166 ---- fss = EasyDialogs.AskFolder(message='Select python home folder:', wanted=macfs.FSSpec) ! if fss: options['dir'] = fss elif n == HELP_ITEM and Help: From jackjansen@users.sourceforge.net Sun Jan 26 22:15:51 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 26 Jan 2003 14:15:51 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE ProfileBrowser.py,1.3,1.4 PyConsole.py,1.13,1.14 PyDocSearch.py,1.9,1.10 PyEdit.py,1.33,1.34 PythonIDEMain.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv23153 Modified Files: ProfileBrowser.py PyConsole.py PyDocSearch.py PyEdit.py PythonIDEMain.py Log Message: Use new file dialogs. Index: ProfileBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/ProfileBrowser.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ProfileBrowser.py 31 Dec 2001 08:58:44 -0000 1.3 --- ProfileBrowser.py 26 Jan 2003 22:15:48 -0000 1.4 *************** *** 1,4 **** --- 1,5 ---- import W from Carbon import Evt + import EasyDialogs import sys *************** *** 84,90 **** else: import macfs ! fss, ok = macfs.PromptGetFile('Profiler data') ! if not ok: sys.exit(0) ! stats = pstats.Stats(fss.as_pathname()) browser = ProfileBrowser(stats) --- 85,91 ---- else: import macfs ! filename = EasyDialogs.AskFileForOpen(message='Profiler data') ! if not filename: sys.exit(0) ! stats = pstats.Stats(filename) browser = ProfileBrowser(stats) Index: PyConsole.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyConsole.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** PyConsole.py 20 Jan 2003 09:02:23 -0000 1.13 --- PyConsole.py 26 Jan 2003 22:15:48 -0000 1.14 *************** *** 11,14 **** --- 11,15 ---- import MacPrefs from Carbon import Qd + import EasyDialogs import PyInteractive *************** *** 86,93 **** def domenu_save_as(self, *args): import macfs ! fss, ok = macfs.StandardPutFile('Save console text as:', 'console.txt') ! if not ok: return ! f = open(fss.as_pathname(), 'wb') f.write(self.get()) f.close() --- 87,95 ---- def domenu_save_as(self, *args): import macfs ! filename = EasyDialogs.AskFileForSave(message='Save console text as:', ! savedFileName='console.txt') ! if not filename: return ! f = open(filename, 'wb') f.write(self.get()) f.close() *************** *** 242,249 **** title = self._parentwindow.gettitle() import macfs ! fss, ok = macfs.StandardPutFile('Save %s text as:' % title, title + '.txt') ! if not ok: return ! f = open(fss.as_pathname(), 'wb') f.write(self.get()) f.close() --- 244,252 ---- title = self._parentwindow.gettitle() import macfs ! filename = EasyDialogs.AskFileForSave(message='Save %s text as:' % title, ! savedFileName=title + '.txt') ! if not filename: return ! f = open(filename, 'wb') f.write(self.get()) f.close() Index: PyDocSearch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyDocSearch.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PyDocSearch.py 21 Jan 2002 23:00:52 -0000 1.9 --- PyDocSearch.py 26 Jan 2003 22:15:48 -0000 1.10 *************** *** 7,10 **** --- 7,11 ---- import string import webbrowser + import EasyDialogs *************** *** 224,230 **** def setdocpath(self): ! fss, ok = macfs.GetDirectory() ! if ok: ! docpath = fss.as_pathname() if not verifydocpath(docpath): W.Message("This does not seem to be a Python documentation folder...") --- 225,230 ---- def setdocpath(self): ! docpath = EasyDialogs.AskFolder() ! if docpath: if not verifydocpath(docpath): W.Message("This does not seem to be a Python documentation folder...") Index: PyEdit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyEdit.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** PyEdit.py 24 Oct 2002 20:03:29 -0000 1.33 --- PyEdit.py 26 Jan 2003 22:15:48 -0000 1.34 *************** *** 8,11 **** --- 8,12 ---- import MACFS import MacOS + import EasyDialogs from Carbon import Win from Carbon import Res *************** *** 68,72 **** if '\n' in text: - import EasyDialogs if string.find(text, '\r\n') >= 0: self._eoln = '\r\n' --- 69,72 ---- *************** *** 366,370 **** def close(self): if self.editgroup.editor.changed: - import EasyDialogs Qd.InitCursor() save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?' % self.title, --- 366,369 ---- *************** *** 407,415 **** def domenu_save_as(self, *args): ! fss, ok = macfs.StandardPutFile('Save as:', self.title) ! if not ok: return 1 self.showbreakpoints(0) ! self.path = fss.as_pathname() self.setinfotext() self.title = os.path.split(self.path)[-1] --- 406,414 ---- def domenu_save_as(self, *args): ! path = EasyDialogs.AskFileForSave(message='Save as:', savedFileName=self.title) ! if not path: return 1 self.showbreakpoints(0) ! self.path = path self.setinfotext() self.title = os.path.split(self.path)[-1] *************** *** 435,443 **** else: destname = self.title + ".applet" ! fss, ok = macfs.StandardPutFile('Save as Applet:', destname) ! if not ok: return 1 W.SetCursor("watch") - destname = fss.as_pathname() if self.path: filename = self.path --- 434,442 ---- else: destname = self.title + ".applet" ! destname = EasyDialogs.AskFileForSave(message='Save as Applet:', ! savedFileName=destname) ! if not destname: return 1 W.SetCursor("watch") if self.path: filename = self.path *************** *** 509,513 **** if self.run_with_interpreter: if self.editgroup.editor.changed: - import EasyDialogs Qd.InitCursor() save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1) --- 508,511 ---- *************** *** 522,526 **** elif self.run_with_cl_interpreter: if self.editgroup.editor.changed: - import EasyDialogs Qd.InitCursor() save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1) --- 520,523 ---- *************** *** 1026,1030 **** if counter: self.hide() - import EasyDialogs from Carbon import Res editor.textchanged() --- 1023,1026 ---- Index: PythonIDEMain.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDEMain.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** PythonIDEMain.py 22 Nov 2002 12:48:47 -0000 1.24 --- PythonIDEMain.py 26 Jan 2003 22:15:48 -0000 1.25 *************** *** 10,13 **** --- 10,14 ---- import macfs import MacOS + import EasyDialogs if MacOS.runtimemodel == 'macho': *************** *** 190,195 **** def do_setscriptsfolder(self, *args): ! fss, ok = macfs.GetDirectory("Select Scripts Folder") ! if ok: prefs = self.getprefs() alis = fss.NewAlias() --- 191,197 ---- def do_setscriptsfolder(self, *args): ! fss = EasyDialogs.AskFolder(message="Select Scripts Folder", ! wanted=macfs.FSSpec) ! if fss: prefs = self.getprefs() alis = fss.NewAlias() *************** *** 205,211 **** def domenu_open(self, *args): ! fss, ok = macfs.StandardGetFile("TEXT") ! if ok: ! self.openscript(fss.as_pathname()) def domenu_new(self, *args): --- 207,213 ---- def domenu_open(self, *args): ! filename = EasyDialogs.AskFileForOpen(typeList=("TEXT",)) ! if filename: ! self.openscript(filename) def domenu_new(self, *args): *************** *** 345,349 **** # if there is no selection, but the can_ methods only seem # to work for Windows. Or not for the Help menu, maybe? - import EasyDialogs text = EasyDialogs.AskString("Search documentation for", ok="Search") return text --- 347,350 ---- From rhettinger@users.sourceforge.net Mon Jan 27 00:13:50 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 26 Jan 2003 16:13:50 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools - New directory Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv10254/itertools Log Message: Directory /cvsroot/python/python/nondist/sandbox/itertools added to the repository From rhettinger@users.sourceforge.net Mon Jan 27 00:16:53 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 26 Jan 2003 16:16:53 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,NONE,1.1 libitertools.tex,NONE,1.1 setup.py,NONE,1.1 test_itertools.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv10778/itertools Added Files: itertools.c libitertools.tex setup.py test_itertools.py Log Message: Open a sandbox directory for itertools which provide SML/Haskell style tools creating iterators and looping. --- NEW FILE: itertools.c --- #include "Python.h" /* times object ************************************************************/ typedef struct { PyObject_HEAD long cnt; } timesobject; PyTypeObject times_type; static PyObject * times_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { timesobject *lz; long cnt; if (!PyArg_ParseTuple(args, "l:times", &cnt)) return NULL; /* create timesobject structure */ lz = (timesobject *)PyObject_New(timesobject, ×_type); if (lz == NULL) return NULL; lz->cnt = cnt; return (PyObject *)lz; } static PyObject * times_next(timesobject *lz) { if (lz->cnt > 0) { lz->cnt--; Py_INCREF(Py_None); return Py_None; } return NULL; } static PyObject * times_getiter(PyObject *lz) { Py_INCREF(lz); return lz; } PyDoc_STRVAR(times_doc, "times(n) --> times object\n\ \n\ Return an times object whose .next() method returns n consecutive\n\ instance of None."); PyTypeObject times_type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "itertools.times", /* tp_name */ sizeof(timesobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)PyObject_Del, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ times_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)times_getiter, /* tp_iter */ (iternextfunc)times_next, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ times_new, /* tp_new */ }; /* ifilter object ************************************************************/ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; long invert; } ifilterobject; PyTypeObject ifilter_type; static PyObject * ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *func, *seq, *invert=NULL; PyObject *it; ifilterobject *lz; long inv=0; if (!PyArg_UnpackTuple(args, "ifilter", 2, 3, &func, &seq, &invert)) return NULL; if (invert != NULL && PyObject_IsTrue(invert)) inv = 1; /* Get iterator. */ it = PyObject_GetIter(seq); if (it == NULL) return NULL; /* create ifilterobject structure */ lz = (ifilterobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(it); return NULL; } lz->func = func; lz->it = it; lz->invert = inv; return (PyObject *)lz; } static void ifilter_dealloc(ifilterobject *lz) { PyObject_GC_UnTrack(lz); //Py_XDECREF(lz->func); Py_XDECREF(lz->it); lz->ob_type->tp_free(lz); } static int ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg) { if (lz->it) return visit(lz->it, arg); return 0; } static PyObject * ifilter_next(ifilterobject *lz) { PyObject *item; long ok; for (;;) { item = PyIter_Next(lz->it); if (item == NULL) return NULL; if (lz->func == Py_None) { ok = PyObject_IsTrue(item); } else { PyObject *good; good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; } ok = PyObject_IsTrue(good); Py_DECREF(good); } if (ok ^ lz->invert) return item; Py_DECREF(item); } } static PyObject * ifilter_getiter(PyObject *lz) { Py_INCREF(lz); return lz; } PyDoc_STRVAR(ifilter_doc, "filter(function or None, sequence [, invert]) --> ifilter object\n\ \n\ Return those items of sequence for which function(item) is true. If\n\ invert is set to True, return items for which function(item) if False.\n\ If function is None, return the items that are true (unless invert is set)."); PyTypeObject ifilter_type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "itertools.ifilter", /* tp_name */ sizeof(ifilterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)ifilter_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ ifilter_doc, /* tp_doc */ (traverseproc)ifilter_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)ifilter_getiter, /* tp_iter */ (iternextfunc)ifilter_next, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ ifilter_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; /* count object ************************************************************/ typedef struct { PyObject_HEAD long cnt; } countobject; PyTypeObject count_type; static PyObject * count_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { countobject *lz; long cnt = 0; if (!PyArg_ParseTuple(args, "|l:count", &cnt)) return NULL; /* create countobject structure */ lz = (countobject *)PyObject_New(countobject, &count_type); if (lz == NULL) return NULL; lz->cnt = cnt; return (PyObject *)lz; } static PyObject * count_next(countobject *lz) { return PyInt_FromLong(lz->cnt++); } static PyObject * count_getiter(PyObject *lz) { Py_INCREF(lz); return lz; } PyDoc_STRVAR(count_doc, "count([firstval]) --> count object\n\ \n\ Return an count object whose .next() method returns consecutive\n\ integers starting from zero or, if specified, from firstval."); PyTypeObject count_type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "itertools.count", /* tp_name */ sizeof(countobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)PyObject_Del, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ count_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)count_getiter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ count_new, /* tp_new */ }; /* loopzip object ************************************************************/ #include "Python.h" typedef struct { PyObject_HEAD long tuplesize; PyObject *ittuple; /* tuple of iterators */ PyObject *result; } loopzipobject; PyTypeObject loopzip_type; static PyObject * loopzip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { loopzipobject *lz; int i; PyObject *ittuple; /* tuple of iterators */ int tuplesize = PySequence_Length(args); if (tuplesize < 1) { PyErr_SetString(PyExc_TypeError, "loopzip() requires at least one sequence"); return NULL; } /* args must be a tuple */ assert(PyTuple_Check(args)); /* obtain iterators */ ittuple = PyTuple_New(tuplesize); if(ittuple == NULL) return NULL; for (i = 0; i < tuplesize; ++i) { PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *it = PyObject_GetIter(item); if (it == NULL) { if (PyErr_ExceptionMatches(PyExc_TypeError)) PyErr_Format(PyExc_TypeError, "loopzip argument #%d must support iteration", i+1); Py_DECREF(ittuple); return NULL; } PyTuple_SET_ITEM(ittuple, i, it); } /* create loopzipobject structure */ lz = (loopzipobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(ittuple); return NULL; } lz->ittuple = ittuple; lz->tuplesize = tuplesize; /* create result holder */ lz->result = PyList_New(tuplesize); if (lz->result == NULL) { Py_DECREF(ittuple); Py_DECREF(lz); return NULL; } for (i=0 ; i < tuplesize ; i++) { Py_INCREF(Py_None); PyList_SET_ITEM(lz->result, i, Py_None); } return (PyObject *)lz; } static void loopzip_dealloc(loopzipobject *lz) { PyObject_GC_UnTrack(lz); Py_XDECREF(lz->ittuple); //Py_XDECREF(lz->result); lz->ob_type->tp_free(lz); } static int loopzip_traverse(loopzipobject *lz, visitproc visit, void *arg) { if (lz->ittuple) return visit(lz->ittuple, arg); return 0; } static PyObject * loopzip_next(loopzipobject *lz) { int i; long tuplesize = lz->tuplesize; PyObject *result = lz->result; PyObject *it; PyObject *item; /* XXX: Add check that resultsize == tuplesize */ for (i=0 ; i < tuplesize ; i++) { item = PyList_GET_ITEM(result, i); Py_DECREF(item); it = PyTuple_GET_ITEM(lz->ittuple, i); item = PyIter_Next(it); if (item == NULL) return NULL; PyList_SET_ITEM(result, i, item); } Py_INCREF(result); return result; } static PyObject * loopzip_getiter(PyObject *lz) { Py_INCREF(lz); return lz; } PyDoc_STRVAR(loopzip_doc, "loopzip(iter1 [,iter2 [...]]) --> loopzip object\n\ \n\ Return an loopzip object whose .next() method returns a list where\n\ the i-th element comes from the i-th iterable argument. The .next()\n\ method updates the returns the same list everytime until the shortest\n\ iterable in the argument sequence is exhausted and then it raises\n\ StopIteration. Works like the zip() function but consumes less memory.\n\ Unlike zip, it returns an iterator and the n-th return is a list rather\n\ than a tuple. It is appropriate for use in loops, but not for conversion\n\ to a list. For example: list(loopzip('abc')) returns a list of three\n\ identical sublists which is usually not what was intended."); PyTypeObject loopzip_type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "itertools.loopzip", /* tp_name */ sizeof(loopzipobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)loopzip_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ loopzip_doc, /* tp_doc */ (traverseproc)loopzip_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)loopzip_getiter, /* tp_iter */ (iternextfunc)loopzip_next, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ loopzip_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; /* repeat object ************************************************************/ typedef struct { PyObject_HEAD PyObject *element; } repeatobject; PyTypeObject repeat_type; static PyObject * repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { repeatobject *ro; PyObject *element; if (!PyArg_UnpackTuple(args, "repeat", 1, 1, &element)) return NULL; ro = (repeatobject *)type->tp_alloc(type, 0); if (ro == NULL) return NULL; Py_INCREF(element); ro->element = element; return (PyObject *)ro; } static void repeat_dealloc(repeatobject *ro) { PyObject_GC_UnTrack(ro); Py_XDECREF(ro->element); ro->ob_type->tp_free(ro); } static int repeat_traverse(repeatobject *ro, visitproc visit, void *arg) { if (ro->element) return visit(ro->element, arg); return 0; } static PyObject * repeat_next(repeatobject *ro) { Py_INCREF(ro->element); return ro->element; } static PyObject * repeat_getiter(PyObject *ro) { Py_INCREF(ro); return ro; } PyDoc_STRVAR(repeat_doc, "repeat(element) -> create an iterator which returns the element endlessly."); PyTypeObject repeat_type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "itertools.repeat", /* tp_name */ sizeof(repeatobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)repeat_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ repeat_doc, /* tp_doc */ (traverseproc)repeat_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)repeat_getiter, /* tp_iter */ (iternextfunc)repeat_next, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ repeat_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; /* module level code ********************************************************/ PyDoc_STRVAR(module_doc, "Module implements a set of functional tools for creating and using iterators.\n\ \n\ Infinite iterators:\n\ count([n]) --> n, n+1, n+2, ...\n\ cycle(seq) --> seq0, seq1, ... seqlast, seq0, ...\n\ repeat(elem) --> elem, elem, elem, elem\n\ tabulate(fun, [n]) --> fun(n), fun(n+1), fun(n+2), ...\n\ \n\ Iterators terminating on the shortest input sequence:\n\ loopzip(p, q, ...) --> [p[0], q[0]], [p[1], q[1]], ... \n\ same list each time but with updated contents\n\ ifilter(pred, seq, invert=False) --> elements of seq where\n\ pred(elem) is True (or False invert is set)\n\ islice(seq, start, stop, step) --> elements from\n\ seq[start:stop:step]\n\ imap(fun, p, q) --> fun(p0, q0), fun(p1, q1), ...\n\ "); /* XXX repeat(e) = lambda: cycle([e]) enumerate(s, n=0) = lambda: izip(count(n), s) tabulate(f, n=0) = lambda: imap(f, count(n)) nth(s, n) = lambda: islice(n, n+1) ? apply(s, f, args, kw) ? are both izip and loopzip needed? ? first(pred, seqn) takewhile dropwhile No iterator form: partition(s, pred) unzip --> multiple iterators ?? how would this work starmap --> [yield func(*args) for args in ia] starmap(f, s) --> f(*(s1)), f(*(s2)) */ PyMODINIT_FUNC inititertools(void) { PyObject *m; m = Py_InitModule3("itertools", NULL, module_doc); if (PyType_Ready(×_type) < 0) return; Py_INCREF(×_type); PyModule_AddObject(m, "times", (PyObject *)×_type); if (PyType_Ready(&ifilter_type) < 0) return; Py_INCREF(&ifilter_type); PyModule_AddObject(m, "ifilter", (PyObject *)&ifilter_type); if (PyType_Ready(&count_type) < 0) return; Py_INCREF(&count_type); PyModule_AddObject(m, "count", (PyObject *)&count_type); if (PyType_Ready(&loopzip_type) < 0) return; Py_INCREF(&loopzip_type); PyModule_AddObject(m, "loopzip", (PyObject *)&loopzip_type); if (PyType_Ready(&repeat_type) < 0) return; Py_INCREF(&repeat_type); PyModule_AddObject(m, "repeat", (PyObject *)&repeat_type); } --- NEW FILE: libitertools.tex --- \section{\module{itertools} --- Functions creating iterators for efficient looping} \declaremodule{standard}{itertools} \modulesynopsis{Functions creating iterators for efficient looping.} This module implements a number of iterator building blocks inspired by constructs from the Haskell and SML programming languages. Each has been recast in a form suitable for Python. \versionadded{2.3} With the advent of iterators and generators in Python 2.3, each of these tools can be expressed easily and succinctly in pure python. Rather duplicating what can already be done, this module takes the slightly unnatural approach of providing value in other ways: \begin{itemize} \item Instead of constructing an over-specialized toolset, this module provides basic building blocks that can be readily combined. For instance, SML provides a tabulation tool: \code{tabulate(\var{f})} which produces a sequence \code{f(0), f(1), ...}. This toolbox takes a diffenct approach of providing \function{imap()} and \function{count()} which can be combined to form \code{imap(\var{f}, count())} and produce an equivalent result. \item Wherever straight-forward alternatives exist, the corresponding tools in this module seek to meet a different need and are designed for speed. In fact, the \emph{sole} justification for this module being written in C is its speed advantage. For instance, Python's \module{__builtins__} module has an easy-to-use, no surprises version of \function(zip()). This module's corresponding function, \function{loopzip()} returns an iterator rather than a full list. Also, calls to the iterator return a mutable list rather than a tuple and it returns the \emph{same} list on each pass. Used in a \keyword{for} loop, \function{loopzip()} can be directly substituted for \function{zip()} and run much faster. It has nearly zero overhead since the looping is done in C code (bypassing Python's eval loop); since it returns an iterator (saving the need to allocate a list and append to it an element at a time); and since it reuses just one output list (saving the time to allocate and build a tuple on every pass). Though very fast, using \function{loopzip()} outside of a \keyword{for} loop can result in surprising behavior and an unwelcome refresher lesson in mutability. \item Another source of value comes from standardizing a core set of tools to avoid the readability and reliability problems that arise when many different individuals create their own slightly varying implementations each with their own quirks and naming conventions. \item Whether cast in pure python form or C code, tools that use iterators are more memory efficient than their list based counterparts. Adopting the principles of just-in-time manufacturing, they create data when and where needed instead of consuming memory with the computer equivalent of ``inventory''. \end{itemize} \subsection{Itertool functions \label{itertools-functions}} \begin{funcdesc}{count}{\optional{n}} Make an iterator that returns consecutive integers starting with \var{n}. Used in zip and loop constructions to consecutively number a sequence. Equivalent to: \begin{verbatim} def count(n=0): while True: yield n cnt += 1 \end{verbatim} \end{funcdesc} \begin{funcdesc}{ifilter}{func, iterable \optional{, invert}} Make an iterator that filters elements from iterable returning only those for which the function evaluates to \code{True}. If \var{invert} is \code{True}, then reverse the process and pass through only those elements for which the function evaluates to \code{False}. Equivalent to: \begin{verbatim} def filter(func, iterable, invert=False): iterable = iter(iterable) while True: x = bool(iterable.next()) if not invert and x or invert and not x: yield None \end{verbatim} \end{funcdesc} \begin{funcdesc}{loopzip}{*iterables} Make an iterator that aggregates elements from each of the iterables. Like \function{zip()} except that it returns an iterator instead of a list and the individual elements are stored in a list rather than in a tuple. The \emph{same} list is used for each pass and only the contents are updated; hence, \function{loopzip()} is only appropriate in a \keyword{for} loop or other itertool. The iterator terminates with \exception{StopIteration} when the first of the iterables is exhausted. Equivalent to: \begin{verbatim} def loopzip(*iterables): iterables = map(iter, iterables) result = [None] * len(iterables) while True: for i in xrange(len(iterables)): result[i] = iterable[i].next() yield result \end{verbatim} \end{funcdesc} \begin{funcdesc}{repeat}{obj} Make an iterator that returns \var{obj} over and over again. Used inside map, zip, or loop constructions for multiple references to the same object. Equivalent to: \begin{verbatim} def repeat(x): while True: yield None \end{verbatim} \end{funcdesc} \begin{funcdesc}{times}{n} Make an iterator that returns None \var{n} times. Used for looping a specific number of times without creating a number object on each pass. Equivalent to: \begin{verbatim} def times(n): for i in xrange(n): yield None \end{verbatim} \end{funcdesc} \subsection{Examples \label{itertools-example}} The following examples show common uses for each tool and demonstrate ways they can be combined. \begin{verbatim} >>> for i in times(3): ... print "Hello" ... Hello Hello Hello >>> for checknum, amount in loopzip(count(1200), amounts): ... print 'Check %d is for $%.2f' % (checknum, amount) ... Check 1200 is for $120.15 Check 1201 is for $764.05 Check 1202 is for $823.14 >>> bases = [2, 3, 5, 7] >>> powers = [2, 3, 4] >>> for power in powers: ... print list(imap(operator.pow, bases, repeat(power))) ... \end{verbatim} As a further example of how itertools can be combined, here are a few re-definitions of existing tools: \begin{verbatim} >>> enumerate = lambda s: izip(count(), s) >>> tabulate = lambda f: imap(f, count()) >>> iteritems = lambda d: izip(d.iterkeys(), d.itervalues()) >>> repeat = lambda o: cycle([o]) \end{verbatim} --- NEW FILE: setup.py --- from distutils.core import setup, Extension setup(name="itertools", ext_modules=[Extension("itertools", ["itertools.c"])]) --- NEW FILE: test_itertools.py --- import unittest from test import test_support from itertools import * class TestBasicOps(unittest.TestCase): def test_count(self): self.assertEqual(zip('abc',count()), [('a', 0), ('b', 1), ('c', 2)]) self.assertEqual(zip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)]) def test_ifilter(self): def isEven(x): return x%2==0 self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4]) self.assertEqual(list(ifilter(isEven, range(6), True)), [1,3,5]) def test_loopzip(self): ans = [(x,y) for x, y in loopzip('abc',count())] self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) self.assertEqual(list(loopzip('abc',count())), [['c', 2]] * 3) def test_repeat(self): self.assertEqual(zip(xrange(3),repeat('a')), [(0, 'a'), (1, 'a'), (2, 'a')]) def test_times(self): self.assertEqual(list(times(3)), [None]*3) def test_main(): suite = unittest.TestSuite() for testclass in (TestBasicOps, ): suite.addTest(unittest.makeSuite(testclass)) test_support.run_suite(suite) if __name__ == "__main__": test_main() From rhettinger@users.sourceforge.net Mon Jan 27 00:19:00 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 26 Jan 2003 16:19:00 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools todo.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv11929 Added Files: todo.txt Log Message: Add a open items list. --- NEW FILE: todo.txt --- Add: islice(iterator, start, stop, step) cylce(seqn) imap(func, iter1, iter2, ...) Verify: proper GC refcounts From tim_one@users.sourceforge.net Mon Jan 27 00:19:52 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 16:19:52 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv11749 Modified Files: pickletools.py Log Message: Got rid of the Walker base class and the Dis disassembler class. There's now a genops(pickle) generator instead, and a dis() function. The code is simpler, faster, and clearer this way. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** pickletools.py 26 Jan 2003 20:04:35 -0000 1.25 --- pickletools.py 27 Jan 2003 00:19:50 -0000 1.26 *************** *** 6,10 **** # descriptors. # ! # - A symbolic pickle disassembler. # # - A pickle verifier: read a pickle and check it exhaustively for --- 6,10 ---- # descriptors. # ! # - A symbolic pickle disassembler (done -- see function dis()). # # - A pickle verifier: read a pickle and check it exhaustively for *************** *** 1365,1449 **** ############################################################################## ! # A pickle walker base clase. ! ! class Walker: ! def __init__(self, pickle): ! """pickle is a file-like object containing a pickle bytestream. ! ! Invoking walk() traverses the pickle, calling visit() for each ! opcode encountered, then calling done() once at the end. Subclasses ! will want to override visit(), and possibly done(). The default ! implementations do nothing. ! """ ! self.pickle = pickle ! if hasattr(pickle, 'tell'): ! def position(): ! return pickle.tell() ! else: ! def position(): ! return None ! self.position = position ! def walk(self): ! """"Run" the pickle, from the current position, until a STOP opcode. ! For each opcode encountered, calls ! self.visit(opcode, arg, pos) ! opcode is an OpcodeInfo record, describing the current opcode. ! If the opcode has an argument embedded in the pickle, arg contains ! its decoded value, as a Python object. If the opcode doesn't have ! an argument, arg is None. ! If the pickle has a tell() method, pos was the value of pickle.tell() ! before reading the current opcode. Else pos is None. ! After a STOP opcode triggers a visit() call, self.done() is called ! once. ! """ ! pickle = self.pickle ! position = self.position ! while True: ! pos = position() ! code = pickle.read(1) ! opcode = code2op.get(code) ! if opcode is None: ! if code == "": ! raise ValueError("pickle exhausted before seeing STOP") ! else: ! raise ValueError("at position %s, opcode %r unknown" % ( ! pos is None and "" or pos, ! code)) ! if opcode.arg is None: ! arg = None else: ! arg = opcode.arg.reader(pickle) ! self.visit(opcode, arg, pos) ! if code == '.': ! assert opcode.name == 'STOP' ! break ! self.done() ! def visit(self, opcode, arg, pos): ! "Called once per opcode. See the walk() docs for argument details." ! pass ! def done(self): ! "Called after STOP is passed to visit()." ! pass ! class Dis(Walker): ! def __init__(self, pickle, out=None): ! Walker.__init__(self, pickle) ! self.out = out ! def visit(self, opcode, arg, pos): ! out = self.out if pos is not None: print >> out, "%5d:" % pos, --- 1365,1439 ---- ############################################################################## ! # A pickle opcode generator. ! def genops(pickle): ! """"Generate all the opcodes in a pickle. ! 'pickle' is a file-like object, or string, containing the pickle. ! Each opcode in the pickle is generated, from the current pickle position, ! stopping after a STOP opcode is delivered. A triple is generated for ! each opcode: ! opcode, arg, pos ! opcode is an OpcodeInfo record, describing the current opcode. ! If the opcode has an argument embedded in the pickle, arg is its decoded ! value, as a Python object. If the opcode doesn't have an argument, arg ! is None. ! If the pickle has a tell() method, pos was the value of pickle.tell() ! before reading the current opcode. If the pickle is a string object, ! it's wrapped in a StringIO object, and the latter's tell() result is ! used. Else (the pickle doesn't have a tell(), and it's not obvious how ! to query its current position) pos is None. ! """ ! import cStringIO as StringIO ! if isinstance(pickle, str): ! pickle = StringIO.StringIO(pickle) ! if hasattr(pickle, "tell"): ! getpos = pickle.tell ! else: ! getpos = lambda: None ! while True: ! pos = getpos() ! code = pickle.read(1) ! opcode = code2op.get(code) ! if opcode is None: ! if code == "": ! raise ValueError("pickle exhausted before seeing STOP") else: ! raise ValueError("at position %s, opcode %r unknown" % ( ! pos is None and "" or pos, ! code)) ! if opcode.arg is None: ! arg = None ! else: ! arg = opcode.arg.reader(pickle) ! yield opcode, arg, pos ! if code == '.': ! assert opcode.name == 'STOP' ! break ! ############################################################################## ! # A symbolic pickle disassembler. ! def dis(pickle, out=None): ! """Produce a symbolic disassembly of a pickle. ! 'pickle' is file-like object, or string, containing a (at least one) ! pickle. The pickle is disassembled from the current position, through ! the first STOP opcode encountered. ! Optional arg 'out' is a file-like object to which the disassembly is ! printed. It defaults to sys.stdout. ! """ ! ! for opcode, arg, pos in genops(pickle): if pos is not None: print >> out, "%5d:" % pos, *************** *** 1455,1465 **** _disassembler_test = """ - >>> from StringIO import StringIO >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] >>> pik = pickle.dumps(x) ! >>> stream = StringIO(pik) ! >>> d = Dis(stream) ! >>> d.walk() 0: ( MARK 1: l LIST --- 1445,1452 ---- _disassembler_test = """ >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] >>> pik = pickle.dumps(x) ! >>> dis(pik) 0: ( MARK 1: l LIST *************** *** 1487,1494 **** Try again with a "binary" pickle. >>> pik = pickle.dumps(x, 1) ! >>> stream = StringIO(pik) ! >>> d = Dis(stream) ! >>> d.walk() 0: ] EMPTY_LIST 1: q BINPUT 0 --- 1474,1480 ---- Try again with a "binary" pickle. + >>> pik = pickle.dumps(x, 1) ! >>> dis(pik) 0: ] EMPTY_LIST 1: q BINPUT 0 From rhettinger@users.sourceforge.net Mon Jan 27 00:27:43 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 26 Jan 2003 16:27:43 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.1,1.2 libitertools.tex,1.1,1.2 todo.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv14929 Modified Files: itertools.c libitertools.tex todo.txt Log Message: Updated todo and comments Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** itertools.c 27 Jan 2003 00:16:51 -0000 1.1 --- itertools.c 27 Jan 2003 00:27:41 -0000 1.2 *************** *** 629,633 **** cycle(seq) --> seq0, seq1, ... seqlast, seq0, ...\n\ repeat(elem) --> elem, elem, elem, elem\n\ - tabulate(fun, [n]) --> fun(n), fun(n+1), fun(n+2), ...\n\ \n\ Iterators terminating on the shortest input sequence:\n\ --- 629,632 ---- *************** *** 639,666 **** seq[start:stop:step]\n\ imap(fun, p, q) --> fun(p0, q0), fun(p1, q1), ...\n\ "); - /* - XXX - repeat(e) = lambda: cycle([e]) - enumerate(s, n=0) = lambda: izip(count(n), s) - tabulate(f, n=0) = lambda: imap(f, count(n)) - nth(s, n) = lambda: islice(n, n+1) - - ? apply(s, f, args, kw) - - ? are both izip and loopzip needed? - ? first(pred, seqn) - - takewhile - dropwhile - - No iterator form: partition(s, pred) - - unzip --> multiple iterators ?? how would this work - - starmap --> [yield func(*args) for args in ia] - starmap(f, s) --> f(*(s1)), f(*(s2)) - */ PyMODINIT_FUNC --- 638,644 ---- seq[start:stop:step]\n\ imap(fun, p, q) --> fun(p0, q0), fun(p1, q1), ...\n\ + starmap(fun, s) --> fun(*s[0]), fun(*s[1]), ...\n\ "); PyMODINIT_FUNC Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** libitertools.tex 27 Jan 2003 00:16:51 -0000 1.1 --- libitertools.tex 27 Jan 2003 00:27:41 -0000 1.2 *************** *** 176,179 **** --- 176,180 ---- >>> iteritems = lambda d: izip(d.iterkeys(), d.itervalues()) >>> repeat = lambda o: cycle([o]) + >>> nth = lambda s, n: islice(n, n+1).next() \end{verbatim} Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** todo.txt 27 Jan 2003 00:18:58 -0000 1.1 --- todo.txt 27 Jan 2003 00:27:41 -0000 1.2 *************** *** 1,6 **** Add: islice(iterator, start, stop, step) ! cylce(seqn) imap(func, iter1, iter2, ...) Verify: --- 1,7 ---- Add: islice(iterator, start, stop, step) ! cycle(seqn) imap(func, iter1, iter2, ...) + starmap(f, s) --> f(*(s1)), f(*(s2)) = [yield func(*args) for args in ia] Verify: *************** *** 8,9 **** --- 9,12 ---- refcounts + Consider adding: + unzip() --> list of multiple iterator ??? how would this work From tim_one@users.sourceforge.net Mon Jan 27 00:44:44 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 16:44:44 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv20938 Modified Files: pickletools.py Log Message: Heh -- 5 stinking opcodes to go, and I finally hit oue that actually has two arguments. Added GLOBAL and hacked around that. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** pickletools.py 27 Jan 2003 00:19:50 -0000 1.26 --- pickletools.py 27 Jan 2003 00:44:40 -0000 1.27 *************** *** 286,289 **** --- 286,314 ---- """) + def read_stringnl_noescape_pair(f): + """ + >>> import StringIO + >>> read_stringnl_noescape_pair(StringIO.StringIO("Queue\\nEmpty\\njunk")) + 'Queue.Empty' + """ + + return "%s %s" % (read_stringnl_noescape(f), read_stringnl_noescape(f)) + + stringnl_noescape_pair = ArgumentDescriptor( + name='stringnl_noescape_pair', + n=UP_TO_NEWLINE, + reader=read_stringnl_noescape_pair, + doc="""A pair of newline-terminated strings. + + These are str-style strings, without embedded + escapes, or bracketing quotes. They should + consist solely of printable ASCII characters. + The pair is returned as a single string, with + a single '.' separating the two strings. + """) + + def read_stringnl_noescape_pair(f): + return read_stringnl_noescape(f), read_stringnl_noescape(f) + def read_string4(f): """ *************** *** 1188,1191 **** --- 1213,1233 ---- """), + # Global names (class names). + + I(name='GLOBAL', + code='c', + arg=stringnl_noescape_pair, + stack_before=[], + stack_after=[anyobject], + proto=0, + doc="""Push a global object on the stack. + + Two newline-terminated strings follow the GLOBAL opcode. The first is + taken as a module name, and the second as a class name. The class + object module.class is pushed on the stack. More accurately, the + object returned by self.find_class(module, class) is pushed on the + stack, so unpickling subclasses can override this form of lookup. + """), + # Machine control. *************** *** 1260,1274 **** """), - I(name='GLOBAL', - code='c', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - I(name='INST', code='i', --- 1302,1305 ---- *************** *** 1427,1431 **** """Produce a symbolic disassembly of a pickle. ! 'pickle' is file-like object, or string, containing a (at least one) pickle. The pickle is disassembled from the current position, through the first STOP opcode encountered. --- 1458,1462 ---- """Produce a symbolic disassembly of a pickle. ! 'pickle' is a file-like object, or string, containing a (at least one) pickle. The pickle is disassembled from the current position, through the first STOP opcode encountered. From tim_one@users.sourceforge.net Mon Jan 27 00:47:09 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 16:47:09 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv21513 Modified Files: pickletools.py Log Message: Fixed a remarkably confusing buglet in fresh code. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** pickletools.py 27 Jan 2003 00:44:40 -0000 1.27 --- pickletools.py 27 Jan 2003 00:47:05 -0000 1.28 *************** *** 293,297 **** """ ! return "%s %s" % (read_stringnl_noescape(f), read_stringnl_noescape(f)) stringnl_noescape_pair = ArgumentDescriptor( --- 293,297 ---- """ ! return "%s.%s" % (read_stringnl_noescape(f), read_stringnl_noescape(f)) stringnl_noescape_pair = ArgumentDescriptor( *************** *** 307,313 **** a single '.' separating the two strings. """) - - def read_stringnl_noescape_pair(f): - return read_stringnl_noescape(f), read_stringnl_noescape(f) def read_string4(f): --- 307,310 ---- From rhettinger@users.sourceforge.net Mon Jan 27 01:35:23 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 26 Jan 2003 17:35:23 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.2,1.3 todo.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv2289 Modified Files: libitertools.tex todo.txt Log Message: Dropped cycle() from the todo list and documented the reasons. Re-added starmap(), takewhile(), and dropwhile(). Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** libitertools.tex 27 Jan 2003 00:27:41 -0000 1.2 --- libitertools.tex 27 Jan 2003 01:35:20 -0000 1.3 *************** *** 27,30 **** --- 27,42 ---- \code{imap(\var{f}, count())} and produce an equivalent result. + + \item Some tools were dropped because they offer no advantage over their + pure python counterparts or because their behavior was too + surprising. + + For instance, SML provides a tool: \code{cycle(\var{seq})} which + loops over the sequence elements and then starts again when the + sequence is exhausted. The surprising behavior is the need for + significant auxilliary storage (unusual for iterators). Also, it + is trivially implemented in python with almost no performance + penalty. + \item Wherever straight-forward alternatives exist, the corresponding tools in this module seek to meet a different need and are designed Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** todo.txt 27 Jan 2003 00:27:41 -0000 1.2 --- todo.txt 27 Jan 2003 01:35:21 -0000 1.3 *************** *** 1,7 **** Add: islice(iterator, start, stop, step) - cycle(seqn) imap(func, iter1, iter2, ...) ! starmap(f, s) --> f(*(s1)), f(*(s2)) = [yield func(*args) for args in ia] Verify: --- 1,9 ---- Add: islice(iterator, start, stop, step) imap(func, iter1, iter2, ...) ! iapply ! starmap() ! takewhile(pred, seqn) ! dropwhile(pred, seqn) Verify: *************** *** 9,12 **** refcounts ! Consider adding: ! unzip() --> list of multiple iterator ??? how would this work --- 11,16 ---- refcounts ! ! Things dropped because they bug me: ! cycle(seqn) requires auxilliary storage (which is surprising ! behavior for iterators). This is best left for pure python. From tim_one@users.sourceforge.net Mon Jan 27 02:06:06 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 18:06:06 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv10028 Modified Files: pickletools.py Log Message: Finished a first stab at all the remaining opcode docs. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** pickletools.py 27 Jan 2003 00:47:05 -0000 1.28 --- pickletools.py 27 Jan 2003 02:06:04 -0000 1.29 *************** *** 1210,1214 **** """), ! # Global names (class names). I(name='GLOBAL', --- 1210,1214 ---- """), ! # Puah a class object on the stack, via its module and name. I(name='GLOBAL', *************** *** 1218,1222 **** stack_after=[anyobject], proto=0, ! doc="""Push a global object on the stack. Two newline-terminated strings follow the GLOBAL opcode. The first is --- 1218,1222 ---- stack_after=[anyobject], proto=0, ! doc="""Push a global object (module.attr) on the stack. Two newline-terminated strings follow the GLOBAL opcode. The first is *************** *** 1227,1230 **** --- 1227,1382 ---- """), + # Ways to build objects of classes pickle doesn't know about directly + # (user-defined classes). I despair of documenting this accurately + # and comprehensibly -- you really have to read the pickle code to + # find all the special cases. + + I(name='REDUCE', + code='R', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[anyobject], + proto=0, + doc="""Push an object built from a callable and an argument tuple. + + The opcode is named to remind of the __reduce__() method. + + Stack before: ... callable pytuple + Stack after: ... callable(*pytuple) + + The callable and the argument tuple are the first two items returned + by a __reduce__ method. Applying the callable to the argtuple is + supposed to reproduce the original object, or at least get it started. + If the __reduce__ method returns a 3-tuple, the last component is an + argument to be passed to the object's __setstate__, and then the REDUCE + opcode is followed by code to create setstate's argument, and then a + BUILD opcode to apply __setstate__ to that argument. + + There are lots of special cases here. The argtuple can be None, in + which case callable.__basicnew__() is called instead to produce the + object to be pushed on the stack. This appears to be a trick unique + to ExtensionClasses, and is deprecated regardless. + + If type(callable) is not ClassType, REDUCE complains unless the + callable has been registered with the copy_reg module's + safe_constructors dict, or the callable has a magic + '__safe_for_unpickling__' attribute with a true value. I'm not sure + why it does this, but I've sure seen this complaint often enough when + I didn't want to . + """), + + I(name='BUILD', + code='b', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[anyobject], + proto=0, + doc="""Finish building an object, via __setstate__ or dict update. + + Stack before: ... anyobject argument + Stack after: ... anyobject + + where anyobject may have been mutated, as follows: + + If the object has a __setstate__ method, + + anyobject.__setstate__(argument) + + is called. + + Else the argument must be a dict, the object must have a __dict__, and + the object is updated via + + anyobject.__dict__.update(argument) + + This may raise RuntimeError in restricted execution mode (which + disallows access to __dict__ directly); in that case, the object + is updated instead via + + for k, v in argument.items(): + anyobject[k] = v + """), + + I(name='INST', + code='i', + arg=stringnl_noescape_pair, + stack_before=[markobject, stackslice], + stack_after=[anyobject], + proto=0, + doc="""Build a class instance. + + This is the protocol 0 version of protocol 1's OBJ opcode. + INST is followed by two newline-terminated strings, giving a + module and class name, just as for the GLOBAL opcode (and see + GLOBAL for more details about that). self.find_class(module, name) + is used to get a class object. + + In addition, all the objects on the stack following the topmost + markobject are gathered into a tuple and popped (along with the + topmost markobject), just as for the TUPLE opcode. + + Now it gets complicated. If all of these are true: + + + The argtuple is empty (markobject was at the top of the stack + at the start). + + + It's an old-style class object (the type of the class object is + ClassType). + + + The class object does not have a __getinitargs__ attribute. + + then we want to create an old-style class instance without invoking + its __init__() method (pickle has waffled on this over the years; not + calling __init__() is current wisdom). In this case, an instance of + an old-style dummy class is created, and then we try to rebind its + __class__ attribute to the desired class object. If this succeeds, + the new instance object is pushed on the stack, and we're done. In + restricted execution mode it can fail (assignment to __class__ is + disallowed), and I'm not really sure what happens then -- it looks + like the code ends up calling the class object's __init__ anyway, + via falling into the next case. + + Else (the argtuple is not empty, it's not an old-style class object, + or the class object does have a __getinitargs__ attribute), the code + first insists that the class object have a __safe_for_unpickling__ + attribute. Unlike as for the __safe_for_unpickling__ check in REDUCE, + it doesn't matter whether this attribute has a true or false value, it + only matters whether it exists (XXX this smells like a bug). If + __safe_for_unpickling__ dosn't exist, UnpicklingError is raised. + + Else (the class object does have a __safe_for_unpickling__ attr), + the class object obtained from INST's arguments is applied to the + argtuple obtained from the stack, and the resulting instance object + is pushed on the stack. + """), + + I(name='OBJ', + code='o', + arg=None, + stack_before=[markobject, anyobject, stackslice], + stack_after=[anyobject], + proto=1, + doc="""Build a class instance. + + This is the protocol 1 version of protocol 0's INST opcode, and is + very much like it. The major difference is that the class object + is taken off the stack, allowing it to be retrieved from the memo + repeatedly if several instances of the same class are created. This + can be much more efficient (in both time and space) than repeatedly + embedding the module and class names in INST opcodes. + + Unlike INST, OBJ takes no arguments from the opcode stream. Instead + the class object is taken off the stack, immediately above the + topmost markobject: + + Stack before: ... markobject classobject stackslice + Stack after: ... new_instance_object + + As for INST, the remainder of the stack above the markobject is + gathered into an argument tuple, and then the logic seems identical, + except that no __safe_for_unpickling__ check is done (XXX this smells + like a bug). See INST for the gory details. + """), + # Machine control. *************** *** 1274,1323 **** returns is pushed on the stack. See PERSID for more detail. """), - - # XXX opcodes below this point haven't been done yet. - - I(name='REDUCE', - code='R', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='BUILD', - code='b', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='INST', - code='i', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), - - I(name='OBJ', - code='o', - arg=None, - stack_before=[], - stack_after=[], - proto=0, - doc="""XXX One-line description goes here. - - XXX Doc body goes here. - """), ] del I --- 1426,1429 ---- *************** *** 1472,1476 **** print >> out, "%-10s %r" % (opcode.name, arg) ! _disassembler_test = """ >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] --- 1578,1582 ---- print >> out, "%-10s %r" % (opcode.name, arg) ! _dis_test1 = """ >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] *************** *** 1526,1530 **** """ ! __test__ = {'dissassembler_test': _disassembler_test, } --- 1632,1636 ---- """ ! __test__ = {'dissassembler_test1': _dis_test1, } From tim_one@users.sourceforge.net Mon Jan 27 02:49:42 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sun, 26 Jan 2003 18:49:42 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv20734 Modified Files: pickletools.py Log Message: Woo hoo! Added annotations to the disassembler output so that an opcode that uses a markobject tells us which MARK opcode created it. Don't know about anyone else, but it greatly improves the comprehensibility for me. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** pickletools.py 27 Jan 2003 02:06:04 -0000 1.29 --- pickletools.py 27 Jan 2003 02:49:40 -0000 1.30 *************** *** 978,982 **** stack_before=[pylist, markobject, stackslice], stack_after=[pylist], ! proto=0, doc="""Extend a list by a slice of stack objects. --- 978,982 ---- stack_before=[pylist, markobject, stackslice], stack_after=[pylist], ! proto=1, doc="""Extend a list by a slice of stack objects. *************** *** 1210,1214 **** """), ! # Puah a class object on the stack, via its module and name. I(name='GLOBAL', --- 1210,1215 ---- """), ! # Puah a class object, or module function, on the stack, via its module ! # and name. I(name='GLOBAL', *************** *** 1569,1582 **** """ for opcode, arg, pos in genops(pickle): if pos is not None: print >> out, "%5d:" % pos, - print >> out, opcode.code, - if arg is None: - print >> out, opcode.name - else: - print >> out, "%-10s %r" % (opcode.name, arg) ! _dis_test1 = """ >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] --- 1570,1600 ---- """ + markstack = [] for opcode, arg, pos in genops(pickle): if pos is not None: print >> out, "%5d:" % pos, ! line = opcode.code + " " + opcode.name ! ! markmsg = None ! if markstack and markobject in opcode.stack_before: ! markpos = markstack.pop() ! if markpos is not None: ! markmsg = "(MARK at %d)" % markpos ! ! if arg is not None or markmsg: ! # make a mild effort to align arguments ! line += (' ' * 10)[len(opcode.name):] ! if arg is not None: ! line += ' ' + repr(arg) ! if markmsg: ! line += ' ' + markmsg ! print >> out, line ! ! if markobject in opcode.stack_after: ! markstack.append(pos) ! ! ! _dis_test = """ >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] *************** *** 1584,1588 **** >>> dis(pik) 0: ( MARK ! 1: l LIST 2: p PUT 0 5: I INT 1 --- 1602,1606 ---- >>> dis(pik) 0: ( MARK ! 1: l LIST (MARK at 0) 2: p PUT 0 5: I INT 1 *************** *** 1593,1601 **** 14: I INT 3 17: I INT 4 ! 20: t TUPLE 21: p PUT 1 24: a APPEND 25: ( MARK ! 26: d DICT 27: p PUT 2 30: S STRING 'abc' --- 1611,1619 ---- 14: I INT 3 17: I INT 4 ! 20: t TUPLE (MARK at 13) 21: p PUT 1 24: a APPEND 25: ( MARK ! 26: d DICT (MARK at 25) 27: p PUT 2 30: S STRING 'abc' *************** *** 1619,1623 **** 9: K BININT1 3 11: K BININT1 4 ! 13: t TUPLE 14: q BINPUT 1 16: } EMPTY_DICT --- 1637,1641 ---- 9: K BININT1 3 11: K BININT1 4 ! 13: t TUPLE (MARK at 8) 14: q BINPUT 1 16: } EMPTY_DICT *************** *** 1628,1636 **** 34: q BINPUT 4 36: s SETITEM ! 37: e APPENDS 38: . STOP """ ! __test__ = {'dissassembler_test1': _dis_test1, } --- 1646,1705 ---- 34: q BINPUT 4 36: s SETITEM ! 37: e APPENDS (MARK at 3) 38: . STOP + + Exercise the INST/OBJ/BUILD family. + + >>> import random + >>> dis(pickle.dumps(random.random)) + 0: c GLOBAL 'random.random' + 15: p PUT 0 + 18: . STOP + + >>> x = [pickle.PicklingError()] * 2 + >>> dis(pickle.dumps(x)) + 0: ( MARK + 1: l LIST (MARK at 0) + 2: p PUT 0 + 5: ( MARK + 6: i INST 'pickle.PicklingError' (MARK at 5) + 28: p PUT 1 + 31: ( MARK + 32: d DICT (MARK at 31) + 33: p PUT 2 + 36: S STRING 'args' + 44: p PUT 3 + 47: ( MARK + 48: t TUPLE (MARK at 47) + 49: p PUT 4 + 52: s SETITEM + 53: b BUILD + 54: a APPEND + 55: g GET 1 + 58: a APPEND + 59: . STOP + + >>> dis(pickle.dumps(x, 1)) + 0: ] EMPTY_LIST + 1: q BINPUT 0 + 3: ( MARK + 4: ( MARK + 5: c GLOBAL 'pickle.PicklingError' + 27: q BINPUT 1 + 29: o OBJ (MARK at 4) + 30: q BINPUT 2 + 32: } EMPTY_DICT + 33: q BINPUT 3 + 35: U SHORT_BINSTRING 'args' + 41: q BINPUT 4 + 43: ) EMPTY_TUPLE + 44: s SETITEM + 45: b BUILD + 46: h BINGET 2 + 48: e APPENDS (MARK at 3) + 49: . STOP """ ! __test__ = {'dissassembler_test': _dis_test, } From rhettinger@users.sourceforge.net Mon Jan 27 04:24:16 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 26 Jan 2003 20:24:16 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.2,1.3 libitertools.tex,1.3,1.4 test_itertools.py,1.1,1.2 todo.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv10416 Modified Files: itertools.c libitertools.tex test_itertools.py todo.txt Log Message: Added imap() Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** itertools.c 27 Jan 2003 00:27:41 -0000 1.2 --- itertools.c 27 Jan 2003 04:24:14 -0000 1.3 *************** *** 2,5 **** --- 2,161 ---- #include "Python.h" + /* imap object ************************************************************/ + + typedef struct { + PyObject_HEAD + PyObject *iters; + PyObject *argtuple; + PyObject *func; + } imapobject; + + PyTypeObject imap_type; + + static PyObject * + imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *it, *iters, *argtuple; + imapobject *lz; + int numargs, i; + + numargs = PyTuple_Size(args); + if (numargs == 0) { + // XXX raise Err for not having a function arg + return NULL; + } + + iters = PyTuple_New(numargs-1); + if (iters == NULL) + return NULL; + + argtuple = PyTuple_New(numargs-1); + if (argtuple == NULL) { + Py_DECREF(iters); + return NULL; + } + + for (i=1 ; itp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(argtuple); + Py_DECREF(iters); + return NULL; + } + lz->iters = iters; + lz->argtuple = argtuple; + lz->func = PyTuple_GET_ITEM(args, 0); + + return (PyObject *)lz; + } + + static void + imap_dealloc(imapobject *lz) + { + PyObject_GC_UnTrack(lz); + //Py_XDECREF(lz->argtuple); + //Py_XDECREF(lz->iters); + lz->ob_type->tp_free(lz); + } + + static int + imap_traverse(imapobject *lz, visitproc visit, void *arg) + { + if (lz->argtuple) + return visit(lz->argtuple, arg); + return 0; + } + + static PyObject * + imap_next(imapobject *lz) + { + PyObject *val; + PyObject *iters=lz->iters, *argtuple=lz->argtuple; + int numargs, i; + + numargs = PyTuple_Size(lz->iters); + + for (i=0 ; iiters, i)); + if (val == NULL) + return NULL; + PyTuple_SET_ITEM(argtuple, i, val); + } + return PyObject_Call(lz->func, argtuple, NULL); + } + + static PyObject * + imap_getiter(PyObject *lz) + { + Py_INCREF(lz); + return lz; + } + + PyDoc_STRVAR(imap_doc, + "imap(func, *iterables) --> imap object\n\ + \n\ + Make an iterator that computes the function using arguments from\n\ + each of the iterables. Like map() except 1) that it returns\n\ + an iterator instead of a list, 2) that it stops when the shortest\n\ + iterable is exhausted instead of filling in None for shorter\n\ + iterables, and 3) that it does not accept None for func."); + + PyTypeObject imap_type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "itertools.imap", /* tp_name */ + sizeof(imapobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)imap_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + imap_doc, /* tp_doc */ + (traverseproc)imap_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)imap_getiter, /* tp_iter */ + (iternextfunc)imap_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + imap_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + }; + + /* times object ************************************************************/ *************** *** 195,199 **** PyDoc_STRVAR(ifilter_doc, ! "filter(function or None, sequence [, invert]) --> ifilter object\n\ \n\ Return those items of sequence for which function(item) is true. If\n\ --- 351,355 ---- PyDoc_STRVAR(ifilter_doc, ! "ifilter(function or None, sequence [, invert]) --> ifilter object\n\ \n\ Return those items of sequence for which function(item) is true. If\n\ *************** *** 648,655 **** m = Py_InitModule3("itertools", NULL, module_doc); if (PyType_Ready(×_type) < 0) return; Py_INCREF(×_type); - PyModule_AddObject(m, "times", (PyObject *)×_type); if (PyType_Ready(&ifilter_type) < 0) --- 804,816 ---- m = Py_InitModule3("itertools", NULL, module_doc); + PyModule_AddObject(m, "imap", (PyObject *)&imap_type); + if (PyType_Ready(&imap_type) < 0) + return; + Py_INCREF(&imap_type); + + PyModule_AddObject(m, "times", (PyObject *)×_type); if (PyType_Ready(×_type) < 0) return; Py_INCREF(×_type); if (PyType_Ready(&ifilter_type) < 0) Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libitertools.tex 27 Jan 2003 01:35:20 -0000 1.3 --- libitertools.tex 27 Jan 2003 04:24:14 -0000 1.4 *************** *** 27,31 **** \code{imap(\var{f}, count())} and produce an equivalent result. - \item Some tools were dropped because they offer no advantage over their pure python counterparts or because their behavior was too --- 27,30 ---- *************** *** 44,48 **** being written in C is its speed advantage. ! For instance, Python's \module{__builtins__} module has an easy-to-use, no surprises version of \function(zip()). This module's corresponding function, --- 43,47 ---- being written in C is its speed advantage. ! For instance, the \module{__builtins__} module has an easy-to-use, no surprises version of \function(zip()). This module's corresponding function, *************** *** 57,62 **** one output list (saving the time to allocate and build a tuple on every pass). Though very fast, using \function{loopzip()} outside of ! a \keyword{for} loop can result in surprising behavior and an ! unwelcome refresher lesson in mutability. \item Another source of value comes from standardizing a core set of tools --- 56,61 ---- one output list (saving the time to allocate and build a tuple on every pass). Though very fast, using \function{loopzip()} outside of ! a \keyword{for} loop or other itertool can result in surprising ! behavior and an unwelcome refresher lesson in mutability. \item Another source of value comes from standardizing a core set of tools *************** *** 107,110 **** --- 106,126 ---- \end{funcdesc} + \begin{funcdesc}{imap}{func, *iterables} + Make an iterator that computes the function using arguments from + each of the iterables. Like \function{map()} except 1) that it returns + an iterator instead of a list, 2) that it stops when the shortest + iterable is exhausted instead of filling in \code{None} for shorter + iterables, and 3) that it does not accept \code{None} for \var{func}. + Equivalent to: + + \begin{verbatim} + def imap(func, *iterables): + iterables = map(iter, iterables) + while True: + args = [i.next() for i in iterables] + yield f(*args) + \end{verbatim} + \end{funcdesc} + \begin{funcdesc}{loopzip}{*iterables} Make an iterator that aggregates elements from each of the iterables. *************** *** 184,192 **** \begin{verbatim} ! >>> enumerate = lambda s: izip(count(), s) ! >>> tabulate = lambda f: imap(f, count()) ! >>> iteritems = lambda d: izip(d.iterkeys(), d.itervalues()) ! >>> repeat = lambda o: cycle([o]) ! >>> nth = lambda s, n: islice(n, n+1).next() \end{verbatim} --- 200,211 ---- \begin{verbatim} ! >>> def enumerate(s): ! ... return izip(count(), s) ! >>> def tabulate(f): ! ... return imap(f, count()) ! >>> def iteritems(d): ! ... return izip(d.iterkeys(), d.itervalues()) ! >>> def nth(s, n): ! ... return islice(n, n+1).next() \end{verbatim} Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_itertools.py 27 Jan 2003 00:16:51 -0000 1.1 --- test_itertools.py 27 Jan 2003 04:24:14 -0000 1.2 *************** *** 20,29 **** def test_repeat(self): ! self.assertEqual(zip(xrange(3),repeat('a')), [(0, 'a'), (1, 'a'), (2, 'a')]) def test_times(self): self.assertEqual(list(times(3)), [None]*3) ! def test_main(): suite = unittest.TestSuite() --- 20,34 ---- def test_repeat(self): ! self.assertEqual(zip(xrange(3),repeat('a')), ! [(0, 'a'), (1, 'a'), (2, 'a')]) def test_times(self): self.assertEqual(list(times(3)), [None]*3) ! def test_imap(self): ! import operator ! self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), ! [0**1, 1**2, 2**3]) ! def test_main(): suite = unittest.TestSuite() Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** todo.txt 27 Jan 2003 01:35:21 -0000 1.3 --- todo.txt 27 Jan 2003 04:24:14 -0000 1.4 *************** *** 1,5 **** Add: islice(iterator, start, stop, step) - imap(func, iter1, iter2, ...) iapply starmap() --- 1,4 ---- From rhettinger@users.sourceforge.net Mon Jan 27 05:24:43 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 26 Jan 2003 21:24:43 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.3,1.4 libitertools.tex,1.4,1.5 test_itertools.py,1.2,1.3 todo.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv25992 Modified Files: itertools.c libitertools.tex test_itertools.py todo.txt Log Message: Added starmap(). Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** itertools.c 27 Jan 2003 04:24:14 -0000 1.3 --- itertools.c 27 Jan 2003 05:24:40 -0000 1.4 *************** *** 2,5 **** --- 2,134 ---- #include "Python.h" + + /* starmap object ************************************************************/ + + typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; + } starmapobject; + + PyTypeObject starmap_type; + + static PyObject * + starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *func, *seq; + PyObject *it; + starmapobject *lz; + + if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq)) + return NULL; + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create starmapobject structure */ + lz = (starmapobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + Py_INCREF(func); + lz->func = func; + lz->it = it; + + return (PyObject *)lz; + } + + static void + starmap_dealloc(starmapobject *lz) + { + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->func); + Py_XDECREF(lz->it); + lz->ob_type->tp_free(lz); + } + + static int + starmap_traverse(starmapobject *lz, visitproc visit, void *arg) + { + if (lz->it) + return visit(lz->it, arg); + return 0; + } + + static PyObject * + starmap_next(starmapobject *lz) + { + PyObject *args; + PyObject *result; + + args = PyIter_Next(lz->it); + if (args == NULL) + return NULL; + result = PyObject_Call(lz->func, args, NULL); + Py_DECREF(args); + return result; + } + + static PyObject * + starmap_getiter(PyObject *lz) + { + Py_INCREF(lz); + return lz; + } + + PyDoc_STRVAR(starmap_doc, + "starmap(function, sequence) --> starmap object\n\ + \n\ + Return an iterator whose values are returned from the function evaluated\n\ + with a argument tuple taken from the given sequence."); + + PyTypeObject starmap_type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "itertools.starmap", /* tp_name */ + sizeof(starmapobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)starmap_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + starmap_doc, /* tp_doc */ + (traverseproc)starmap_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)starmap_getiter, /* tp_iter */ + (iternextfunc)starmap_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + starmap_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + }; + + /* imap object ************************************************************/ *************** *** 65,70 **** { PyObject_GC_UnTrack(lz); ! //Py_XDECREF(lz->argtuple); ! //Py_XDECREF(lz->iters); lz->ob_type->tp_free(lz); } --- 194,199 ---- { PyObject_GC_UnTrack(lz); ! Py_XDECREF(lz->argtuple); ! Py_XDECREF(lz->iters); lz->ob_type->tp_free(lz); } *************** *** 289,292 **** --- 418,422 ---- return NULL; } + Py_INCREF(func); lz->func = func; lz->it = it; *************** *** 300,304 **** { PyObject_GC_UnTrack(lz); ! //Py_XDECREF(lz->func); Py_XDECREF(lz->it); lz->ob_type->tp_free(lz); --- 430,434 ---- { PyObject_GC_UnTrack(lz); ! Py_XDECREF(lz->func); Py_XDECREF(lz->it); lz->ob_type->tp_free(lz); *************** *** 803,806 **** --- 933,941 ---- PyObject *m; m = Py_InitModule3("itertools", NULL, module_doc); + + PyModule_AddObject(m, "starmap", (PyObject *)&starmap_type); + if (PyType_Ready(&starmap_type) < 0) + return; + Py_INCREF(&starmap_type); PyModule_AddObject(m, "imap", (PyObject *)&imap_type); Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** libitertools.tex 27 Jan 2003 04:24:14 -0000 1.4 --- libitertools.tex 27 Jan 2003 05:24:40 -0000 1.5 *************** *** 52,59 **** for \function{zip()} and run much faster. It has nearly zero overhead since the looping is done in C code (bypassing Python's eval ! loop); since it returns an iterator (saving the need to allocate a ! list and append to it an element at a time); and since it reuses just one output list (saving the time to allocate and build a tuple on ! every pass). Though very fast, using \function{loopzip()} outside of a \keyword{for} loop or other itertool can result in surprising behavior and an unwelcome refresher lesson in mutability. --- 52,59 ---- for \function{zip()} and run much faster. It has nearly zero overhead since the looping is done in C code (bypassing Python's eval ! loop); since it returns an iterator (saving the need to allocate a ! list and append to it an element at a time); and since it reuses just one output list (saving the time to allocate and build a tuple on ! every pass). Though very fast, using \function{loopzip()} outside of a \keyword{for} loop or other itertool can result in surprising behavior and an unwelcome refresher lesson in mutability. *************** *** 70,74 **** computer equivalent of ``inventory''. ! \end{itemize} --- 70,74 ---- computer equivalent of ``inventory''. ! \end{itemize} *************** *** 98,106 **** \begin{verbatim} def filter(func, iterable, invert=False): ! iterable = iter(iterable) while True: ! x = bool(iterable.next()) ! if not invert and x or invert and not x: ! yield None \end{verbatim} \end{funcdesc} --- 98,106 ---- \begin{verbatim} def filter(func, iterable, invert=False): ! iterable = iter(iterable) while True: ! x = bool(iterable.next()) ! if not invert and x or invert and not x: ! yield None \end{verbatim} \end{funcdesc} *************** *** 116,123 **** \begin{verbatim} def imap(func, *iterables): ! iterables = map(iter, iterables) while True: ! args = [i.next() for i in iterables] ! yield f(*args) \end{verbatim} \end{funcdesc} --- 116,123 ---- \begin{verbatim} def imap(func, *iterables): ! iterables = map(iter, iterables) while True: ! args = [i.next() for i in iterables] ! yield f(*args) \end{verbatim} \end{funcdesc} *************** *** 135,144 **** \begin{verbatim} def loopzip(*iterables): ! iterables = map(iter, iterables) ! result = [None] * len(iterables) while True: ! for i in xrange(len(iterables)): ! result[i] = iterable[i].next() ! yield result \end{verbatim} \end{funcdesc} --- 135,144 ---- \begin{verbatim} def loopzip(*iterables): ! iterables = map(iter, iterables) ! result = [None] * len(iterables) while True: ! for i in xrange(len(iterables)): ! result[i] = iterable[i].next() ! yield result \end{verbatim} \end{funcdesc} *************** *** 156,159 **** --- 156,171 ---- \end{funcdesc} + \begin{funcdesc}{starmap}{func, iterable} + Make an iterator that computes the function using arguments tuples + obtained from the iterable. Equivalent to: + + \begin{verbatim} + def stapmap(func, iterable): + iterable = iter(iterable) + while True: + yield func(*iterable.next()) + \end{verbatim} + \end{funcdesc} + \begin{funcdesc}{times}{n} Make an iterator that returns None \var{n} times. *************** *** 194,198 **** ... print list(imap(operator.pow, bases, repeat(power))) ... ! \end{verbatim} As a further example of how itertools can be combined, here --- 206,210 ---- ... print list(imap(operator.pow, bases, repeat(power))) ... ! \end{verbatim} As a further example of how itertools can be combined, here Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_itertools.py 27 Jan 2003 04:24:14 -0000 1.2 --- test_itertools.py 27 Jan 2003 05:24:40 -0000 1.3 *************** *** 30,34 **** self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), [0**1, 1**2, 2**3]) ! def test_main(): suite = unittest.TestSuite() --- 30,40 ---- self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), [0**1, 1**2, 2**3]) ! ! def test_starmap(self): ! import operator ! self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))), ! [0**1, 1**2, 2**3]) ! ! def test_main(): suite = unittest.TestSuite() Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** todo.txt 27 Jan 2003 04:24:14 -0000 1.4 --- todo.txt 27 Jan 2003 05:24:40 -0000 1.5 *************** *** 2,6 **** islice(iterator, start, stop, step) iapply - starmap() takewhile(pred, seqn) dropwhile(pred, seqn) --- 2,5 ---- From rhettinger@users.sourceforge.net Mon Jan 27 10:03:13 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 02:03:13 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.4,1.5 libitertools.tex,1.5,1.6 test_itertools.py,1.3,1.4 todo.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv3903 Modified Files: itertools.c libitertools.tex test_itertools.py todo.txt Log Message: Added islice() and stronger error checking. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** itertools.c 27 Jan 2003 05:24:40 -0000 1.4 --- itertools.c 27 Jan 2003 10:02:59 -0000 1.5 *************** *** 2,5 **** --- 2,170 ---- #include "Python.h" + /* islice object ************************************************************/ + + typedef struct { + PyObject_HEAD + PyObject *it; + long next; + long stop; + long step; + long cnt; + } isliceobject; + + PyTypeObject islice_type; + + static PyObject * + islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *seq; + long a1=0, a2=0, a3=0, start=0, stop=0, step=1; + PyObject *it; + int numargs; + isliceobject *lz; + + numargs = PyTuple_Size(args); + if (!PyArg_ParseTuple(args, "Ol|ll:islice", &seq, &a1, &a2, &a3)) + return NULL; + + if (numargs == 2) { + stop = a1; + } else if (numargs == 3) { + start = a1; + stop = a2; + } else { + start = a1; + stop = a2; + step = a3; + } + + if (start<0 || stop<0) { + PyErr_SetString(PyExc_ValueError, + "Indices for islice() must be positive."); + return NULL; + } + + if (step<1) { + PyErr_SetString(PyExc_ValueError, + "Step must be one or larger for islice()."); + return NULL; + } + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create isliceobject structure */ + lz = (isliceobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + lz->it = it; + lz->next = start; + lz->stop = stop; + lz->step = step; + lz->cnt = 0L; + + return (PyObject *)lz; + } + + static void + islice_dealloc(isliceobject *lz) + { + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->it); + lz->ob_type->tp_free(lz); + } + + static int + islice_traverse(isliceobject *lz, visitproc visit, void *arg) + { + if (lz->it) + return visit(lz->it, arg); + return 0; + } + + static PyObject * + islice_next(isliceobject *lz) + { + PyObject *item; + + while (lz->cnt < lz->next) { + item = PyIter_Next(lz->it); + if (item == NULL) + return NULL; + Py_DECREF(item); + lz->cnt++; + } + if (lz->stop != 0 && lz->cnt >= lz->stop) + return NULL; + item = PyIter_Next(lz->it); + if (item == NULL) + return NULL; + lz->cnt += 1; + lz->next += lz->step; + return item; + } + + static PyObject * + islice_getiter(PyObject *lz) + { + Py_INCREF(lz); + return lz; + } + + PyDoc_STRVAR(islice_doc, + "islice(function, sequence) --> islice object\n\ + \n\ + Return an iterator whose values are returned from the function evaluated\n\ + with a argument tuple taken from the given sequence."); + + PyTypeObject islice_type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "itertools.islice", /* tp_name */ + sizeof(isliceobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)islice_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + islice_doc, /* tp_doc */ + (traverseproc)islice_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)islice_getiter, /* tp_iter */ + (iternextfunc)islice_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + islice_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + }; + /* starmap object ************************************************************/ *************** *** 150,155 **** numargs = PyTuple_Size(args); ! if (numargs == 0) { ! // XXX raise Err for not having a function arg return NULL; } --- 315,321 ---- numargs = PyTuple_Size(args); ! if (numargs < 2) { ! PyErr_SetString(PyExc_TypeError, ! "imap() must have at least two arguments."); return NULL; } *************** *** 305,308 **** --- 471,480 ---- return NULL; + if (cnt < 0) { + PyErr_SetString(PyExc_ValueError, + "count for imap() cannot be negative."); + return NULL; + } + /* create timesobject structure */ lz = (timesobject *)PyObject_New(timesobject, ×_type); *************** *** 933,936 **** --- 1105,1113 ---- PyObject *m; m = Py_InitModule3("itertools", NULL, module_doc); + + PyModule_AddObject(m, "islice", (PyObject *)&islice_type); + if (PyType_Ready(&islice_type) < 0) + return; + Py_INCREF(&islice_type); PyModule_AddObject(m, "starmap", (PyObject *)&starmap_type); Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** libitertools.tex 27 Jan 2003 05:24:40 -0000 1.5 --- libitertools.tex 27 Jan 2003 10:03:04 -0000 1.6 *************** *** 123,126 **** --- 123,148 ---- \end{funcdesc} + \begin{funcdesc}{islice}{iterable, \optional{start,} stop \optional{, step}} + Make an iterator that returns selected elements from the iterable. + If \var{start} is non-zero, then elements from the iterable are skiped + until start is reached. Afterward, elements are returned consecutively + unless \var{step} is set higher than one which results in items being + skipped. If \var{stop} is specified, then iteration stops at the + specified element position; otherwise, it continues indefinitely or + until the iterable is exhausted. Unlike regular slicing, + \function{islice()} does not support negative values for \var{start}, + \var{stop}, or \var{step}. Equivalent to: + + \begin{verbatim} + def islice(func, iterable, *args): + i = 0 + for j in xrange(*args): + while i != j: + _ = iterable.next() + i += 1 + yield iterable.next() + \end{verbatim} + \end{funcdesc} + \begin{funcdesc}{loopzip}{*iterables} Make an iterator that aggregates elements from each of the iterables. *************** *** 170,175 **** \begin{funcdesc}{times}{n} Make an iterator that returns None \var{n} times. ! Used for looping a specific number of times without creating a number object ! on each pass. Equivalent to: \begin{verbatim} --- 192,197 ---- \begin{funcdesc}{times}{n} Make an iterator that returns None \var{n} times. ! Used for looping a specific number of times without creating a number ! object on each pass. Equivalent to: \begin{verbatim} Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_itertools.py 27 Jan 2003 05:24:40 -0000 1.3 --- test_itertools.py 27 Jan 2003 10:03:06 -0000 1.4 *************** *** 7,10 **** --- 7,11 ---- self.assertEqual(zip('abc',count()), [('a', 0), ('b', 1), ('c', 2)]) self.assertEqual(zip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)]) + self.assertRaises(TypeError, count, 2, 3) def test_ifilter(self): *************** *** 13,16 **** --- 14,21 ---- self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4]) self.assertEqual(list(ifilter(isEven, range(6), True)), [1,3,5]) + self.assertRaises(TypeError, ifilter) + self.assertRaises(TypeError, ifilter, 3) + self.assertRaises(TypeError, ifilter, isEven, 3) + self.assertRaises(TypeError, ifilter, isEven, [3], True, 4) def test_loopzip(self): *************** *** 18,28 **** --- 23,36 ---- self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) self.assertEqual(list(loopzip('abc',count())), [['c', 2]] * 3) + self.assertRaises(TypeError, loopzip) def test_repeat(self): self.assertEqual(zip(xrange(3),repeat('a')), [(0, 'a'), (1, 'a'), (2, 'a')]) + self.assertRaises(TypeError, repeat) def test_times(self): self.assertEqual(list(times(3)), [None]*3) + self.assertRaises(ValueError, times, -1) def test_imap(self): *************** *** 30,33 **** --- 38,43 ---- self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), [0**1, 1**2, 2**3]) + self.assertRaises(TypeError, imap) + self.assertRaises(TypeError, imap, operator.neg) def test_starmap(self): *************** *** 36,39 **** --- 46,73 ---- [0**1, 1**2, 2**3]) + def test_islice(self): + for args in [ # islice(args) should agree with range(args) + (10, 20, 3), + (10, 3, 20), + (10, 20), + (10, 3), + (20,) + ]: + self.assertEqual(list(islice(xrange(100), *args)), range(*args)) + + for args, tgtargs in [ # Stop when seqn is exhausted + ((10, 110, 3), ((10, 100, 3))), + ((10, 110), ((10, 100))), + ((110,), (100,)) + ]: + self.assertEqual(list(islice(xrange(100), *args)), range(*tgtargs)) + + + self.assertRaises(TypeError, islice, xrange(10)) + self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4) + self.assertRaises(ValueError, islice, xrange(10), -5, 10, 1) + self.assertRaises(ValueError, islice, xrange(10), 1, -5, -1) + self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1) + self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0) def test_main(): Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** todo.txt 27 Jan 2003 05:24:40 -0000 1.5 --- todo.txt 27 Jan 2003 10:03:07 -0000 1.6 *************** *** 1,5 **** Add: ! islice(iterator, start, stop, step) ! iapply takewhile(pred, seqn) dropwhile(pred, seqn) --- 1,4 ---- Add: ! iapply(func) ?? what did this do in SML takewhile(pred, seqn) dropwhile(pred, seqn) *************** *** 9,14 **** refcounts - Things dropped because they bug me: cycle(seqn) requires auxilliary storage (which is surprising behavior for iterators). This is best left for pure python. --- 8,16 ---- refcounts Things dropped because they bug me: cycle(seqn) requires auxilliary storage (which is surprising behavior for iterators). This is best left for pure python. + + Things that just bug me: + islice is supposed to looklike i-slice but can be read as is-lice + From rhettinger@users.sourceforge.net Mon Jan 27 10:44:54 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 02:44:54 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.5,1.6 libitertools.tex,1.6,1.7 todo.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv21061 Modified Files: itertools.c libitertools.tex todo.txt Log Message: Fixed whitespace in C code to unformly use tabs. Cited research references in the documentation. Updated todo list. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** itertools.c 27 Jan 2003 10:02:59 -0000 1.5 --- itertools.c 27 Jan 2003 10:44:52 -0000 1.6 *************** *** 74,80 **** islice_dealloc(isliceobject *lz) { ! PyObject_GC_UnTrack(lz); ! Py_XDECREF(lz->it); ! lz->ob_type->tp_free(lz); } --- 74,80 ---- islice_dealloc(isliceobject *lz) { [...1879 lines suppressed...] ! if (PyType_Ready(&ifilter_type) < 0) ! return; ! Py_INCREF(&ifilter_type); ! PyModule_AddObject(m, "ifilter", (PyObject *)&ifilter_type); ! if (PyType_Ready(&count_type) < 0) ! return; ! Py_INCREF(&count_type); ! PyModule_AddObject(m, "count", (PyObject *)&count_type); ! if (PyType_Ready(&loopzip_type) < 0) ! return; ! Py_INCREF(&loopzip_type); ! PyModule_AddObject(m, "loopzip", (PyObject *)&loopzip_type); ! if (PyType_Ready(&repeat_type) < 0) ! return; ! Py_INCREF(&repeat_type); ! PyModule_AddObject(m, "repeat", (PyObject *)&repeat_type); } Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** libitertools.tex 27 Jan 2003 10:03:04 -0000 1.6 --- libitertools.tex 27 Jan 2003 10:44:52 -0000 1.7 *************** *** 13,18 **** With the advent of iterators and generators in Python 2.3, each of these tools can be expressed easily and succinctly in pure python. ! Rather duplicating what can already be done, this module takes the ! slightly unnatural approach of providing value in other ways: \begin{itemize} --- 13,18 ---- With the advent of iterators and generators in Python 2.3, each of these tools can be expressed easily and succinctly in pure python. ! Rather duplicating what can already be done, this module emphasizes ! providing value in other ways: \begin{itemize} *************** *** 72,78 **** --- 72,91 ---- \end{itemize} + \begin{seealso} + \seetext{The Standard ML Basis Library, + \citetitle[http://www.standardml.org/Basis/] + {The Standard ML Basis Library}.} + + \seetext{Haskell, A Purely Functional Language, + \citetitle[http://www.haskell.org/definition/] + {Definition of Haskell and the Standard Libraries}.} + \end{seealso} + \subsection{Itertool functions \label{itertools-functions}} + The following module functions all construct and return iterators. + Some provide streams of infinite length, so they should only be accessed + by functions or loops that truncate the stream. \begin{funcdesc}{count}{\optional{n}} Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** todo.txt 27 Jan 2003 10:03:07 -0000 1.6 --- todo.txt 27 Jan 2003 10:44:52 -0000 1.7 *************** *** 3,10 **** --- 3,14 ---- takewhile(pred, seqn) dropwhile(pred, seqn) + unzip(seqn) ?? does this make sense for iterators + exists() and any() ?? do these make sense + Verify: proper GC refcounts + subclassability Things dropped because they bug me: From rhettinger@users.sourceforge.net Mon Jan 27 11:17:48 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 03:17:48 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.6,1.7 test_itertools.py,1.4,1.5 todo.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv1395 Modified Files: itertools.c test_itertools.py todo.txt Log Message: Added takewhile(). Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** itertools.c 27 Jan 2003 10:44:52 -0000 1.6 --- itertools.c 27 Jan 2003 11:17:45 -0000 1.7 *************** *** 2,5 **** --- 2,147 ---- #include "Python.h" + /* takewhile object ************************************************************/ + + typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; + long stop; + } takewhileobject; + + PyTypeObject takewhile_type; + + static PyObject * + takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *func, *seq; + PyObject *it; + takewhileobject *lz; + + if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq)) + return NULL; + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create takewhileobject structure */ + lz = (takewhileobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + Py_INCREF(func); + lz->func = func; + lz->it = it; + lz->stop = 0; + + return (PyObject *)lz; + } + + static void + takewhile_dealloc(takewhileobject *lz) + { + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->func); + Py_XDECREF(lz->it); + lz->ob_type->tp_free(lz); + } + + static int + takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) + { + if (lz->it) + return visit(lz->it, arg); + return 0; + } + + static PyObject * + takewhile_next(takewhileobject *lz) + { + PyObject *item, *good; + long ok; + + if (lz->stop == 1) + return NULL; + + item = PyIter_Next(lz->it); + if (item == NULL) + return NULL; + + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); + if (good == NULL) { + Py_DECREF(item); + return NULL; + } + ok = PyObject_IsTrue(good); + Py_DECREF(good); + if (ok) + return item; + Py_DECREF(item); + lz->stop = 1; + return NULL; + } + + static PyObject * + takewhile_getiter(PyObject *lz) + { + Py_INCREF(lz); + return lz; + } + + PyDoc_STRVAR(takewhile_doc, + "takewhile(predicate, sequence) --> takewhile object\n\ + \n\ + Return those items of sequence while the predicate is true."); + + PyTypeObject takewhile_type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "itertools.takewhile", /* tp_name */ + sizeof(takewhileobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)takewhile_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + takewhile_doc, /* tp_doc */ + (traverseproc)takewhile_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)takewhile_getiter, /* tp_iter */ + (iternextfunc)takewhile_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + takewhile_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + }; + + /* islice object ************************************************************/ *************** *** 1085,1089 **** Infinite iterators:\n\ count([n]) --> n, n+1, n+2, ...\n\ - cycle(seq) --> seq0, seq1, ... seqlast, seq0, ...\n\ repeat(elem) --> elem, elem, elem, elem\n\ \n\ --- 1227,1230 ---- *************** *** 1097,1100 **** --- 1238,1243 ---- imap(fun, p, q) --> fun(p0, q0), fun(p1, q1), ...\n\ starmap(fun, s) --> fun(*s[0]), fun(*s[1]), ...\n\ + times(n) --> None, None, ... for n times.\n\ + takewhile(pred, seq) --> s[0], s[1], until pred fails\n\ "); *************** *** 1105,1108 **** --- 1248,1256 ---- PyObject *m; m = Py_InitModule3("itertools", NULL, module_doc); + + PyModule_AddObject(m, "takewhile", (PyObject *)&takewhile_type); + if (PyType_Ready(&takewhile_type) < 0) + return; + Py_INCREF(&takewhile_type); PyModule_AddObject(m, "islice", (PyObject *)&islice_type); Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_itertools.py 27 Jan 2003 10:03:06 -0000 1.4 --- test_itertools.py 27 Jan 2003 11:17:45 -0000 1.5 *************** *** 63,67 **** self.assertEqual(list(islice(xrange(100), *args)), range(*tgtargs)) - self.assertRaises(TypeError, islice, xrange(10)) self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4) --- 63,66 ---- *************** *** 70,73 **** --- 69,82 ---- self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1) self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0) + + def test_takewhile(self): + data = [1, 3, 5, 20, 2, 4, 6, 8] + underten = lambda x: x<10 + self.assertEqual(list(takewhile(underten, data)), [1, 3, 5]) + + ## def test_dropwhile(self): + ## data = [1, 3, 5, 20, 2, 4, 6, 8] + ## underten = lambda x: x<10 + ## self.assertEqual(list(takewhile(underten, data)), [20, 2, 4, 6, 8]) def test_main(): Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** todo.txt 27 Jan 2003 10:44:52 -0000 1.7 --- todo.txt 27 Jan 2003 11:17:45 -0000 1.8 *************** *** 1,8 **** Add: iapply(func) ?? what did this do in SML - takewhile(pred, seqn) dropwhile(pred, seqn) unzip(seqn) ?? does this make sense for iterators ! exists() and any() ?? do these make sense --- 1,7 ---- Add: iapply(func) ?? what did this do in SML dropwhile(pred, seqn) unzip(seqn) ?? does this make sense for iterators ! exists() and any() ?? these don't return iterators From loewis@users.sourceforge.net Mon Jan 27 11:28:54 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon, 27 Jan 2003 03:28:54 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_iconv_codecs.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv5784 Added Files: test_iconv_codecs.py Log Message: Patch #670715: Universal Unicode Codec for POSIX iconv. --- NEW FILE: test_iconv_codecs.py --- from test import test_support import unittest, sys import codecs, _iconv_codec from encodings import iconv_codec from StringIO import StringIO class IconvCodecTest(unittest.TestCase): if sys.byteorder == 'big': spam = '\x00s\x00p\x00a\x00m\x00s\x00p\x00a\x00m' else: spam = 's\x00p\x00a\x00m\x00s\x00p\x00a\x00m\x00' def test_sane(self): self.encoder, self.decoder, self.reader, self.writer = \ codecs.lookup(_iconv_codec.internal_encoding) self.assertEqual(self.decoder(self.spam), (u'spamspam', 16)) self.assertEqual(self.encoder(u'spamspam'), (self.spam, 8)) self.assertEqual(self.reader(StringIO(self.spam)).read(), u'spamspam') f = StringIO() self.writer(f).write(u'spamspam') self.assertEqual(f.getvalue(), self.spam) def test_basic_errors(self): self.encoder, self.decoder, self.reader, self.writer = \ iconv_codec.lookup("ascii") def testencerror(errors): return self.encoder(u'sp\ufffdam', errors) def testdecerror(errors): return self.decoder('sp\xffam', errors) self.assertRaises(UnicodeEncodeError, testencerror, 'strict') self.assertRaises(UnicodeDecodeError, testdecerror, 'strict') self.assertEqual(testencerror('replace'), ('sp?am', 5)) self.assertEqual(testdecerror('replace'), (u'sp\ufffdam', 5)) self.assertEqual(testencerror('ignore'), ('spam', 5)) self.assertEqual(testdecerror('ignore'), (u'spam', 5)) def test_pep293_errors(self): self.encoder, self.decoder, self.reader, self.writer = \ iconv_codec.lookup("ascii") def testencerror(errors): return self.encoder(u'sp\ufffdam', errors) def testdecerror(errors): return self.decoder('sp\xffam', errors) self.assertEqual(testencerror('xmlcharrefreplace'), ('sp�am', 5)) self.assertEqual(testencerror('backslashreplace'), ('sp\\ufffdam', 5)) def error_bomb(exc): return (u'*'*40, len(exc.object)) def error_mock(exc): error_mock.lastexc = exc return (unicode(exc.object[exc.start - 1]), exc.end) codecs.register_error('test_iconv_codec.bomb', error_bomb) codecs.register_error('test_iconv_codec.mock', error_mock) self.assertEqual(testencerror('test_iconv_codec.bomb'), ('sp' + ('*'*40), 5)) self.assertEqual(testdecerror('test_iconv_codec.bomb'), (u'sp' + (u'*'*40), 5)) self.assertEqual(testencerror('test_iconv_codec.mock'), ('sppam', 5)) exc = error_mock.lastexc self.assertEqual(exc.object, u'sp\ufffdam') self.assertEqual(exc.start, 2) self.assertEqual(exc.end, 3) self.assert_(isinstance(exc, UnicodeEncodeError)) self.assertEqual(testdecerror('test_iconv_codec.mock'), (u'sppam', 5)) exc = error_mock.lastexc self.assertEqual(exc.object, 'sp\xffam') self.assertEqual(exc.start, 2) self.assertEqual(exc.end, 3) self.assert_(isinstance(exc, UnicodeDecodeError)) def test_empty_escape_decode(self): self.encoder, self.decoder, self.reader, self.writer = \ iconv_codec.lookup("ascii") self.assertEquals(self.decoder(u""), ("", 0)) self.assertEquals(self.encoder(""), (u"", 0)) def test_main(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(IconvCodecTest)) test_support.run_suite(suite) if __name__ == "__main__": test_main() # ex: ts=8 sts=4 et From loewis@users.sourceforge.net Mon Jan 27 11:39:06 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon, 27 Jan 2003 03:39:06 -0800 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv10728 Modified Files: _iconv_codec.c Log Message: Fix reference counting of iconvcodec_Type. Fixes #670715. Remove GC code; the base type does not need GC. Index: _iconv_codec.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _iconv_codec.c 26 Jan 2003 16:26:20 -0000 1.3 --- _iconv_codec.c 27 Jan 2003 11:39:04 -0000 1.4 *************** *** 534,539 **** iconvcodec_dealloc(iconvcodecObject *self) { - _PyObject_GC_UNTRACK(self); - if (self->enchdl != (iconv_t)-1) iconv_close(self->enchdl); --- 534,537 ---- *************** *** 543,547 **** PyMem_Free(self->encoding); ! PyObject_GC_Del(self); } --- 541,545 ---- PyMem_Free(self->encoding); ! self->ob_type->tp_free((PyObject *)self); } *************** *** 574,579 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | ! Py_TPFLAGS_HAVE_GC, /* tp_flags */ iconvcodec_doc, /* tp_doc */ 0, /* tp_traverse */ --- 572,576 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ iconvcodec_doc, /* tp_doc */ 0, /* tp_traverse */ *************** *** 594,598 **** PyType_GenericAlloc, /* tp_alloc */ iconvcodec_new, /* tp_new */ ! PyObject_GC_Del, /* tp_free */ }; --- 591,595 ---- PyType_GenericAlloc, /* tp_alloc */ iconvcodec_new, /* tp_new */ ! PyObject_Del, /* tp_free */ }; *************** *** 609,612 **** --- 606,610 ---- PyModule_AddStringConstant(m, "__version__", (char*)__version__); + Py_INCREF(&iconvcodec_Type); PyModule_AddObject(m, "iconvcodec", (PyObject *)(&iconvcodec_Type)); PyModule_AddStringConstant(m, "internal_encoding", UNICODE_ENCODING); From rhettinger@users.sourceforge.net Mon Jan 27 12:16:45 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 04:16:45 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools NEWS,NONE,1.1 itertools.c,1.7,1.8 libitertools.tex,1.7,1.8 test_itertools.py,1.5,1.6 todo.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv26261 Modified Files: itertools.c libitertools.tex test_itertools.py todo.txt Added Files: NEWS Log Message: Add dropwhile(). --- NEW FILE: NEWS --- - Added an itertools module containing high speed looping constructs inspired by tools in Haskell and SML. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** itertools.c 27 Jan 2003 11:17:45 -0000 1.7 --- itertools.c 27 Jan 2003 12:16:42 -0000 1.8 *************** *** 2,5 **** --- 2,150 ---- #include "Python.h" + /* dropwhile object ************************************************************/ + + typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; + long start; + } dropwhileobject; + + PyTypeObject dropwhile_type; + + static PyObject * + dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *func, *seq; + PyObject *it; + dropwhileobject *lz; + + if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq)) + return NULL; + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create dropwhileobject structure */ + lz = (dropwhileobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + Py_INCREF(func); + lz->func = func; + lz->it = it; + lz->start = 0; + + return (PyObject *)lz; + } + + static void + dropwhile_dealloc(dropwhileobject *lz) + { + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->func); + Py_XDECREF(lz->it); + lz->ob_type->tp_free(lz); + } + + static int + dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) + { + if (lz->it) + return visit(lz->it, arg); + return 0; + } + + static PyObject * + dropwhile_next(dropwhileobject *lz) + { + PyObject *item, *good; + long ok; + + for (;;) { + item = PyIter_Next(lz->it); + if (item == NULL) + return NULL; + if (lz->start == 1) + return item; + + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); + if (good == NULL) { + printf("R"); + Py_DECREF(item); + return NULL; + } + ok = PyObject_IsTrue(good); + Py_DECREF(good); + if (!ok) { + lz->start = 1; + return item; + } + Py_DECREF(item); + } + } + + static PyObject * + dropwhile_getiter(PyObject *lz) + { + Py_INCREF(lz); + return lz; + } + + PyDoc_STRVAR(dropwhile_doc, + "dropwhile(predicate, iterable) --> dropwhile object\n\ + \n\ + Drop items from the iterable while predicate(item) is true.\n\ + Afterwards, return every element until the iterable is exhausted."); + + PyTypeObject dropwhile_type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "itertools.dropwhile", /* tp_name */ + sizeof(dropwhileobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dropwhile_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + dropwhile_doc, /* tp_doc */ + (traverseproc)dropwhile_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)dropwhile_getiter, /* tp_iter */ + (iternextfunc)dropwhile_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + dropwhile_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + }; + + /* takewhile object ************************************************************/ *************** *** 1233,1243 **** same list each time but with updated contents\n\ ifilter(pred, seq, invert=False) --> elements of seq where\n\ ! pred(elem) is True (or False invert is set)\n\ ! islice(seq, start, stop, step) --> elements from\n\ seq[start:stop:step]\n\ ! imap(fun, p, q) --> fun(p0, q0), fun(p1, q1), ...\n\ starmap(fun, s) --> fun(*s[0]), fun(*s[1]), ...\n\ times(n) --> None, None, ... for n times.\n\ takewhile(pred, seq) --> s[0], s[1], until pred fails\n\ "); --- 1378,1389 ---- same list each time but with updated contents\n\ ifilter(pred, seq, invert=False) --> elements of seq where\n\ ! pred(elem) is True (or False if invert is set)\n\ ! islice(seq, [start,] stop [, step]) --> elements from\n\ seq[start:stop:step]\n\ ! imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\ starmap(fun, s) --> fun(*s[0]), fun(*s[1]), ...\n\ times(n) --> None, None, ... for n times.\n\ takewhile(pred, seq) --> s[0], s[1], until pred fails\n\ + dropwhile(pred, seq) --> s[n], s[n+1], starting when pred fails\n\ "); *************** *** 1248,1251 **** --- 1394,1402 ---- PyObject *m; m = Py_InitModule3("itertools", NULL, module_doc); + + PyModule_AddObject(m, "dropwhile", (PyObject *)&dropwhile_type); + if (PyType_Ready(&dropwhile_type) < 0) + return; + Py_INCREF(&dropwhile_type); PyModule_AddObject(m, "takewhile", (PyObject *)&takewhile_type); Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** libitertools.tex 27 Jan 2003 10:44:52 -0000 1.7 --- libitertools.tex 27 Jan 2003 12:16:42 -0000 1.8 *************** *** 74,83 **** \begin{seealso} \seetext{The Standard ML Basis Library, ! \citetitle[http://www.standardml.org/Basis/] ! {The Standard ML Basis Library}.} \seetext{Haskell, A Purely Functional Language, \citetitle[http://www.haskell.org/definition/] ! {Definition of Haskell and the Standard Libraries}.} \end{seealso} --- 74,83 ---- \begin{seealso} \seetext{The Standard ML Basis Library, ! \citetitle[http://www.standardml.org/Basis/] ! {The Standard ML Basis Library}.} \seetext{Haskell, A Purely Functional Language, \citetitle[http://www.haskell.org/definition/] ! {Definition of Haskell and the Standard Libraries}.} \end{seealso} *************** *** 102,105 **** --- 102,123 ---- \end{funcdesc} + \begin{funcdesc}{dropwhile}{predicate, iterable} + Make an iterator that drops elements from the iterable as long as + the predicate is true; afterwards, returns every element. + Equivalent to: + + \begin{verbatim} + def dropwhile(func, iterable, invert=False): + iterable = iter(iterable) + while True: + x = iterable.next() + if not predicate(x): + yield x + break + while True: + yield iterable.next() + \end{verbatim} + \end{funcdesc} + \begin{funcdesc}{ifilter}{func, iterable \optional{, invert}} Make an iterator that filters elements from iterable returning only *************** *** 200,203 **** --- 218,237 ---- while True: yield func(*iterable.next()) + \end{verbatim} + \end{funcdesc} + + \begin{funcdesc}{takewhile}{predicate, iterable} + Make an iterator that returns elements from the iterable as long as + the predicate is true. Equivalent to: + + \begin{verbatim} + def takewhile(func, iterable, invert=False): + iterable = iter(iterable) + while True: + x = iterable.next() + if predicate(x): + yield x + else: + break \end{verbatim} \end{funcdesc} Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_itertools.py 27 Jan 2003 11:17:45 -0000 1.5 --- test_itertools.py 27 Jan 2003 12:16:42 -0000 1.6 *************** *** 75,82 **** self.assertEqual(list(takewhile(underten, data)), [1, 3, 5]) ! ## def test_dropwhile(self): ! ## data = [1, 3, 5, 20, 2, 4, 6, 8] ! ## underten = lambda x: x<10 ! ## self.assertEqual(list(takewhile(underten, data)), [20, 2, 4, 6, 8]) def test_main(): --- 75,82 ---- self.assertEqual(list(takewhile(underten, data)), [1, 3, 5]) ! def test_dropwhile(self): ! data = [1, 3, 5, 20, 2, 4, 6, 8] ! underten = lambda x: x<10 ! self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8]) def test_main(): Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** todo.txt 27 Jan 2003 11:17:45 -0000 1.8 --- todo.txt 27 Jan 2003 12:16:42 -0000 1.9 *************** *** 1,5 **** Add: iapply(func) ?? what did this do in SML - dropwhile(pred, seqn) unzip(seqn) ?? does this make sense for iterators exists() and any() ?? these don't return iterators --- 1,4 ---- *************** *** 16,19 **** Things that just bug me: ! islice is supposed to looklike i-slice but can be read as is-lice --- 15,18 ---- Things that just bug me: ! islice is supposed to sound like i-slice but can be read as is-lice From walter@livinglogic.de Mon Jan 27 12:49:34 2003 From: walter@livinglogic.de (=?ISO-8859-15?Q?Walter_D=F6rwald?=) Date: Mon, 27 Jan 2003 13:49:34 +0100 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 In-Reply-To: References: Message-ID: <3E352ADE.3090908@livinglogic.de> loewis@users.sourceforge.net wrote: > Update of /cvsroot/python/python/dist/src/Modules > In directory sc8-pr-cvs1:/tmp/cvs-serv2026/Modules > > Added Files: > _iconv_codec.c > Log Message: > Patch #670715: Universal Unicode Codec for POSIX iconv. > [...] > > newpos = PyInt_AS_LONG(PyTuple_GET_ITEM(retobj, 1)); > Py_DECREF(retobj); > > if (newpos < 0) > newpos = inputlen - newpos; This interprets negative indizes as being relative to the end of the input. All other encoders treat <0 as ==0. Bye, Walter Dörwald From montanaro@users.sourceforge.net Mon Jan 27 14:26:52 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 27 Jan 2003 06:26:52 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv30661 Modified Files: pickletools.py Log Message: typo Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** pickletools.py 27 Jan 2003 02:49:40 -0000 1.30 --- pickletools.py 27 Jan 2003 14:26:48 -0000 1.31 *************** *** 1210,1214 **** """), ! # Puah a class object, or module function, on the stack, via its module # and name. --- 1210,1214 ---- """), ! # Push a class object, or module function, on the stack, via its module # and name. From montanaro@users.sourceforge.net Mon Jan 27 15:00:43 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 27 Jan 2003 07:00:43 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libhttplib.tex,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv21074 Modified Files: libhttplib.tex Log Message: * add \versionadded{} strings as appropriate * remove doc for defunct IllegalKeywordArgument exception * add note that HTTP class is for backward compatibility and refer reader to online docstrings for help Index: libhttplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libhttplib.tex,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** libhttplib.tex 24 Mar 2002 16:55:57 -0000 1.31 --- libhttplib.tex 27 Jan 2003 15:00:38 -0000 1.32 *************** *** 13,17 **** that use HTTP and HTTPS. \note{HTTPS support is only available if the \refmodule{socket} module was compiled with SSL ! support.} The constants defined in this module are: --- 13,19 ---- that use HTTP and HTTPS. \note{HTTPS support is only available if the \refmodule{socket} module was compiled with SSL ! support.} \note{The \class{HTTP} class is retained only for backward ! compatibility with 1.5.2. It should not be used in new code. Refer to the ! online docstrings for usage.} The constants defined in this module are: *************** *** 40,43 **** --- 42,46 ---- >>> h3 = httplib.HTTPConnection('www.cwi.nl', 80) \end{verbatim} + \versionadded{2.0} \end{classdesc} *************** *** 45,48 **** --- 48,58 ---- A subclass of \class{HTTPConnection} that uses SSL for communication with secure servers. Default port is \code{443}. + \versionadded{2.0} + \end{classdesc} + + \begin{classdesc}{HTTPResponse}{sock\optional{, debuglevel=0}\optional{, strict=0}} + Class whose instances are returned upon successful connection. Not + instantiated directly by user. + \versionadded{2.0} \end{classdesc} *************** *** 52,59 **** --- 62,71 ---- The base class of the other exceptions in this module. It is a subclass of \exception{Exception}. + \versionadded{2.0} \end{excdesc} \begin{excdesc}{NotConnected} A subclass of \exception{HTTPException}. + \versionadded{2.0} \end{excdesc} *************** *** 61,100 **** A subclass of \exception{HTTPException}, raised if a port is given and is either non-numeric or empty. \end{excdesc} \begin{excdesc}{UnknownProtocol} A subclass of \exception{HTTPException}. \end{excdesc} \begin{excdesc}{UnknownTransferEncoding} A subclass of \exception{HTTPException}. ! \end{excdesc} ! ! \begin{excdesc}{IllegalKeywordArgument} ! A subclass of \exception{HTTPException}. \end{excdesc} \begin{excdesc}{UnimplementedFileMode} A subclass of \exception{HTTPException}. \end{excdesc} \begin{excdesc}{IncompleteRead} A subclass of \exception{HTTPException}. \end{excdesc} \begin{excdesc}{ImproperConnectionState} A subclass of \exception{HTTPException}. \end{excdesc} \begin{excdesc}{CannotSendRequest} A subclass of \exception{ImproperConnectionState}. \end{excdesc} \begin{excdesc}{CannotSendHeader} A subclass of \exception{ImproperConnectionState}. \end{excdesc} \begin{excdesc}{ResponseNotReady} A subclass of \exception{ImproperConnectionState}. \end{excdesc} --- 73,117 ---- A subclass of \exception{HTTPException}, raised if a port is given and is either non-numeric or empty. + \versionadded{2.3} \end{excdesc} \begin{excdesc}{UnknownProtocol} A subclass of \exception{HTTPException}. + \versionadded{2.0} \end{excdesc} \begin{excdesc}{UnknownTransferEncoding} A subclass of \exception{HTTPException}. ! \versionadded{2.0} \end{excdesc} \begin{excdesc}{UnimplementedFileMode} A subclass of \exception{HTTPException}. + \versionadded{2.0} \end{excdesc} \begin{excdesc}{IncompleteRead} A subclass of \exception{HTTPException}. + \versionadded{2.0} \end{excdesc} \begin{excdesc}{ImproperConnectionState} A subclass of \exception{HTTPException}. + \versionadded{2.0} \end{excdesc} \begin{excdesc}{CannotSendRequest} A subclass of \exception{ImproperConnectionState}. + \versionadded{2.0} \end{excdesc} \begin{excdesc}{CannotSendHeader} A subclass of \exception{ImproperConnectionState}. + \versionadded{2.0} \end{excdesc} \begin{excdesc}{ResponseNotReady} A subclass of \exception{ImproperConnectionState}. + \versionadded{2.0} \end{excdesc} *************** *** 102,105 **** --- 119,123 ---- A subclass of \exception{HTTPException}. Raised if a server responds with a HTTP status code that we don't understand. + \versionadded{2.0} \end{excdesc} From jackjansen@users.sourceforge.net Mon Jan 27 15:21:47 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 27 Jan 2003 07:21:47 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.627,1.628 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv822 Modified Files: NEWS Log Message: Attempting to keep the Mac section of the NEWS file up-to-date, in stead of the usual frantic editing at the last moment:-) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.627 retrieving revision 1.628 diff -C2 -d -r1.627 -r1.628 *** NEWS 26 Jan 2003 11:27:16 -0000 1.627 --- NEWS 27 Jan 2003 15:21:39 -0000 1.628 *************** *** 213,217 **** --- ! TBD --- 213,221 ---- --- ! - There are new dialogs EasyDialogs.AskFileForOpen, AskFileForSave ! and AskFolder. The old macfs.StandardGetFile and friends are deprecated. ! ! - Type Carbon.File.FSCatalogInfo and supporting methods have been implemented. ! This also makes macfs.FSSpec.SetDates() work again. From montanaro@users.sourceforge.net Mon Jan 27 15:23:05 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 27 Jan 2003 07:23:05 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv2459 Modified Files: itertools.c Log Message: a couple docstring typos Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** itertools.c 27 Jan 2003 12:16:42 -0000 1.8 --- itertools.c 27 Jan 2003 15:22:59 -0000 1.9 *************** *** 794,798 **** "times(n) --> times object\n\ \n\ ! Return an times object whose .next() method returns n consecutive\n\ instance of None."); --- 794,798 ---- "times(n) --> times object\n\ \n\ ! Return a times object whose .next() method returns n consecutive\n\ instance of None."); *************** *** 1035,1039 **** "count([firstval]) --> count object\n\ \n\ ! Return an count object whose .next() method returns consecutive\n\ integers starting from zero or, if specified, from firstval."); --- 1035,1039 ---- "count([firstval]) --> count object\n\ \n\ ! Return a count object whose .next() method returns consecutive\n\ integers starting from zero or, if specified, from firstval."); *************** *** 1204,1208 **** "loopzip(iter1 [,iter2 [...]]) --> loopzip object\n\ \n\ ! Return an loopzip object whose .next() method returns a list where\n\ the i-th element comes from the i-th iterable argument. The .next()\n\ method updates the returns the same list everytime until the shortest\n\ --- 1204,1208 ---- "loopzip(iter1 [,iter2 [...]]) --> loopzip object\n\ \n\ ! Return a loopzip object whose .next() method returns a list where\n\ the i-th element comes from the i-th iterable argument. The .next()\n\ method updates the returns the same list everytime until the shortest\n\ From tim_one@users.sourceforge.net Mon Jan 27 15:38:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 07:38:17 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv12961 Modified Files: pickletools.py Log Message: dis(): Indenting MARK blocks improves clarity. All over: minor typo repair and fiddling. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** pickletools.py 27 Jan 2003 14:26:48 -0000 1.31 --- pickletools.py 27 Jan 2003 15:38:14 -0000 1.32 *************** *** 1403,1409 **** stack_after=[anyobject], proto=0, ! doc="""Push an object identified by a persisent ID. ! The pickle module doesn't define what a persisent ID means. PERSID's argument is a newline-terminated str-style (no embedded escapes, no bracketing quote characters) string, which *is* "the persistent ID". --- 1403,1409 ---- stack_after=[anyobject], proto=0, ! doc="""Push an object identified by a persistent ID. ! The pickle module doesn't define what a persistent ID means. PERSID's argument is a newline-terminated str-style (no embedded escapes, no bracketing quote characters) string, which *is* "the persistent ID". *************** *** 1434,1439 **** code2i = {} ! i = 0 ! for d in opcodes: if d.name in name2i: raise ValueError("repeated name %r at indices %d and %d" % --- 1434,1438 ---- code2i = {} ! for i, d in enumerate(opcodes): if d.name in name2i: raise ValueError("repeated name %r at indices %d and %d" % *************** *** 1445,1449 **** name2i[d.name] = i code2i[d.code] = i - i += 1 del name2i, code2i, i, d --- 1444,1447 ---- *************** *** 1559,1563 **** # A symbolic pickle disassembler. ! def dis(pickle, out=None): """Produce a symbolic disassembly of a pickle. --- 1557,1561 ---- # A symbolic pickle disassembler. ! def dis(pickle, out=None, indentlevel=4): """Produce a symbolic disassembly of a pickle. *************** *** 1568,1582 **** Optional arg 'out' is a file-like object to which the disassembly is printed. It defaults to sys.stdout. """ markstack = [] for opcode, arg, pos in genops(pickle): if pos is not None: print >> out, "%5d:" % pos, ! line = opcode.code + " " + opcode.name markmsg = None if markstack and markobject in opcode.stack_before: markpos = markstack.pop() if markpos is not None: --- 1566,1587 ---- Optional arg 'out' is a file-like object to which the disassembly is printed. It defaults to sys.stdout. + + Optional arg indentlevel is the number of blanks by which to indent + a new MARK level. It defaults to 4. """ markstack = [] + indentchunk = ' ' * indentlevel for opcode, arg, pos in genops(pickle): if pos is not None: print >> out, "%5d:" % pos, ! line = "%s %s%s" % (opcode.code, ! indentchunk * len(markstack), ! opcode.name) markmsg = None if markstack and markobject in opcode.stack_before: + assert markobject not in opcode.stack_after markpos = markstack.pop() if markpos is not None: *************** *** 1585,1589 **** if arg is not None or markmsg: # make a mild effort to align arguments ! line += (' ' * 10)[len(opcode.name):] if arg is not None: line += ' ' + repr(arg) --- 1590,1594 ---- if arg is not None or markmsg: # make a mild effort to align arguments ! line += ' ' * (10 - len(opcode.name)) if arg is not None: line += ' ' + repr(arg) *************** *** 1593,1596 **** --- 1598,1602 ---- if markobject in opcode.stack_after: + assert markobject not in opcode.stack_before markstack.append(pos) *************** *** 1602,1606 **** >>> dis(pik) 0: ( MARK ! 1: l LIST (MARK at 0) 2: p PUT 0 5: I INT 1 --- 1608,1612 ---- >>> dis(pik) 0: ( MARK ! 1: l LIST (MARK at 0) 2: p PUT 0 5: I INT 1 *************** *** 1609,1619 **** 12: a APPEND 13: ( MARK ! 14: I INT 3 ! 17: I INT 4 ! 20: t TUPLE (MARK at 13) 21: p PUT 1 24: a APPEND 25: ( MARK ! 26: d DICT (MARK at 25) 27: p PUT 2 30: S STRING 'abc' --- 1615,1625 ---- 12: a APPEND 13: ( MARK ! 14: I INT 3 ! 17: I INT 4 ! 20: t TUPLE (MARK at 13) 21: p PUT 1 24: a APPEND 25: ( MARK ! 26: d DICT (MARK at 25) 27: p PUT 2 30: S STRING 'abc' *************** *** 1632,1650 **** 1: q BINPUT 0 3: ( MARK ! 4: K BININT1 1 ! 6: K BININT1 2 ! 8: ( MARK ! 9: K BININT1 3 ! 11: K BININT1 4 ! 13: t TUPLE (MARK at 8) ! 14: q BINPUT 1 ! 16: } EMPTY_DICT ! 17: q BINPUT 2 ! 19: U SHORT_BINSTRING 'abc' ! 24: q BINPUT 3 ! 26: X BINUNICODE u'def' ! 34: q BINPUT 4 ! 36: s SETITEM ! 37: e APPENDS (MARK at 3) 38: . STOP --- 1638,1656 ---- 1: q BINPUT 0 3: ( MARK ! 4: K BININT1 1 ! 6: K BININT1 2 ! 8: ( MARK ! 9: K BININT1 3 ! 11: K BININT1 4 ! 13: t TUPLE (MARK at 8) ! 14: q BINPUT 1 ! 16: } EMPTY_DICT ! 17: q BINPUT 2 ! 19: U SHORT_BINSTRING 'abc' ! 24: q BINPUT 3 ! 26: X BINUNICODE u'def' ! 34: q BINPUT 4 ! 36: s SETITEM ! 37: e APPENDS (MARK at 3) 38: . STOP *************** *** 1660,1675 **** >>> dis(pickle.dumps(x)) 0: ( MARK ! 1: l LIST (MARK at 0) 2: p PUT 0 5: ( MARK ! 6: i INST 'pickle.PicklingError' (MARK at 5) 28: p PUT 1 31: ( MARK ! 32: d DICT (MARK at 31) 33: p PUT 2 36: S STRING 'args' 44: p PUT 3 47: ( MARK ! 48: t TUPLE (MARK at 47) 49: p PUT 4 52: s SETITEM --- 1666,1681 ---- >>> dis(pickle.dumps(x)) 0: ( MARK ! 1: l LIST (MARK at 0) 2: p PUT 0 5: ( MARK ! 6: i INST 'pickle.PicklingError' (MARK at 5) 28: p PUT 1 31: ( MARK ! 32: d DICT (MARK at 31) 33: p PUT 2 36: S STRING 'args' 44: p PUT 3 47: ( MARK ! 48: t TUPLE (MARK at 47) 49: p PUT 4 52: s SETITEM *************** *** 1684,1701 **** 1: q BINPUT 0 3: ( MARK ! 4: ( MARK ! 5: c GLOBAL 'pickle.PicklingError' ! 27: q BINPUT 1 ! 29: o OBJ (MARK at 4) ! 30: q BINPUT 2 ! 32: } EMPTY_DICT ! 33: q BINPUT 3 ! 35: U SHORT_BINSTRING 'args' ! 41: q BINPUT 4 ! 43: ) EMPTY_TUPLE ! 44: s SETITEM ! 45: b BUILD ! 46: h BINGET 2 ! 48: e APPENDS (MARK at 3) 49: . STOP """ --- 1690,1707 ---- 1: q BINPUT 0 3: ( MARK ! 4: ( MARK ! 5: c GLOBAL 'pickle.PicklingError' ! 27: q BINPUT 1 ! 29: o OBJ (MARK at 4) ! 30: q BINPUT 2 ! 32: } EMPTY_DICT ! 33: q BINPUT 3 ! 35: U SHORT_BINSTRING 'args' ! 41: q BINPUT 4 ! 43: ) EMPTY_TUPLE ! 44: s SETITEM ! 45: b BUILD ! 46: h BINGET 2 ! 48: e APPENDS (MARK at 3) 49: . STOP """ From rhettinger@users.sourceforge.net Mon Jan 27 15:43:29 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 07:43:29 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv17257 Modified Files: libitertools.tex Log Message: Transform the pure python versions from off-the-cuff psuedo-code into tested executable code. Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** libitertools.tex 27 Jan 2003 12:16:42 -0000 1.8 --- libitertools.tex 27 Jan 2003 15:42:54 -0000 1.9 *************** *** 96,101 **** \begin{verbatim} def count(n=0): while True: ! yield n cnt += 1 \end{verbatim} --- 96,102 ---- \begin{verbatim} def count(n=0): + cnt = n while True: ! yield cnt cnt += 1 \end{verbatim} *************** *** 108,112 **** \begin{verbatim} ! def dropwhile(func, iterable, invert=False): iterable = iter(iterable) while True: --- 109,113 ---- \begin{verbatim} ! def dropwhile(predicate, iterable, invert=False): iterable = iter(iterable) while True: *************** *** 128,137 **** \begin{verbatim} ! def filter(func, iterable, invert=False): iterable = iter(iterable) while True: ! x = bool(iterable.next()) ! if not invert and x or invert and not x: ! yield None \end{verbatim} \end{funcdesc} --- 129,139 ---- \begin{verbatim} ! def ifilter(func, iterable, invert=False): iterable = iter(iterable) while True: ! x = iterable.next() ! b = bool(func(x)) ! if not invert and b or invert and not b: ! yield x \end{verbatim} \end{funcdesc} *************** *** 150,154 **** while True: args = [i.next() for i in iterables] ! yield f(*args) \end{verbatim} \end{funcdesc} --- 152,156 ---- while True: args = [i.next() for i in iterables] ! yield func(*args) \end{verbatim} \end{funcdesc} *************** *** 192,196 **** while True: for i in xrange(len(iterables)): ! result[i] = iterable[i].next() yield result \end{verbatim} --- 194,198 ---- while True: for i in xrange(len(iterables)): ! result[i] = iterables[i].next() yield result \end{verbatim} *************** *** 205,209 **** def repeat(x): while True: ! yield None \end{verbatim} \end{funcdesc} --- 207,211 ---- def repeat(x): while True: ! yield x \end{verbatim} \end{funcdesc} *************** *** 214,218 **** \begin{verbatim} ! def stapmap(func, iterable): iterable = iter(iterable) while True: --- 216,220 ---- \begin{verbatim} ! def starmap(func, iterable): iterable = iter(iterable) while True: *************** *** 226,230 **** \begin{verbatim} ! def takewhile(func, iterable, invert=False): iterable = iter(iterable) while True: --- 228,232 ---- \begin{verbatim} ! def takewhile(predicate, iterable, invert=False): iterable = iter(iterable) while True: *************** *** 244,247 **** --- 246,250 ---- \begin{verbatim} def times(n): + if n<0: raise ValueError for i in xrange(n): yield None From doerwalter@users.sourceforge.net Mon Jan 27 15:57:20 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Mon, 27 Jan 2003 07:57:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_builtin.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv1562/Lib/test Modified Files: test_builtin.py Log Message: Fix comment typos Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_builtin.py 25 Jan 2003 22:46:11 -0000 1.4 --- test_builtin.py 27 Jan 2003 15:57:14 -0000 1.5 *************** *** 353,362 **** self.assertRaises(TypeError, filter, badfunc, range(5)) ! # test biltinmodule.c::filtertuple() self.assertEqual(filter(None, (1, 2)), (1, 2)) self.assertEqual(filter(lambda x: x>=3, (1, 2, 3, 4)), (3, 4)) self.assertRaises(TypeError, filter, 42, (1, 2)) ! # test biltinmodule.c::filterstring() self.assertEqual(filter(None, "12"), "12") self.assertEqual(filter(lambda x: x>="3", "1234"), "34") --- 353,362 ---- self.assertRaises(TypeError, filter, badfunc, range(5)) ! # test bltinmodule.c::filtertuple() self.assertEqual(filter(None, (1, 2)), (1, 2)) self.assertEqual(filter(lambda x: x>=3, (1, 2, 3, 4)), (3, 4)) self.assertRaises(TypeError, filter, 42, (1, 2)) ! # test bltinmodule.c::filterstring() self.assertEqual(filter(None, "12"), "12") self.assertEqual(filter(lambda x: x>="3", "1234"), "34") *************** *** 366,371 **** raise ValueError self.assertRaises(ValueError, filter, lambda x: x >="3", badstr("1234")) if have_unicode: ! # test biltinmodule.c::filterstring() self.assertEqual(filter(None, unicode("12")), unicode("12")) self.assertEqual(filter(lambda x: x>="3", unicode("1234")), unicode("34")) --- 366,372 ---- raise ValueError self.assertRaises(ValueError, filter, lambda x: x >="3", badstr("1234")) + if have_unicode: ! # test bltinmodule.c::filterunicode() self.assertEqual(filter(None, unicode("12")), unicode("12")) self.assertEqual(filter(lambda x: x>="3", unicode("1234")), unicode("34")) From tim_one@users.sourceforge.net Mon Jan 27 16:25:26 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 08:25:26 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv25249 Modified Files: pickletools.py Log Message: Added some pickle disassemblies of recursive objects to the dis test. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** pickletools.py 27 Jan 2003 15:38:14 -0000 1.32 --- pickletools.py 27 Jan 2003 16:25:22 -0000 1.33 *************** *** 1705,1708 **** --- 1705,1766 ---- 48: e APPENDS (MARK at 3) 49: . STOP + + Try "the canonical" recursive-object test. + >>> L = [] + >>> T = L, + >>> L.append(T) + >>> L[0] is T + True + >>> T[0] is L + True + >>> L[0][0] is L + True + >>> T[0][0] is T + True + >>> dis(pickle.dumps(L)) + 0: ( MARK + 1: l LIST (MARK at 0) + 2: p PUT 0 + 5: ( MARK + 6: g GET 0 + 9: t TUPLE (MARK at 5) + 10: p PUT 1 + 13: a APPEND + 14: . STOP + >>> dis(pickle.dumps(L, 1)) + 0: ] EMPTY_LIST + 1: q BINPUT 0 + 3: ( MARK + 4: h BINGET 0 + 6: t TUPLE (MARK at 3) + 7: q BINPUT 1 + 9: a APPEND + 10: . STOP + >>> dis(pickle.dumps(T)) + 0: ( MARK + 1: ( MARK + 2: l LIST (MARK at 1) + 3: p PUT 0 + 6: ( MARK + 7: g GET 0 + 10: t TUPLE (MARK at 6) + 11: p PUT 1 + 14: a APPEND + 15: 0 POP + 16: 0 POP + 17: g GET 1 + 20: . STOP + >>> dis(pickle.dumps(T, 1)) + 0: ( MARK + 1: ] EMPTY_LIST + 2: q BINPUT 0 + 4: ( MARK + 5: h BINGET 0 + 7: t TUPLE (MARK at 4) + 8: q BINPUT 1 + 10: a APPEND + 11: 1 POP_MARK (MARK at 0) + 12: h BINGET 1 + 14: . STOP """ From akuchling@users.sourceforge.net Mon Jan 27 16:30:39 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 27 Jan 2003 08:30:39 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils core.py,1.56,1.57 extension.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory sc8-pr-cvs1:/tmp/cvs-serv28128 Modified Files: core.py extension.py Log Message: Remove the recently-added get_distutil_options(), and just have two tuples listing the legal keywords for setup() and Extension() Index: core.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/core.py,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** core.py 19 Nov 2002 13:12:27 -0000 1.56 --- core.py 27 Jan 2003 16:30:35 -0000 1.57 *************** *** 43,46 **** --- 43,59 ---- _setup_distribution = None + # Legal keyword arguments for the setup() function + setup_keywords = ('distclass', 'script_name', 'script_args', 'options', + 'name', 'version', 'author', 'author_email', + 'maintainer', 'maintainer_email', 'url', 'license', + 'description', 'long_description', 'keywords', + 'platforms', 'classifiers') + + # Legal keyword arguments for the Extension constructor + extension_keywords = ('name', 'sources', 'include_dirs', + 'define_macros', 'undef_macros', + 'library_dirs', 'libraries', 'runtime_library_dirs', + 'extra_objects', 'extra_compile_args', 'extra_link_args', + 'export_symbols', 'depends', 'language') def setup (**attrs): *************** *** 227,236 **** # run_setup () - def get_distutil_options (): - """Returns a list of strings recording changes to the Distutils. - - setup.py files can then do: - if 'optional-thing' in get_distutil_options(): - ... - """ - return [] --- 240,241 ---- Index: extension.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/extension.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** extension.py 27 Nov 2002 13:45:26 -0000 1.17 --- extension.py 27 Jan 2003 16:30:36 -0000 1.18 *************** *** 83,86 **** --- 83,88 ---- """ + # When adding arguments to this constructor, be sure to update + # setup_keywords in core.py. def __init__ (self, name, sources, include_dirs=None, From fdrake@users.sourceforge.net Mon Jan 27 16:31:19 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 27 Jan 2003 08:31:19 -0800 Subject: [Python-checkins] python/dist/src/Doc/html style.css,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/html In directory sc8-pr-cvs1:/tmp/cvs-serv28999 Modified Files: style.css Log Message: Make the "notice" environments somewhat similar, with less difference between the "note" and "warning" flavors. Index: style.css =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/html/style.css,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** style.css 14 Jun 2002 13:47:58 -0000 1.23 --- style.css 27 Jan 2003 16:31:16 -0000 1.24 *************** *** 68,73 **** margin-right: 2em; } ! div.warning .label { font-size: 110%; margin-right: 0.5em; } .release-info { font-style: italic; } --- 68,83 ---- margin-right: 2em; } ! div.warning .label { font-family: sans-serif; ! font-size: 110%; margin-right: 0.5em; } + + div.note { background-color: #fffaf0; + border: thin solid black; + padding: 0.5em; + margin-left: 2em; + margin-right: 2em; } + + div.note .label { margin-right: 0.5em; + font-family: sans-serif; } .release-info { font-style: italic; } From fdrake@users.sourceforge.net Mon Jan 27 16:32:08 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 27 Jan 2003 08:32:08 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libhttplib.tex,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv29593 Modified Files: libhttplib.tex Log Message: Adjust some of Skip's latest changes slightly; these really are things that should stand out. Index: libhttplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libhttplib.tex,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** libhttplib.tex 27 Jan 2003 15:00:38 -0000 1.32 --- libhttplib.tex 27 Jan 2003 16:32:04 -0000 1.33 *************** *** 11,19 **** HTTP and HTTPS protocols. It is normally not used directly --- the module \refmodule{urllib}\refstmodindex{urllib} uses it to handle URLs ! that use HTTP and HTTPS. \note{HTTPS support is only ! available if the \refmodule{socket} module was compiled with SSL ! support.} \note{The \class{HTTP} class is retained only for backward ! compatibility with 1.5.2. It should not be used in new code. Refer to the ! online docstrings for usage.} The constants defined in this module are: --- 11,27 ---- HTTP and HTTPS protocols. It is normally not used directly --- the module \refmodule{urllib}\refstmodindex{urllib} uses it to handle URLs ! that use HTTP and HTTPS. ! ! \begin{notice} ! HTTPS support is only available if the \refmodule{socket} module was ! compiled with SSL support. ! \end{notice} ! ! \begin{notice} ! The public interface for this module changed substantially in Python ! 2.0. The \class{HTTP} class is retained only for backward ! compatibility with 1.5.2. It should not be used in new code. Refer ! to the online docstrings for usage. ! \end{notice} The constants defined in this module are: From tim_one@users.sourceforge.net Mon Jan 27 16:33:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 08:33:56 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv30526 Modified Files: pickletools.py Log Message: Explained the surprising dump of the text-mode pickle of the recursive tuple. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/pickletools/pickletools.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** pickletools.py 27 Jan 2003 16:25:22 -0000 1.33 --- pickletools.py 27 Jan 2003 16:33:51 -0000 1.34 *************** *** 1707,1710 **** --- 1707,1711 ---- Try "the canonical" recursive-object test. + >>> L = [] >>> T = L, *************** *** 1737,1740 **** --- 1738,1749 ---- 9: a APPEND 10: . STOP + + The protocol 0 pickle of the tuple causes the disassembly to get confused, + as it doesn't realize that the POP opcode at 16 gets rid of the MARK at 0 + (so the output remains indented until the end). The protocol 1 pickle + doesn't trigger this glitch, because the disassembler realizes that + POP_MARK gets rid of the MARK. Doing a better job on the protocol 0 + pickle would require the disassembler to emulate the stack. + >>> dis(pickle.dumps(T)) 0: ( MARK From akuchling@users.sourceforge.net Mon Jan 27 16:36:39 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 27 Jan 2003 08:36:39 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.110,1.111 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv32451 Modified Files: whatsnew23.tex Log Message: Update register example Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** whatsnew23.tex 17 Jan 2003 22:50:10 -0000 1.110 --- whatsnew23.tex 27 Jan 2003 16:36:34 -0000 1.111 *************** *** 727,742 **** \citetitle[http://www.tuxedo.org/\%7Eesr/trove/]{Trove}-style strings can be supplied to help classify the software. ! Here's an example \file{setup.py} with classifiers: \begin{verbatim} ! setup (name = "Quixote", ! version = "0.5.1", ! description = "A highly Pythonic Web application framework", ! ... ! classifiers= ['Topic :: Internet :: WWW/HTTP :: Dynamic Content', ! 'Environment :: No Input/Output (Daemon)', ! 'Intended Audience :: Developers'], ... ) \end{verbatim} --- 727,749 ---- \citetitle[http://www.tuxedo.org/\%7Eesr/trove/]{Trove}-style strings can be supplied to help classify the software. ! Here's an example \file{setup.py} with classifiers, written to be compatible ! with older versions of the Distutils: \begin{verbatim} ! from distutils import core ! kw = ('name': "Quixote", ! 'version': "0.5.1", ! 'description': "A highly Pythonic Web application framework", ... ) + + if (hasattr(core, 'setup_keywords') and + 'classifiers' in core.setup_keywords): + kw['classifiers'] = \ + ['Topic :: Internet :: WWW/HTTP :: Dynamic Content', + 'Environment :: No Input/Output (Daemon)', + 'Intended Audience :: Developers'], + + core.setup (**kw) \end{verbatim} *************** *** 1280,1285 **** \envvar{LDFLAGS}, and \envvar{CPPFLAGS} environment variables, using them to override the settings in Python's configuration (contributed ! by Robert Weber); the \function{get_distutils_options()} method lists ! recently-added extensions to Distutils. \item The \module{getopt} module gained a new function, --- 1287,1291 ---- \envvar{LDFLAGS}, and \envvar{CPPFLAGS} environment variables, using them to override the settings in Python's configuration (contributed ! by Robert Weber). \item The \module{getopt} module gained a new function, From tim_one@users.sourceforge.net Mon Jan 27 16:45:14 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 08:45:14 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.117,1.118 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv4569/python/Lib/test Modified Files: regrtest.py Log Message: Repaired spelling of "test_iconv_codecs" in various expected-skip lists. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.117 retrieving revision 1.118 diff -C2 -d -r1.117 -r1.118 *** regrtest.py 26 Jan 2003 11:27:16 -0000 1.117 --- regrtest.py 27 Jan 2003 16:45:03 -0000 1.118 *************** *** 557,561 **** test_gl test_grp ! test_iconv_codec test_imgfile test_largefile --- 557,561 ---- test_gl test_grp ! test_iconv_codecs test_imgfile test_largefile *************** *** 613,617 **** test_gl test_grp ! test_iconv_codec test_imgfile test_largefile --- 613,617 ---- test_gl test_grp ! test_iconv_codecs test_imgfile test_largefile *************** *** 901,905 **** test_email_codecs test_gl ! test_iconv_codec test_imgfile test_largefile --- 901,905 ---- test_email_codecs test_gl ! test_iconv_codecs test_imgfile test_largefile From tim_one@users.sourceforge.net Mon Jan 27 18:34:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 10:34:53 -0800 Subject: [Python-checkins] python/nondist/sandbox/pickletools pickletools.py,1.34,NONE Message-ID: Update of /cvsroot/python/python/nondist/sandbox/pickletools In directory sc8-pr-cvs1:/tmp/cvs-serv5059/pickletools Removed Files: pickletools.py Log Message: This is moving to the std library. Thanks for all the fish! --- pickletools.py DELETED --- From tim_one@users.sourceforge.net Mon Jan 27 18:51:49 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 10:51:49 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14907/python/Lib Added Files: pickletools.py Log Message: Moving pickletools.py from the sandbox into the std library. I started this over the weekend, and it made faster & better progress than I expected -- it's already useful . --- NEW FILE: pickletools.py --- """"Executable documentation" for the pickle module. Extensive comments about the pickle protocols and pickle-machine opcodes can be found here. Some functions meant for external use: genops(pickle) Generate all the opcodes in a pickle, as (opcode, arg, position) triples. dis(pickle, out=None, indentlevel=4) Print a symbolic disassembly of a pickle. """ # Other ideas: # # - A pickle verifier: read a pickle and check it exhaustively for # well-formedness. # # - A protocol identifier: examine a pickle and return its protocol number # (== the highest .proto attr value among all the opcodes in the pickle). [...1755 lines suppressed...] 2: q BINPUT 0 4: ( MARK 5: h BINGET 0 7: t TUPLE (MARK at 4) 8: q BINPUT 1 10: a APPEND 11: 1 POP_MARK (MARK at 0) 12: h BINGET 1 14: . STOP """ __test__ = {'dissassembler_test': _dis_test, } def _test(): import doctest return doctest.testmod() if __name__ == "__main__": _test() From tim_one@users.sourceforge.net Mon Jan 27 18:51:50 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 10:51:50 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_pickletools.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14907/python/Lib/test Added Files: test_pickletools.py Log Message: Moving pickletools.py from the sandbox into the std library. I started this over the weekend, and it made faster & better progress than I expected -- it's already useful . --- NEW FILE: test_pickletools.py --- import pickletools from test import test_support test_support.run_doctest(pickletools) From tim_one@users.sourceforge.net Mon Jan 27 18:51:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 10:51:53 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.628,1.629 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv14907/python/Misc Modified Files: NEWS Log Message: Moving pickletools.py from the sandbox into the std library. I started this over the weekend, and it made faster & better progress than I expected -- it's already useful . Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.628 retrieving revision 1.629 diff -C2 -d -r1.628 -r1.629 *** NEWS 27 Jan 2003 15:21:39 -0000 1.628 --- NEWS 27 Jan 2003 18:51:48 -0000 1.629 *************** *** 123,126 **** --- 123,130 ---- ------- + - The new pickletools.py contains lots of documentation about pickle + internals, and supplies some helpers for working with pickles, such as + a symbolic pickle disassembler. + - Xmlrpclib.py now supports the builtin boolean type. *************** *** 152,156 **** - Fix logging.handlers.SysLogHandler protocol when using UNIX domain sockets. ! See SF patch #642974. Tools/Demos --- 156,160 ---- - Fix logging.handlers.SysLogHandler protocol when using UNIX domain sockets. ! See SF patch #642974. Tools/Demos *************** *** 215,219 **** - There are new dialogs EasyDialogs.AskFileForOpen, AskFileForSave and AskFolder. The old macfs.StandardGetFile and friends are deprecated. ! - Type Carbon.File.FSCatalogInfo and supporting methods have been implemented. This also makes macfs.FSSpec.SetDates() work again. --- 219,223 ---- - There are new dialogs EasyDialogs.AskFileForOpen, AskFileForSave and AskFolder. The old macfs.StandardGetFile and friends are deprecated. ! - Type Carbon.File.FSCatalogInfo and supporting methods have been implemented. This also makes macfs.FSSpec.SetDates() work again. From martin@v.loewis.de Mon Jan 27 18:53:49 2003 From: martin@v.loewis.de (Martin v. =?iso-8859-15?q?L=F6wis?=) Date: 27 Jan 2003 19:53:49 +0100 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 In-Reply-To: <3E352ADE.3090908@livinglogic.de> References: <3E352ADE.3090908@livinglogic.de> Message-ID: Walter D=F6rwald writes: > This interprets negative indizes as being relative to the > end of the input. All other encoders treat <0 as =3D=3D0. Hmm. This appears to be unspecified in the PEP. What is the rationale for equating <0 to =3D0? It appears that this indicates a bug in the error callback, which should not pass silently. In any case, I'ld like to request that the documentation is clarified in this aspect (preferable, the "proper" documentation, not (just) the PEP). Once that clarification is added, the incorrect codecs should be corrected. Regards, Martin From tim_one@users.sourceforge.net Mon Jan 27 19:01:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 11:01:53 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19776/python/Lib Modified Files: pickletools.py Log Message: stringnl_noescape_pair(): changed the reader to separate the two component strings by a blank instead of a period. Guido pointed out that the component strings (at least the first one) can be dotted already. find_class() is overridable too, so only God knows all the possibilities that make sense to someone. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pickletools.py 27 Jan 2003 18:51:47 -0000 1.1 --- pickletools.py 27 Jan 2003 19:01:47 -0000 1.2 *************** *** 300,307 **** >>> import StringIO >>> read_stringnl_noescape_pair(StringIO.StringIO("Queue\\nEmpty\\njunk")) ! 'Queue.Empty' """ ! return "%s.%s" % (read_stringnl_noescape(f), read_stringnl_noescape(f)) stringnl_noescape_pair = ArgumentDescriptor( --- 300,307 ---- >>> import StringIO >>> read_stringnl_noescape_pair(StringIO.StringIO("Queue\\nEmpty\\njunk")) ! 'Queue Empty' """ ! return "%s %s" % (read_stringnl_noescape(f), read_stringnl_noescape(f)) stringnl_noescape_pair = ArgumentDescriptor( *************** *** 315,319 **** consist solely of printable ASCII characters. The pair is returned as a single string, with ! a single '.' separating the two strings. """) --- 315,319 ---- consist solely of printable ASCII characters. The pair is returned as a single string, with ! a single blank separating the two strings. """) *************** *** 1669,1673 **** >>> import random >>> dis(pickle.dumps(random.random)) ! 0: c GLOBAL 'random.random' 15: p PUT 0 18: . STOP --- 1669,1673 ---- >>> import random >>> dis(pickle.dumps(random.random)) ! 0: c GLOBAL 'random random' 15: p PUT 0 18: . STOP *************** *** 1679,1683 **** 2: p PUT 0 5: ( MARK ! 6: i INST 'pickle.PicklingError' (MARK at 5) 28: p PUT 1 31: ( MARK --- 1679,1683 ---- 2: p PUT 0 5: ( MARK ! 6: i INST 'pickle PicklingError' (MARK at 5) 28: p PUT 1 31: ( MARK *************** *** 1701,1705 **** 3: ( MARK 4: ( MARK ! 5: c GLOBAL 'pickle.PicklingError' 27: q BINPUT 1 29: o OBJ (MARK at 4) --- 1701,1705 ---- 3: ( MARK 4: ( MARK ! 5: c GLOBAL 'pickle PicklingError' 27: q BINPUT 1 29: o OBJ (MARK at 4) From tim_one@users.sourceforge.net Mon Jan 27 19:38:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 11:38:41 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5690/python/Lib Modified Files: pickletools.py Log Message: Repaired comment. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pickletools.py 27 Jan 2003 19:01:47 -0000 1.2 --- pickletools.py 27 Jan 2003 19:38:34 -0000 1.3 *************** *** 71,76 **** pickle opcodes never go away, not even when better ways to do a thing get invented. The repertoire of the PM just keeps growing over time. ! So, e.g., there are now six distinct opcodes for building a Python integer, ! five of them devoted to "short" integers. Even so, the only way to pickle a Python long int takes time quadratic in the number of digits, for both pickling and unpickling. This isn't so much a subtlety as a source of --- 71,76 ---- pickle opcodes never go away, not even when better ways to do a thing get invented. The repertoire of the PM just keeps growing over time. ! So, e.g., there are now five distinct opcodes for building a Python integer, ! four of them devoted to "short" integers. Even so, the only way to pickle a Python long int takes time quadratic in the number of digits, for both pickling and unpickling. This isn't so much a subtlety as a source of From gvanrossum@users.sourceforge.net Mon Jan 27 19:40:51 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 11:40:51 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv6674 Modified Files: pickletools.py Log Message: Remove a stray quote. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pickletools.py 27 Jan 2003 19:38:34 -0000 1.3 --- pickletools.py 27 Jan 2003 19:40:47 -0000 1.4 *************** *** 1511,1515 **** def genops(pickle): ! """"Generate all the opcodes in a pickle. 'pickle' is a file-like object, or string, containing the pickle. --- 1511,1515 ---- def genops(pickle): ! """Generate all the opcodes in a pickle. 'pickle' is a file-like object, or string, containing the pickle. From tim_one@users.sourceforge.net Mon Jan 27 20:16:40 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 12:16:40 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.73,1.74 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv23572a/python/Lib Modified Files: pickle.py Log Message: Added a brief comment to each pickle opcode declaration. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -d -r1.73 -r1.74 *** pickle.py 24 Jan 2003 19:29:52 -0000 1.73 --- pickle.py 27 Jan 2003 20:16:36 -0000 1.74 *************** *** 3,6 **** --- 3,7 ---- See module cPickle for a (much) faster implementation. See module copy_reg for a mechanism for registering custom picklers. + See module pickletools source for extensive comments. Classes: *************** *** 78,125 **** UnicodeType = None ! MARK = '(' ! STOP = '.' ! POP = '0' ! POP_MARK = '1' ! DUP = '2' ! FLOAT = 'F' ! INT = 'I' ! BININT = 'J' ! BININT1 = 'K' ! LONG = 'L' ! BININT2 = 'M' ! NONE = 'N' ! PERSID = 'P' ! BINPERSID = 'Q' ! REDUCE = 'R' ! STRING = 'S' ! BINSTRING = 'T' ! SHORT_BINSTRING = 'U' ! UNICODE = 'V' ! BINUNICODE = 'X' ! APPEND = 'a' ! BUILD = 'b' ! GLOBAL = 'c' ! DICT = 'd' ! EMPTY_DICT = '}' ! APPENDS = 'e' ! GET = 'g' ! BINGET = 'h' ! INST = 'i' ! LONG_BINGET = 'j' ! LIST = 'l' ! EMPTY_LIST = ']' ! OBJ = 'o' ! PUT = 'p' ! BINPUT = 'q' ! LONG_BINPUT = 'r' ! SETITEM = 's' ! TUPLE = 't' ! EMPTY_TUPLE = ')' ! SETITEMS = 'u' ! BINFLOAT = 'G' ! TRUE = 'I01\n' ! FALSE = 'I00\n' --- 79,130 ---- UnicodeType = None + # Pickle opcodes. See pickletools.py for extensive docs. The listing + # here is in kind-of alphabetical order of 1-character pickle code. + # pickletools groups them by purpose. ! MARK = '(' # push special markobject on stack ! STOP = '.' # every pickle ends with STOP ! POP = '0' # discard topmost stack item ! POP_MARK = '1' # discard stack top through topmost markobject ! DUP = '2' # duplicate top stack item ! FLOAT = 'F' # push float object; decimal string argument ! INT = 'I' # push integer or bool; decimal string argument ! BININT = 'J' # push four-byte signed int ! BININT1 = 'K' # push 1-byte unsigned int ! LONG = 'L' # push long; decimal string argument ! BININT2 = 'M' # push 2-byte unsigned int ! NONE = 'N' # push None ! PERSID = 'P' # push persistent object; id is taken from string arg ! BINPERSID = 'Q' # " " " ; " " " " stack ! REDUCE = 'R' # apply callable to argtuple, both on stack ! STRING = 'S' # push string; NL-terminated string argument ! BINSTRING = 'T' # push string; counted binary string argument ! SHORT_BINSTRING = 'U' # " " ; " " " " < 256 bytes ! UNICODE = 'V' # push Unicode string; raw-unicode-escaped'd argument ! BINUNICODE = 'X' # " " " ; counted UTF-8 string argument ! APPEND = 'a' # append stack top to list below it ! BUILD = 'b' # call __setstate__ or __dict__.update() ! GLOBAL = 'c' # push self.find_class(modname, name); 2 string args ! DICT = 'd' # build a dict from stack items ! EMPTY_DICT = '}' # push empty dict ! APPENDS = 'e' # extend list on stack by topmost stack slice ! GET = 'g' # push item from memo on stack; index is string arg ! BINGET = 'h' # " " " " " " ; " " 1-byte arg ! INST = 'i' # build & push class instance ! LONG_BINGET = 'j' # push item from memo on stack; index is 4-byte arg ! LIST = 'l' # build list from topmost stack items ! EMPTY_LIST = ']' # push empty list ! OBJ = 'o' # build & push class instance ! PUT = 'p' # store stack top in memo; index is string arg ! BINPUT = 'q' # " " " " " ; " " 1-byte arg ! LONG_BINPUT = 'r' # " " " " " ; " " 4-byte arg ! SETITEM = 's' # add key+value pair to dict ! TUPLE = 't' # build tuple from topmost stack items ! EMPTY_TUPLE = ')' # push empty tuple ! SETITEMS = 'u' # modify dict by adding topmost key+value pairs ! BINFLOAT = 'G' # push float; arg is 8-byte float encoding ! ! TRUE = 'I01\n' # not an opcode; see INT docs in pickletools.py ! FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py *************** *** 304,308 **** raise PicklingError("__reduce__() must return callable as " "first argument, not %s" % `acallable`) ! save(acallable) save(arg_tup) --- 309,313 ---- raise PicklingError("__reduce__() must return callable as " "first argument, not %s" % `acallable`) ! save(acallable) save(arg_tup) From tim_one@users.sourceforge.net Mon Jan 27 21:15:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 13:15:39 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28540/python/Lib Modified Files: pickle.py Log Message: Using marshal functions to pack & unpack 1-byte ints is an obscure & expensive way to spell chr() and ord(). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** pickle.py 27 Jan 2003 20:16:36 -0000 1.74 --- pickle.py 27 Jan 2003 21:15:36 -0000 1.75 *************** *** 367,376 **** def save_string(self, object): if self.bin: ! l = len(object) ! s = mdumps(l)[1:] ! if l < 256: ! self.write(SHORT_BINSTRING + s[0] + object) else: ! self.write(BINSTRING + s + object) else: self.write(STRING + `object` + '\n') --- 367,375 ---- def save_string(self, object): if self.bin: ! n = len(object) ! if n < 256: ! self.write(SHORT_BINSTRING + chr(n) + object) else: ! self.write(BINSTRING + mdumps(n)[1:] + object) else: self.write(STRING + `object` + '\n') *************** *** 381,386 **** if self.bin: encoding = object.encode('utf-8') ! l = len(encoding) ! s = mdumps(l)[1:] self.write(BINUNICODE + s + encoding) else: --- 380,385 ---- if self.bin: encoding = object.encode('utf-8') ! n = len(encoding) ! s = mdumps(n)[1:] self.write(BINUNICODE + s + encoding) else: *************** *** 717,721 **** def load_binint1(self): ! self.append(mloads('i' + self.read(1) + '\000\000\000')) dispatch[BININT1] = load_binint1 --- 716,720 ---- def load_binint1(self): ! self.append(ord(self.read(1))) dispatch[BININT1] = load_binint1 *************** *** 801,805 **** def load_short_binstring(self): ! len = mloads('i' + self.read(1) + '\000\000\000') self.append(self.read(len)) dispatch[SHORT_BINSTRING] = load_short_binstring --- 800,804 ---- def load_short_binstring(self): ! len = ord(self.read(1)) self.append(self.read(len)) dispatch[SHORT_BINSTRING] = load_short_binstring *************** *** 951,955 **** def load_binget(self): ! i = mloads('i' + self.read(1) + '\000\000\000') self.append(self.memo[`i`]) dispatch[BINGET] = load_binget --- 950,954 ---- def load_binget(self): ! i = ord(self.read(1)) self.append(self.memo[`i`]) dispatch[BINGET] = load_binget *************** *** 965,969 **** def load_binput(self): ! i = mloads('i' + self.read(1) + '\000\000\000') self.memo[`i`] = self.stack[-1] dispatch[BINPUT] = load_binput --- 964,968 ---- def load_binput(self): ! i = ord(self.read(1)) self.memo[`i`] = self.stack[-1] dispatch[BINPUT] = load_binput From tim_one@users.sourceforge.net Mon Jan 27 21:22:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 13:22:13 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.75,1.76 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv512/python/Lib Modified Files: pickle.py Log Message: memoize(): Reworded the docs to try to disentangle the Pickler's memo dict from the Unpickler's memo (which is a different beast!). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -d -r1.75 -r1.76 *** pickle.py 27 Jan 2003 21:15:36 -0000 1.75 --- pickle.py 27 Jan 2003 21:22:10 -0000 1.76 *************** *** 176,187 **** """Store an object in the memo.""" ! # The memo is a dictionary mapping object ids to 2-tuples ! # that contains the memo value and the object being memoized. ! # The memo value is written to the pickle and will become # the key in the Unpickler's memo. The object is stored in the ! # memo so that transient objects are kept alive during pickling. ! # The use of the memo length as the memo value is just a convention. ! # The only requirement is that the memo values by unique. d = id(obj) memo_len = len(self.memo) --- 176,191 ---- """Store an object in the memo.""" ! # The Pickler memo is a dictionary mapping object ids to 2-tuples ! # that contain the Unpickler memo key and the object being memoized. ! # The memo key is written to the pickle and will become # the key in the Unpickler's memo. The object is stored in the ! # Pickler memo so that transient objects are kept alive during ! # pickling. ! # The use of the Unpickler memo length as the memo key is just a ! # convention. The only requirement is that the memo values be unique. ! # But there appears no advantage to any other scheme, and this ! # scheme allows the Unpickler memo to implemented as a plain (but ! # growable) array, indexed by memo key. d = id(obj) memo_len = len(self.memo) From tim_one@users.sourceforge.net Mon Jan 27 21:25:43 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 13:25:43 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.76,1.77 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv3543/python/Lib Modified Files: pickle.py Log Message: Added some comments. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.76 retrieving revision 1.77 diff -C2 -d -r1.76 -r1.77 *** pickle.py 27 Jan 2003 21:22:10 -0000 1.76 --- pickle.py 27 Jan 2003 21:25:41 -0000 1.77 *************** *** 193,196 **** --- 193,197 ---- self.memo[d] = memo_len, obj + # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i. def put(self, i): if self.bin: *************** *** 203,206 **** --- 204,208 ---- return PUT + `i` + '\n' + # Return a GET (BINGET, LONG_BINGET) opcode string, with argument i. def get(self, i): if self.bin: From gvanrossum@users.sourceforge.net Mon Jan 27 21:44:27 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 13:44:27 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.77,1.78 pickletools.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv17632 Modified Files: pickle.py pickletools.py Log Message: Begin documenting protocol 2. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.77 retrieving revision 1.78 diff -C2 -d -r1.77 -r1.78 *** pickle.py 27 Jan 2003 21:25:41 -0000 1.77 --- pickle.py 27 Jan 2003 21:44:24 -0000 1.78 *************** *** 128,131 **** --- 128,147 ---- FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py + # Protocol 2 (not yet implemented) (XXX comments will be added later) + + NEWOBJ = '\x81' + PROTO = '\x80' + EXT2 = '\x83' + EXT1 = '\x82' + TUPLE1 = '\x85' + EXT4 = '\x84' + TUPLE3 = '\x87' + TUPLE2 = '\x86' + NEWFALSE = '\x89' + NEWTRUE = '\x88' + LONG2 = '\x8b' + LONG1 = '\x8a' + LONG4 = '\x8c' + __all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)]) Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pickletools.py 27 Jan 2003 19:40:47 -0000 1.4 --- pickletools.py 27 Jan 2003 21:44:25 -0000 1.5 *************** *** 579,582 **** --- 579,699 ---- """) + # Protocol 2 formats + + def decode_long(data): + r"""Decode a long from a two's complement little-endian binary string. + >>> decode_long("\xff\x00") + 255L + >>> decode_long("\xff\x7f") + 32767L + >>> decode_long("\x00\xff") + -256L + >>> decode_long("\x00\x80") + -32768L + >>> + """ + x = 0L + i = 0L + for c in data: + x |= long(ord(c)) << i + i += 8L + if i and (x & (1L << (i-1L))): + x -= 1L << i + return x + + def read_long1(f): + r""" + >>> import StringIO + >>> read_long1(StringIO.StringIO("\x02\xff\x00")) + 255L + >>> read_long1(StringIO.StringIO("\x02\xff\x7f")) + 32767L + >>> read_long1(StringIO.StringIO("\x02\x00\xff")) + -256L + >>> read_long1(StringIO.StringIO("\x02\x00\x80")) + -32768L + >>> + """ + + n = read_uint1(f) + data = f.read(n) + if len(data) != n: + raise ValueError("not enough data in stream to read long1") + return decode_long(data) + + long1 = ArgumentDescriptor( + name="long1", + n=TAKEN_FROM_ARGUMENT, + reader=read_long1, + doc="""A binary long, little-endian, using 1-byte size. + + This first reads one byte as an unsigned size, then reads that + many bytes and interprets them as a little-endian long. + """) + + def read_long2(f): + r""" + >>> import StringIO + >>> read_long2(StringIO.StringIO("\x02\x00\xff\x00")) + 255L + >>> read_long2(StringIO.StringIO("\x02\x00\xff\x7f")) + 32767L + >>> read_long2(StringIO.StringIO("\x02\x00\x00\xff")) + -256L + >>> read_long2(StringIO.StringIO("\x02\x00\x00\x80")) + -32768L + >>> + """ + + n = read_uint2(f) + data = f.read(n) + if len(data) != n: + raise ValueError("not enough data in stream to read long2") + return decode_long(data) + + long2 = ArgumentDescriptor( + name="long2", + n=TAKEN_FROM_ARGUMENT, + reader=read_long2, + doc="""A binary long, little-endian, using 2-byte size. + + This first reads two byte as an unsigned size, then reads that + many bytes and interprets them as a little-endian long. + """) + + def read_long4(f): + r""" + >>> import StringIO + >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\xff\x00")) + 255L + >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\xff\x7f")) + 32767L + >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\xff")) + -256L + >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\x80")) + -32768L + >>> + """ + + n = read_int4(f) + if n < 0: + raise ValueError("unicodestring4 byte count < 0: %d" % n) + data = f.read(n) + if len(data) != n: + raise ValueError("not enough data in stream to read long1") + return decode_long(data) + + long4 = ArgumentDescriptor( + name="long4", + n=TAKEN_FROM_ARGUMENT, + reader=read_long4, + doc="""A binary representation of a long, little-endian. + + This first reads four bytes as a signed size (but requires the + size to be >= 0), then reads that many bytes and interprets them + as a little-endian long. + """) + + ############################################################################## # Object descriptors. The stack used by the pickle machine holds objects, *************** *** 628,631 **** --- 745,753 ---- "a Python bool.") + pybool = StackObject( + name='bool', + obtype=(bool,), + doc="A Python bool object.") + pyfloat = StackObject( name='float', *************** *** 1437,1440 **** --- 1559,1728 ---- returns is pushed on the stack. See PERSID for more detail. """), + + # Protocol 2 opcodes + + I(name='PROTO', + code='\x80', + arg=uint1, + stack_before=[], + stack_after=[], + proto=2, + doc="""Protocol version indicator. + + For protocol 2 and above, a pickle must start with this opcode. + The argument is the protocol version, an int in range(2, 256). + """), + + I(name='NEWOBJ', + code='\x81', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[anyobject], + proto=2, + doc="""Build an object instance. + + The stack before should be thought of as containing a class + object followed by an argument tuple (the tuple being the stack + top). Call these cls and args. They are popped off the stack, + and the value returned by cls.__new__(cls, *args) is pushed back + onto the stack. + """), + + I(name='EXT1', + code='\x82', + arg=uint1, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + This code and the similar EXT2 and EXT4 allow using a registry + of popular objects that are pickled by name, typically classes. + It is envisioned that through a global negotiation and + registration process, third parties can set up a mapping between + ints and object names. + + In order to guarantee pickle interchangeability, the extension + code registry ought to be global, although a range of codes may + be reserved for private use. + """), + + I(name='EXT2', + code='\x83', + arg=uint2, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + See EXT1. + """), + + I(name='EXT4', + code='\x84', + arg=int4, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + See EXT1. + """), + + I(name='TUPLE1', + code='\x85', + arg=None, + stack_before=[anyobject], + stack_after=[pytuple], + proto=2, + doc="""One-tuple. + + This code pops one value off the stack and pushes a tuple of + length 1 whose one item is that value back onto it. IOW: + + stack[-1] = tuple(stack[-1:]) + """), + + I(name='TUPLE2', + code='\x86', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[pytuple], + proto=2, + doc="""One-tuple. + + This code pops two values off the stack and pushes a tuple + of length 2 whose items are those values back onto it. IOW: + + stack[-2:] = [tuple(stack[-2:])] + """), + + I(name='TUPLE3', + code='\x87', + arg=None, + stack_before=[anyobject, anyobject, anyobject], + stack_after=[pytuple], + proto=2, + doc="""One-tuple. + + This code pops three values off the stack and pushes a tuple + of length 3 whose items are those values back onto it. IOW: + + stack[-3:] = [tuple(stack[-3:])] + """), + + I(name='NEWTRUE', + code='\x88', + arg=None, + stack_before=[], + stack_after=[pybool], + proto=2, + doc="""True. + + Push True onto the stack."""), + + I(name='NEWFALSE', + code='\x89', + arg=None, + stack_before=[], + stack_after=[pybool], + proto=2, + doc="""True. + + Push False onto the stack."""), + + I(name="LONG1", + code='\x8a', + arg=long1, + stack_before=[], + stack_after=[pylong], + proto=2, + doc="""Long integer using one-byte length. + + A more efficient encoding of a Python long; the long1 encoding + says it all."""), + + I(name="LONG2", + code='\x8b', + arg=long2, + stack_before=[], + stack_after=[pylong], + proto=2, + doc="""Long integer using two-byte length. + + A more efficient encoding of a Python long; the long2 encoding + says it all."""), + + I(name="LONG4", + code='\x8c', + arg=long4, + stack_before=[], + stack_after=[pylong], + proto=2, + doc="""Long integer using found-byte length. + + A more efficient encoding of a Python long; the long4 encoding + says it all."""), + ] del I From gvanrossum@users.sourceforge.net Mon Jan 27 22:19:25 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 14:19:25 -0800 Subject: [Python-checkins] python/dist/src/Modules _ssl.c,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6971 Modified Files: _ssl.c Log Message: Support socket timeout in SSL, by Geoff Talvola. (SF patch #675750, to fix SF bug #675552.) Index: _ssl.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_ssl.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** _ssl.c 2 Aug 2002 02:27:13 -0000 1.8 --- _ssl.c 27 Jan 2003 22:19:21 -0000 1.9 *************** *** 303,310 **** --- 303,346 ---- } + /* If the socket has a timeout, do a select() on the socket. + The argument writing indicates the direction. + Return non-zero if the socket timed out, zero otherwise. + */ + static int + wait_for_timeout(PySocketSockObject *s, int writing) + { + fd_set fds; + struct timeval tv; + int rc; + + /* Nothing to do unless we're in timeout mode (not non-blocking) */ + if (s->sock_timeout <= 0.0) + return 0; + + /* Guard against closed socket */ + if (s->sock_fd < 0) + return 0; + + /* Construct the arguments to select */ + tv.tv_sec = (int)s->sock_timeout; + tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6); + FD_ZERO(&fds); + FD_SET(s->sock_fd, &fds); + + /* See if the socket is ready */ + if (writing) + rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv); + else + rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv); + + /* Return 1 on timeout, 0 otherwise */ + return rc == 0; + } + static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args) { char *data; int len; + int timedout; if (!PyArg_ParseTuple(args, "s#:write", &data, &len)) *************** *** 312,315 **** --- 348,358 ---- Py_BEGIN_ALLOW_THREADS + timedout = wait_for_timeout(self->Socket, 1); + Py_END_ALLOW_THREADS + if (timedout) { + PyErr_SetString(PySSLErrorObject, "The write operation timed out"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS len = SSL_write(self->ssl, data, len); Py_END_ALLOW_THREADS *************** *** 331,334 **** --- 374,378 ---- int count = 0; int len = 1024; + int timedout; if (!PyArg_ParseTuple(args, "|i:read", &len)) *************** *** 338,341 **** --- 382,392 ---- return NULL; + Py_BEGIN_ALLOW_THREADS + timedout = wait_for_timeout(self->Socket, 0); + Py_END_ALLOW_THREADS + if (timedout) { + PyErr_SetString(PySSLErrorObject, "The read operation timed out"); + return NULL; + } Py_BEGIN_ALLOW_THREADS count = SSL_read(self->ssl, PyString_AsString(buf), len); From gvanrossum@users.sourceforge.net Mon Jan 27 22:19:59 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 14:19:59 -0800 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.224,1.225 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv7347 Modified Files: ACKS Log Message: Support socket timeout in SSL, by Geoff Talvola. (SF patch #675750, to fix SF bug #675552.) Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.224 retrieving revision 1.225 diff -C2 -d -r1.224 -r1.225 *** ACKS 15 Jan 2003 11:53:13 -0000 1.224 --- ACKS 27 Jan 2003 22:19:55 -0000 1.225 *************** *** 517,520 **** --- 517,521 ---- Daniel Stutzbach Paul Swartz + Geoff Talvola William Tanksley Christian Tanzer From gvanrossum@users.sourceforge.net Mon Jan 27 22:22:54 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 14:22:54 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.629,1.630 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv9106 Modified Files: NEWS Log Message: Support socket timeout in SSL, by Geoff Talvola. (SF patch #675750, to fix SF bug #675552.) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.629 retrieving revision 1.630 diff -C2 -d -r1.629 -r1.630 *** NEWS 27 Jan 2003 18:51:48 -0000 1.629 --- NEWS 27 Jan 2003 22:22:50 -0000 1.630 *************** *** 27,30 **** --- 27,33 ---- ----------------- + - The SSL module now handles sockets with a timeout set correctly (SF + patch #675750, fixing SF bug #675552). + - A new module _iconv_codec has been added, to expose the iconv(3) library. From montanaro@users.sourceforge.net Mon Jan 27 22:33:43 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 27 Jan 2003 14:33:43 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv17244 Modified Files: pep-0304.txt Log Message: add a note about my ignorance of import hooks and how they relate to this pep. add posting date, as it's about to be announced to the unwashed masses... Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pep-0304.txt 23 Jan 2003 18:51:09 -0000 1.3 --- pep-0304.txt 27 Jan 2003 22:33:41 -0000 1.4 *************** *** 8,12 **** Content-Type: text/x-rst Created: 22-Jan-2003 ! Post-History: --- 8,12 ---- Content-Type: text/x-rst Created: 22-Jan-2003 ! Post-History: 27-Jan-2003 *************** *** 189,192 **** --- 189,196 ---- the current user or root. (Does this matter on Windows?) + - The interaction of this PEP with import hooks has not been + considered yet. In fact, the best way to implement this idea might + be as an import hook. See PEP 302. [5]_ + Examples *************** *** 275,278 **** --- 279,285 ---- .. [4] python-dev thread, Parallel pyc construction, Dubois (http://mail.python.org/pipermail/python-dev/2003-January/032060.html) + + .. [5] PEP 302, New Import Hooks, van Rossum and Moore + (http://www.python.org/dev/peps/pep-0302.html) From gvanrossum@users.sourceforge.net Mon Jan 27 22:48:00 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 14:48:00 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.78,1.79 pickletools.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25095 Modified Files: pickle.py pickletools.py Log Message: Begin the change from 'binary vs. text mode' to 'protocol 0, 1, 2'. The protocol now defaults to 1. Protocol 2 is still unimplemented. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -d -r1.78 -r1.79 *** pickle.py 27 Jan 2003 21:44:24 -0000 1.78 --- pickle.py 27 Jan 2003 22:47:45 -0000 1.79 *************** *** 37,42 **** "Unpickler", "dump", "dumps", "load", "loads"] ! format_version = "1.3" # File format version we write ! compatible_formats = ["1.0", "1.1", "1.2"] # Old format versions we can read mdumps = marshal.dumps --- 37,48 ---- "Unpickler", "dump", "dumps", "load", "loads"] ! # These are purely informational; no code usues these ! format_version = "2.0" # File format version we write ! compatible_formats = ["1.0", # Original protocol 0 ! "1.1", # Protocol 0 with class supprt added ! "1.2", # Original protocol 1 ! "1.3", # Protocol 1 with BINFLOAT added ! "2.0", # Protocol 2 ! ] # Old format versions we can read mdumps = marshal.dumps *************** *** 152,161 **** class Pickler: ! def __init__(self, file, bin = 0): """This takes a file-like object for writing a pickle data stream. ! The optional bin parameter if true, tells the pickler to use the more ! efficient binary pickle format, otherwise the ASCII format is used ! (this is the default). The file parameter must have a write() method that accepts a single --- 158,173 ---- class Pickler: ! def __init__(self, file, proto=1): """This takes a file-like object for writing a pickle data stream. ! The optional proto argument tells the pickler to use the given ! protocol; supported protocols are 0, 1, 2. The default ! protocol is 1 (in previous Python versions the default was 0). ! ! Protocol 1 is more efficient than protocol 0; protocol 2 is ! more efficient than protocol 1. Protocol 2 is not the default ! because it is not supported by older Python versions. ! ! XXX Protocol 2 is not yet implemented. The file parameter must have a write() method that accepts a single *************** *** 166,170 **** self.write = file.write self.memo = {} ! self.bin = bin def clear_memo(self): --- 178,183 ---- self.write = file.write self.memo = {} ! self.proto = proto ! self.bin = proto >= 1 def clear_memo(self): *************** *** 1071,1080 **** from StringIO import StringIO ! def dump(object, file, bin = 0): ! Pickler(file, bin).dump(object) ! def dumps(object, bin = 0): file = StringIO() ! Pickler(file, bin).dump(object) return file.getvalue() --- 1084,1093 ---- from StringIO import StringIO ! def dump(object, file, proto=1): ! Pickler(file, proto).dump(object) ! def dumps(object, proto=1): file = StringIO() ! Pickler(file, proto).dump(object) return file.getvalue() Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pickletools.py 27 Jan 2003 21:44:25 -0000 1.5 --- pickletools.py 27 Jan 2003 22:47:53 -0000 1.6 *************** *** 1903,1907 **** >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] ! >>> pik = pickle.dumps(x) >>> dis(pik) 0: ( MARK --- 1903,1907 ---- >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] ! >>> pik = pickle.dumps(x, 0) >>> dis(pik) 0: ( MARK *************** *** 1956,1960 **** >>> import random ! >>> dis(pickle.dumps(random.random)) 0: c GLOBAL 'random random' 15: p PUT 0 --- 1956,1960 ---- >>> import random ! >>> dis(pickle.dumps(random.random, 0)) 0: c GLOBAL 'random random' 15: p PUT 0 *************** *** 1962,1966 **** >>> x = [pickle.PicklingError()] * 2 ! >>> dis(pickle.dumps(x)) 0: ( MARK 1: l LIST (MARK at 0) --- 1962,1966 ---- >>> x = [pickle.PicklingError()] * 2 ! >>> dis(pickle.dumps(x, 0)) 0: ( MARK 1: l LIST (MARK at 0) *************** *** 2017,2021 **** >>> T[0][0] is T True ! >>> dis(pickle.dumps(L)) 0: ( MARK 1: l LIST (MARK at 0) --- 2017,2021 ---- >>> T[0][0] is T True ! >>> dis(pickle.dumps(L, 0)) 0: ( MARK 1: l LIST (MARK at 0) *************** *** 2044,2048 **** pickle would require the disassembler to emulate the stack. ! >>> dis(pickle.dumps(T)) 0: ( MARK 1: ( MARK --- 2044,2048 ---- pickle would require the disassembler to emulate the stack. ! >>> dis(pickle.dumps(T, 0)) 0: ( MARK 1: ( MARK From rhettinger@users.sourceforge.net Mon Jan 27 23:33:28 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 15:33:28 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.9,1.10 libitertools.tex,1.9,1.10 test_itertools.py,1.6,1.7 todo.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv27314 Modified Files: itertools.c libitertools.tex test_itertools.py todo.txt Log Message: Skip pointed out that loopzip() had unsavory qualities. Replaced it with a safer, cleaner izip(). Added doctest for examples in the library reference. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** itertools.c 27 Jan 2003 15:22:59 -0000 1.9 --- itertools.c 27 Jan 2003 23:33:26 -0000 1.10 *************** *** 1082,1086 **** ! /* loopzip object ************************************************************/ #include "Python.h" --- 1082,1086 ---- ! /* izip object ************************************************************/ #include "Python.h" *************** *** 1090,1102 **** long tuplesize; PyObject *ittuple; /* tuple of iterators */ ! PyObject *result; ! } loopzipobject; ! PyTypeObject loopzip_type; static PyObject * ! loopzip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! loopzipobject *lz; int i; PyObject *ittuple; /* tuple of iterators */ --- 1090,1101 ---- long tuplesize; PyObject *ittuple; /* tuple of iterators */ ! } izipobject; ! PyTypeObject izip_type; static PyObject * ! izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! izipobject *lz; int i; PyObject *ittuple; /* tuple of iterators */ *************** *** 1105,1109 **** if (tuplesize < 1) { PyErr_SetString(PyExc_TypeError, ! "loopzip() requires at least one sequence"); return NULL; } --- 1104,1108 ---- if (tuplesize < 1) { PyErr_SetString(PyExc_TypeError, ! "izip() requires at least one sequence"); return NULL; } *************** *** 1116,1120 **** if(ittuple == NULL) return NULL; ! for (i = 0; i < tuplesize; ++i) { PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *it = PyObject_GetIter(item); --- 1115,1119 ---- if(ittuple == NULL) return NULL; ! for (i=0; i < tuplesize; ++i) { PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *it = PyObject_GetIter(item); *************** *** 1122,1126 **** if (PyErr_ExceptionMatches(PyExc_TypeError)) PyErr_Format(PyExc_TypeError, ! "loopzip argument #%d must support iteration", i+1); Py_DECREF(ittuple); --- 1121,1125 ---- if (PyErr_ExceptionMatches(PyExc_TypeError)) PyErr_Format(PyExc_TypeError, ! "izip argument #%d must support iteration", i+1); Py_DECREF(ittuple); *************** *** 1130,1135 **** } ! /* create loopzipobject structure */ ! lz = (loopzipobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(ittuple); --- 1129,1134 ---- } ! /* create izipobject structure */ ! lz = (izipobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(ittuple); *************** *** 1139,1168 **** lz->tuplesize = tuplesize; - /* create result holder */ - lz->result = PyList_New(tuplesize); - if (lz->result == NULL) { - Py_DECREF(ittuple); - Py_DECREF(lz); - return NULL; - } - for (i=0 ; i < tuplesize ; i++) { - Py_INCREF(Py_None); - PyList_SET_ITEM(lz->result, i, Py_None); - } - return (PyObject *)lz; } static void ! loopzip_dealloc(loopzipobject *lz) { PyObject_GC_UnTrack(lz); Py_XDECREF(lz->ittuple); - Py_XDECREF(lz->result); lz->ob_type->tp_free(lz); } static int ! loopzip_traverse(loopzipobject *lz, visitproc visit, void *arg) { if (lz->ittuple) --- 1138,1154 ---- lz->tuplesize = tuplesize; return (PyObject *)lz; } static void ! izip_dealloc(izipobject *lz) { PyObject_GC_UnTrack(lz); Py_XDECREF(lz->ittuple); lz->ob_type->tp_free(lz); } static int ! izip_traverse(izipobject *lz, visitproc visit, void *arg) { if (lz->ittuple) *************** *** 1172,1192 **** static PyObject * ! loopzip_next(loopzipobject *lz) { int i; long tuplesize = lz->tuplesize; ! PyObject *result = lz->result; PyObject *it; PyObject *item; ! /* XXX: Add check that resultsize == tuplesize */ for (i=0 ; i < tuplesize ; i++) { - item = PyList_GET_ITEM(result, i); - Py_DECREF(item); it = PyTuple_GET_ITEM(lz->ittuple, i); item = PyIter_Next(it); if (item == NULL) return NULL; ! PyList_SET_ITEM(result, i, item); } Py_INCREF(result); --- 1158,1179 ---- static PyObject * ! izip_next(izipobject *lz) { int i; long tuplesize = lz->tuplesize; ! PyObject *result; PyObject *it; PyObject *item; ! result = PyTuple_New(tuplesize); ! if (result == NULL) ! return NULL; ! for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); item = PyIter_Next(it); if (item == NULL) return NULL; ! PyTuple_SET_ITEM(result, i, item); } Py_INCREF(result); *************** *** 1195,1199 **** static PyObject * ! loopzip_getiter(PyObject *lz) { Py_INCREF(lz); --- 1182,1186 ---- static PyObject * ! izip_getiter(PyObject *lz) { Py_INCREF(lz); *************** *** 1201,1225 **** } ! PyDoc_STRVAR(loopzip_doc, ! "loopzip(iter1 [,iter2 [...]]) --> loopzip object\n\ \n\ ! Return a loopzip object whose .next() method returns a list where\n\ the i-th element comes from the i-th iterable argument. The .next()\n\ ! method updates the returns the same list everytime until the shortest\n\ ! iterable in the argument sequence is exhausted and then it raises\n\ ! StopIteration. Works like the zip() function but consumes less memory.\n\ ! Unlike zip, it returns an iterator and the n-th return is a list rather\n\ ! than a tuple. It is appropriate for use in loops, but not for conversion\n\ ! to a list. For example: list(loopzip('abc')) returns a list of three\n\ ! identical sublists which is usually not what was intended."); ! PyTypeObject loopzip_type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "itertools.loopzip", /* tp_name */ ! sizeof(loopzipobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ ! (destructor)loopzip_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ --- 1188,1209 ---- } ! PyDoc_STRVAR(izip_doc, ! "izip(iter1 [,iter2 [...]]) --> izip object\n\ \n\ ! Return a izip object whose .next() method returns a tuple where\n\ the i-th element comes from the i-th iterable argument. The .next()\n\ ! method continues until the shortest iterable in the argument sequence\n\ ! is exhausted and then it raises StopIteration. Works like the zip()\n ! function but consumes less memory by returning an iterator instead of\n\ ! a list."); ! PyTypeObject izip_type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "itertools.izip", /* tp_name */ ! sizeof(izipobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ ! (destructor)izip_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ *************** *** 1238,1248 **** Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ ! loopzip_doc, /* tp_doc */ ! (traverseproc)loopzip_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)loopzip_getiter, /* tp_iter */ ! (iternextfunc)loopzip_next, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ --- 1222,1232 ---- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ ! izip_doc, /* tp_doc */ ! (traverseproc)izip_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)izip_getiter, /* tp_iter */ ! (iternextfunc)izip_next, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ *************** *** 1255,1259 **** 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ ! loopzip_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; --- 1239,1243 ---- 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ ! izip_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; *************** *** 1375,1380 **** \n\ Iterators terminating on the shortest input sequence:\n\ ! loopzip(p, q, ...) --> [p[0], q[0]], [p[1], q[1]], ... \n\ ! same list each time but with updated contents\n\ ifilter(pred, seq, invert=False) --> elements of seq where\n\ pred(elem) is True (or False if invert is set)\n\ --- 1359,1363 ---- \n\ Iterators terminating on the shortest input sequence:\n\ ! izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\ ifilter(pred, seq, invert=False) --> elements of seq where\n\ pred(elem) is True (or False if invert is set)\n\ *************** *** 1435,1442 **** PyModule_AddObject(m, "count", (PyObject *)&count_type); ! if (PyType_Ready(&loopzip_type) < 0) return; ! Py_INCREF(&loopzip_type); ! PyModule_AddObject(m, "loopzip", (PyObject *)&loopzip_type); if (PyType_Ready(&repeat_type) < 0) --- 1418,1425 ---- PyModule_AddObject(m, "count", (PyObject *)&count_type); ! if (PyType_Ready(&izip_type) < 0) return; ! Py_INCREF(&izip_type); ! PyModule_AddObject(m, "izip", (PyObject *)&izip_type); if (PyType_Ready(&repeat_type) < 0) Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** libitertools.tex 27 Jan 2003 15:42:54 -0000 1.9 --- libitertools.tex 27 Jan 2003 23:33:26 -0000 1.10 *************** *** 38,62 **** penalty. - \item Wherever straight-forward alternatives exist, the corresponding - tools in this module seek to meet a different need and are designed - for speed. In fact, the \emph{sole} justification for this module - being written in C is its speed advantage. - - For instance, the - \module{__builtins__} module has an easy-to-use, no surprises version - of \function(zip()). This module's corresponding function, - \function{loopzip()} returns an iterator rather than a full list. - Also, calls to the iterator return a mutable list rather than a tuple - and it returns the \emph{same} list on each pass. Used in a - \keyword{for} loop, \function{loopzip()} can be directly substituted - for \function{zip()} and run much faster. It has nearly zero - overhead since the looping is done in C code (bypassing Python's eval - loop); since it returns an iterator (saving the need to allocate a - list and append to it an element at a time); and since it reuses just - one output list (saving the time to allocate and build a tuple on - every pass). Though very fast, using \function{loopzip()} outside of - a \keyword{for} loop or other itertool can result in surprising - behavior and an unwelcome refresher lesson in mutability. - \item Another source of value comes from standardizing a core set of tools to avoid the readability and reliability problems that arise when many --- 38,41 ---- *************** *** 178,199 **** \end{funcdesc} ! \begin{funcdesc}{loopzip}{*iterables} Make an iterator that aggregates elements from each of the iterables. Like \function{zip()} except that it returns an iterator instead of ! a list and the individual elements are stored in a list rather than ! in a tuple. The \emph{same} list is used for each pass and only the ! contents are updated; hence, \function{loopzip()} is only appropriate ! in a \keyword{for} loop or other itertool. The iterator terminates ! with \exception{StopIteration} when the first of the iterables is ! exhausted. Equivalent to: \begin{verbatim} ! def loopzip(*iterables): ! iterables = map(iter, iterables) ! result = [None] * len(iterables) ! while True: ! for i in xrange(len(iterables)): ! result[i] = iterables[i].next() ! yield result \end{verbatim} \end{funcdesc} --- 157,171 ---- \end{funcdesc} ! \begin{funcdesc}{izip}{*iterables} Make an iterator that aggregates elements from each of the iterables. Like \function{zip()} except that it returns an iterator instead of ! a list. Equivalent to: \begin{verbatim} ! def izip(*iterables): ! iterables = map(iter, iterables) ! while True: ! result = [i.next() for i in iterables] ! yield tuple(result) \end{verbatim} \end{funcdesc} *************** *** 266,270 **** Hello ! >>> for checknum, amount in loopzip(count(1200), amounts): ... print 'Check %d is for $%.2f' % (checknum, amount) ... --- 238,242 ---- Hello ! >>> for checknum, amount in izip(count(1200), amounts): ... print 'Check %d is for $%.2f' % (checknum, amount) ... *************** *** 273,276 **** --- 245,249 ---- Check 1202 is for $823.14 + >>> import operator >>> bases = [2, 3, 5, 7] >>> powers = [2, 3, 4] *************** *** 278,281 **** --- 251,258 ---- ... print list(imap(operator.pow, bases, repeat(power))) ... + [4, 9, 25, 49] + [8, 27, 125, 343] + [16, 81, 625, 2401] + \end{verbatim} Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_itertools.py 27 Jan 2003 12:16:42 -0000 1.6 --- test_itertools.py 27 Jan 2003 23:33:26 -0000 1.7 *************** *** 19,27 **** self.assertRaises(TypeError, ifilter, isEven, [3], True, 4) ! def test_loopzip(self): ! ans = [(x,y) for x, y in loopzip('abc',count())] self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) ! self.assertEqual(list(loopzip('abc',count())), [['c', 2]] * 3) ! self.assertRaises(TypeError, loopzip) def test_repeat(self): --- 19,26 ---- self.assertRaises(TypeError, ifilter, isEven, [3], True, 4) ! def test_izip(self): ! ans = [(x,y) for x, y in izip('abc',count())] self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) ! self.assertRaises(TypeError, izip) def test_repeat(self): *************** *** 80,84 **** self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8]) ! def test_main(): suite = unittest.TestSuite() for testclass in (TestBasicOps, --- 79,126 ---- self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8]) ! libreftest = """ Doctest for examples in the library reference, libitertools.tex ! ! >>> for i in times(3): ! ... print "Hello" ! ... ! Hello ! Hello ! Hello ! ! >>> amounts = [120.15, 764.05, 823.14] ! >>> for checknum, amount in izip(count(1200), amounts): ! ... print 'Check %d is for $%.2f' % (checknum, amount) ! ... ! Check 1200 is for $120.15 ! Check 1201 is for $764.05 ! Check 1202 is for $823.14 ! ! >>> import operator ! >>> bases = [2, 3, 5, 7] ! >>> powers = [2, 3, 4] ! >>> for power in powers: ! ... print list(imap(operator.pow, bases, repeat(power))) ! ... ! [4, 9, 25, 49] ! [8, 27, 125, 343] ! [16, 81, 625, 2401] ! ! ! >>> def enumerate(s): ! ... return izip(count(), s) ! >>> def tabulate(f): ! ... return imap(f, count()) ! >>> def iteritems(d): ! ... return izip(d.iterkeys(), d.itervalues()) ! >>> def nth(s, n): ! ... return islice(n, n+1).next() ! ! ! """ ! ! __test__ = {'libreftest' : libreftest} ! ! def test_main(verbose=None): ! import test_itertools suite = unittest.TestSuite() for testclass in (TestBasicOps, *************** *** 86,90 **** suite.addTest(unittest.makeSuite(testclass)) test_support.run_suite(suite) if __name__ == "__main__": ! test_main() --- 128,133 ---- suite.addTest(unittest.makeSuite(testclass)) test_support.run_suite(suite) + test_support.run_doctest(test_itertools, verbose) if __name__ == "__main__": ! test_main(verbose=True) Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** todo.txt 27 Jan 2003 12:16:42 -0000 1.9 --- todo.txt 27 Jan 2003 23:33:26 -0000 1.10 *************** *** 1,2 **** --- 1,10 ---- + Comments from Skip and Jack: + func=None in map + provide in-line motivating examples + ? add default arg to times() + + Doctest: + make islice() python code perform the same as the C code + Add: iapply(func) ?? what did this do in SML *************** *** 12,16 **** Things dropped because they bug me: cycle(seqn) requires auxilliary storage (which is surprising ! behavior for iterators). This is best left for pure python. Things that just bug me: --- 20,26 ---- Things dropped because they bug me: cycle(seqn) requires auxilliary storage (which is surprising ! behavior for iterators). This is best left for pure python. ! loopzip(s1, s2, ...) returned mutuable lists which could be ! prone to creating hard-to-find errors. Things that just bug me: From rhettinger@users.sourceforge.net Mon Jan 27 23:34:17 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 15:34:17 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv28684 Modified Files: itertools.c Log Message: Missing backslash Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** itertools.c 27 Jan 2003 23:33:26 -0000 1.10 --- itertools.c 27 Jan 2003 23:34:15 -0000 1.11 *************** *** 1194,1198 **** the i-th element comes from the i-th iterable argument. The .next()\n\ method continues until the shortest iterable in the argument sequence\n\ ! is exhausted and then it raises StopIteration. Works like the zip()\n function but consumes less memory by returning an iterator instead of\n\ a list."); --- 1194,1198 ---- the i-th element comes from the i-th iterable argument. The .next()\n\ method continues until the shortest iterable in the argument sequence\n\ ! is exhausted and then it raises StopIteration. Works like the zip()\n\ function but consumes less memory by returning an iterator instead of\n\ a list."); From tim_one@users.sourceforge.net Mon Jan 27 23:51:13 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 15:51:13 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5445/Lib Modified Files: pickletools.py Log Message: decode_long(): Simplified the "is it negative?" test. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pickletools.py 27 Jan 2003 22:47:53 -0000 1.6 --- pickletools.py 27 Jan 2003 23:51:11 -0000 1.7 *************** *** 591,595 **** >>> decode_long("\x00\x80") -32768L ! >>> """ x = 0L --- 591,598 ---- >>> decode_long("\x00\x80") -32768L ! >>> decode_long("\x80") ! -128L ! >>> decode_long("\x7f") ! 127L """ x = 0L *************** *** 598,602 **** x |= long(ord(c)) << i i += 8L ! if i and (x & (1L << (i-1L))): x -= 1L << i return x --- 601,605 ---- x |= long(ord(c)) << i i += 8L ! if data and ord(c) >= 0x80: x -= 1L << i return x From tim_one@users.sourceforge.net Mon Jan 27 23:51:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 15:51:38 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5705/Lib Modified Files: pickletools.py Log Message: Whitespace normalization. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pickletools.py 27 Jan 2003 23:51:11 -0000 1.7 --- pickletools.py 27 Jan 2003 23:51:36 -0000 1.8 *************** *** 616,620 **** >>> read_long1(StringIO.StringIO("\x02\x00\x80")) -32768L ! >>> """ --- 616,620 ---- >>> read_long1(StringIO.StringIO("\x02\x00\x80")) -32768L ! >>> """ *************** *** 646,650 **** >>> read_long2(StringIO.StringIO("\x02\x00\x00\x80")) -32768L ! >>> """ --- 646,650 ---- >>> read_long2(StringIO.StringIO("\x02\x00\x00\x80")) -32768L ! >>> """ *************** *** 676,680 **** >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\x80")) -32768L ! >>> """ --- 676,680 ---- >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\x80")) -32768L ! >>> """ From tim_one@users.sourceforge.net Mon Jan 27 23:54:06 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 15:54:06 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv7305/Lib Modified Files: pickletools.py Log Message: Documented the 2's-comp business for the new long opcodes. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pickletools.py 27 Jan 2003 23:51:36 -0000 1.8 --- pickletools.py 27 Jan 2003 23:54:04 -0000 1.9 *************** *** 632,636 **** This first reads one byte as an unsigned size, then reads that ! many bytes and interprets them as a little-endian long. """) --- 632,636 ---- This first reads one byte as an unsigned size, then reads that ! many bytes and interprets them as a little-endian 2's-complement long. """) *************** *** 662,666 **** This first reads two byte as an unsigned size, then reads that ! many bytes and interprets them as a little-endian long. """) --- 662,666 ---- This first reads two byte as an unsigned size, then reads that ! many bytes and interprets them as a little-endian 2's-complement long. """) *************** *** 695,699 **** This first reads four bytes as a signed size (but requires the size to be >= 0), then reads that many bytes and interprets them ! as a little-endian long. """) --- 695,699 ---- This first reads four bytes as a signed size (but requires the size to be >= 0), then reads that many bytes and interprets them ! as a little-endian 2's-complement long. """) From tim_one@users.sourceforge.net Tue Jan 28 00:13:22 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:13:22 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.79,1.80 pickletools.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14951/Lib Modified Files: pickle.py pickletools.py Log Message: Removed the new LONG2 opcode: it's extravagant. If LONG1 isn't enough, then the embedded argument consumes at least 256 bytes. The difference between a 3-byte prefix (LONG2 + 2 bytes) and a 5-byte prefix (LONG4 + 4 bytes) is at worst less than 1%. Note that binary strings and binary Unicode strings also have only "size is 1 byte, or size is 4 bytes?" flavors, and I expect for the same reason. The only place a 2-byte thingie was used was in BININT2, where the 2 bytes make up the *entire* embedded argument (and now EXT2 also does this); that's a large savings over 4 bytes, because the total opcode+argument size is so small in the BININT2/EXT2 case. Removed the TAKEN_FROM_ARGUMENT "number of bytes" code, and bifurcated it into TAKEN_FROM_ARGUMENT1 and TAKEN_FROM_ARGUMENT4. Now there's enough info in ArgumentDescriptor objects to deduce the # of bytes consumed by each opcode. Rearranged the order in which proto2 opcodes are listed in pickle.py. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.79 retrieving revision 1.80 diff -C2 -d -r1.79 -r1.80 *** pickle.py 27 Jan 2003 22:47:45 -0000 1.79 --- pickle.py 28 Jan 2003 00:13:19 -0000 1.80 *************** *** 136,152 **** # Protocol 2 (not yet implemented) (XXX comments will be added later) - NEWOBJ = '\x81' PROTO = '\x80' ! EXT2 = '\x83' EXT1 = '\x82' ! TUPLE1 = '\x85' EXT4 = '\x84' ! TUPLE3 = '\x87' TUPLE2 = '\x86' ! NEWFALSE = '\x89' NEWTRUE = '\x88' ! LONG2 = '\x8b' LONG1 = '\x8a' ! LONG4 = '\x8c' --- 136,151 ---- # Protocol 2 (not yet implemented) (XXX comments will be added later) PROTO = '\x80' ! NEWOBJ = '\x81' EXT1 = '\x82' ! EXT2 = '\x83' EXT4 = '\x84' ! TUPLE1 = '\x85' TUPLE2 = '\x86' ! TUPLE3 = '\x87' NEWTRUE = '\x88' ! NEWFALSE = '\x89' LONG1 = '\x8a' ! LONG4 = '\x8b' Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pickletools.py 27 Jan 2003 23:54:04 -0000 1.9 --- pickletools.py 28 Jan 2003 00:13:19 -0000 1.10 *************** *** 126,130 **** # Represents the number of bytes consumed by a two-argument opcode where # the first argument gives the number of bytes in the second argument. ! TAKEN_FROM_ARGUMENT = -2 class ArgumentDescriptor(object): --- 126,131 ---- # Represents the number of bytes consumed by a two-argument opcode where # the first argument gives the number of bytes in the second argument. ! TAKEN_FROM_ARGUMENT1 = -2 # num bytes is 1-byte unsigned int ! TAKEN_FROM_ARGUMENT4 = -3 # num bytes is 4-byte signed little-endian int class ArgumentDescriptor(object): *************** *** 134,138 **** # length of argument, in bytes; an int; UP_TO_NEWLINE and ! # TAKEN_FROM_ARGUMENT are negative values for variable-length cases 'n', --- 135,140 ---- # length of argument, in bytes; an int; UP_TO_NEWLINE and ! # TAKEN_FROM_ARGUMENT{1,4} are negative values for variable-length ! # cases 'n', *************** *** 151,156 **** assert isinstance(n, int) and (n >= 0 or ! n is UP_TO_NEWLINE or ! n is TAKEN_FROM_ARGUMENT) self.n = n --- 153,159 ---- assert isinstance(n, int) and (n >= 0 or ! n in (UP_TO_NEWLINE, ! TAKEN_FROM_ARGUMENT1, ! TAKEN_FROM_ARGUMENT4)) self.n = n *************** *** 342,346 **** string4 = ArgumentDescriptor( name="string4", ! n=TAKEN_FROM_ARGUMENT, reader=read_string4, doc="""A counted string. --- 345,349 ---- string4 = ArgumentDescriptor( name="string4", ! n=TAKEN_FROM_ARGUMENT4, reader=read_string4, doc="""A counted string. *************** *** 371,375 **** string1 = ArgumentDescriptor( name="string1", ! n=TAKEN_FROM_ARGUMENT, reader=read_string1, doc="""A counted string. --- 374,378 ---- string1 = ArgumentDescriptor( name="string1", ! n=TAKEN_FROM_ARGUMENT1, reader=read_string1, doc="""A counted string. *************** *** 435,439 **** unicodestring4 = ArgumentDescriptor( name="unicodestring4", ! n=TAKEN_FROM_ARGUMENT, reader=read_unicodestring4, doc="""A counted Unicode string. --- 438,442 ---- unicodestring4 = ArgumentDescriptor( name="unicodestring4", ! n=TAKEN_FROM_ARGUMENT4, reader=read_unicodestring4, doc="""A counted Unicode string. *************** *** 627,631 **** long1 = ArgumentDescriptor( name="long1", ! n=TAKEN_FROM_ARGUMENT, reader=read_long1, doc="""A binary long, little-endian, using 1-byte size. --- 630,634 ---- long1 = ArgumentDescriptor( name="long1", ! n=TAKEN_FROM_ARGUMENT1, reader=read_long1, doc="""A binary long, little-endian, using 1-byte size. *************** *** 635,668 **** """) - def read_long2(f): - r""" - >>> import StringIO - >>> read_long2(StringIO.StringIO("\x02\x00\xff\x00")) - 255L - >>> read_long2(StringIO.StringIO("\x02\x00\xff\x7f")) - 32767L - >>> read_long2(StringIO.StringIO("\x02\x00\x00\xff")) - -256L - >>> read_long2(StringIO.StringIO("\x02\x00\x00\x80")) - -32768L - >>> - """ - - n = read_uint2(f) - data = f.read(n) - if len(data) != n: - raise ValueError("not enough data in stream to read long2") - return decode_long(data) - - long2 = ArgumentDescriptor( - name="long2", - n=TAKEN_FROM_ARGUMENT, - reader=read_long2, - doc="""A binary long, little-endian, using 2-byte size. - - This first reads two byte as an unsigned size, then reads that - many bytes and interprets them as a little-endian 2's-complement long. - """) - def read_long4(f): r""" --- 638,641 ---- *************** *** 689,693 **** long4 = ArgumentDescriptor( name="long4", ! n=TAKEN_FROM_ARGUMENT, reader=read_long4, doc="""A binary representation of a long, little-endian. --- 662,666 ---- long4 = ArgumentDescriptor( name="long4", ! n=TAKEN_FROM_ARGUMENT4, reader=read_long4, doc="""A binary representation of a long, little-endian. *************** *** 1706,1722 **** says it all."""), - I(name="LONG2", - code='\x8b', - arg=long2, - stack_before=[], - stack_after=[pylong], - proto=2, - doc="""Long integer using two-byte length. - - A more efficient encoding of a Python long; the long2 encoding - says it all."""), - I(name="LONG4", ! code='\x8c', arg=long4, stack_before=[], --- 1679,1684 ---- says it all."""), I(name="LONG4", ! code='\x8b', arg=long4, stack_before=[], From rhettinger@users.sourceforge.net Tue Jan 28 00:19:47 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:19:47 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.11,1.12 libitertools.tex,1.10,1.11 todo.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv24045 Modified Files: itertools.c libitertools.tex todo.txt Log Message: Rewrite python code for islice() to exactly match what is done in the C code and to pass the same unittests. Whitespace fix-up. Elimininate an unused test branch. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** itertools.c 27 Jan 2003 23:34:15 -0000 1.11 --- itertools.c 28 Jan 2003 00:19:45 -0000 1.12 *************** *** 386,390 **** lz->cnt++; } ! if (lz->stop != 0 && lz->cnt >= lz->stop) return NULL; item = PyIter_Next(lz->it); --- 386,390 ---- lz->cnt++; } ! if (lz->cnt >= lz->stop) return NULL; item = PyIter_Next(lz->it); Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** libitertools.tex 27 Jan 2003 23:33:26 -0000 1.10 --- libitertools.tex 28 Jan 2003 00:19:45 -0000 1.11 *************** *** 147,157 **** \begin{verbatim} ! def islice(func, iterable, *args): ! i = 0 ! for j in xrange(*args): ! while i != j: ! _ = iterable.next() ! i += 1 ! yield iterable.next() \end{verbatim} \end{funcdesc} --- 147,166 ---- \begin{verbatim} ! def islice(iterable, *args): ! iterable = iter(iterable) ! s = slice(*args) ! next = s.start or 0 ! stop = s.stop ! step = s.step or 1 ! cnt = 0 ! while True: ! while cnt < next: ! dummy = iterable.next() ! cnt += 1 ! if cnt >= stop: ! break ! yield iterable.next() ! cnt += 1 ! next += step \end{verbatim} \end{funcdesc} *************** *** 164,171 **** \begin{verbatim} def izip(*iterables): ! iterables = map(iter, iterables) ! while True: ! result = [i.next() for i in iterables] ! yield tuple(result) \end{verbatim} \end{funcdesc} --- 173,180 ---- \begin{verbatim} def izip(*iterables): ! iterables = map(iter, iterables) ! while True: ! result = [i.next() for i in iterables] ! yield tuple(result) \end{verbatim} \end{funcdesc} Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** todo.txt 27 Jan 2003 23:33:26 -0000 1.10 --- todo.txt 28 Jan 2003 00:19:45 -0000 1.11 *************** *** 4,10 **** ? add default arg to times() - Doctest: - make islice() python code perform the same as the C code - Add: iapply(func) ?? what did this do in SML --- 4,7 ---- From nnorwitz@users.sourceforge.net Tue Jan 28 00:20:43 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:20:43 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25339/Lib Modified Files: pickletools.py Log Message: Use proper function name in exception messages Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** pickletools.py 28 Jan 2003 00:13:19 -0000 1.10 --- pickletools.py 28 Jan 2003 00:20:41 -0000 1.11 *************** *** 654,661 **** n = read_int4(f) if n < 0: ! raise ValueError("unicodestring4 byte count < 0: %d" % n) data = f.read(n) if len(data) != n: ! raise ValueError("not enough data in stream to read long1") return decode_long(data) --- 654,661 ---- n = read_int4(f) if n < 0: ! raise ValueError("long4 byte count < 0: %d" % n) data = f.read(n) if len(data) != n: ! raise ValueError("not enough data in stream to read long4") return decode_long(data) From tim_one@users.sourceforge.net Tue Jan 28 00:22:16 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:22:16 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.80,1.81 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv26183/Lib Modified Files: pickle.py Log Message: Added one-line comments to the proto 2 opcodes. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.80 retrieving revision 1.81 diff -C2 -d -r1.80 -r1.81 *** pickle.py 28 Jan 2003 00:13:19 -0000 1.80 --- pickle.py 28 Jan 2003 00:22:12 -0000 1.81 *************** *** 134,151 **** FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py ! # Protocol 2 (not yet implemented) (XXX comments will be added later) ! PROTO = '\x80' ! NEWOBJ = '\x81' ! EXT1 = '\x82' ! EXT2 = '\x83' ! EXT4 = '\x84' ! TUPLE1 = '\x85' ! TUPLE2 = '\x86' ! TUPLE3 = '\x87' ! NEWTRUE = '\x88' ! NEWFALSE = '\x89' ! LONG1 = '\x8a' ! LONG4 = '\x8b' --- 134,151 ---- FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py ! # Protocol 2 (not yet implemented). ! PROTO = '\x80' # identify pickle protocol ! NEWOBJ = '\x81' # build object by applying cls.__new__ to argtuple ! EXT1 = '\x82' # push object from extension registry; 1-byte index ! EXT2 = '\x83' # ditto, but 2-byte index ! EXT4 = '\x84' # ditto, but 4-byte index ! TUPLE1 = '\x85' # build 1-tuple from stack top ! TUPLE2 = '\x86' # build 2-tuple from two topmost stack items ! TUPLE3 = '\x87' # build 3-tuple from three topmost stack items ! NEWTRUE = '\x88' # push True ! NEWFALSE = '\x89' # push False ! LONG1 = '\x8a' # push long from < 256 bytes ! LONG4 = '\x8b' # push really big long From tim_one@users.sourceforge.net Tue Jan 28 00:23:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:23:39 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.81,1.82 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv27194/Lib Modified Files: pickle.py Log Message: clear_memo(): Repaired grammar in docstring. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.81 retrieving revision 1.82 diff -C2 -d -r1.81 -r1.82 *** pickle.py 28 Jan 2003 00:22:12 -0000 1.81 --- pickle.py 28 Jan 2003 00:23:36 -0000 1.82 *************** *** 184,190 **** The memo is the data structure that remembers which objects the ! pickler has already seen, so that shared or recursive objects pickled ! by reference and not by value. This method is useful when re-using ! picklers. """ --- 184,190 ---- The memo is the data structure that remembers which objects the ! pickler has already seen, so that shared or recursive objects are ! pickled by reference and not by value. This method is useful when ! re-using picklers. """ From tim_one@users.sourceforge.net Tue Jan 28 00:24:45 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:24:45 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.82,1.83 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv27922/Lib Modified Files: pickle.py Log Message: Repaired grammar in new comment. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.82 retrieving revision 1.83 diff -C2 -d -r1.82 -r1.83 *** pickle.py 28 Jan 2003 00:23:36 -0000 1.82 --- pickle.py 28 Jan 2003 00:24:43 -0000 1.83 *************** *** 214,218 **** # convention. The only requirement is that the memo values be unique. # But there appears no advantage to any other scheme, and this ! # scheme allows the Unpickler memo to implemented as a plain (but # growable) array, indexed by memo key. d = id(obj) --- 214,218 ---- # convention. The only requirement is that the memo values be unique. # But there appears no advantage to any other scheme, and this ! # scheme allows the Unpickler memo to be implemented as a plain (but # growable) array, indexed by memo key. d = id(obj) From tim_one@users.sourceforge.net Tue Jan 28 00:26:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:26:17 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.83,1.84 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28964/Lib Modified Files: pickle.py Log Message: save_bool(): simplified. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.83 retrieving revision 1.84 diff -C2 -d -r1.83 -r1.84 *** pickle.py 28 Jan 2003 00:24:43 -0000 1.83 --- pickle.py 28 Jan 2003 00:26:14 -0000 1.84 *************** *** 359,366 **** def save_bool(self, object): ! if object: ! self.write(TRUE) ! else: ! self.write(FALSE) dispatch[bool] = save_bool --- 359,363 ---- def save_bool(self, object): ! self.write(object and TRUE or FALSE) dispatch[bool] = save_bool From tim_one@users.sourceforge.net Tue Jan 28 00:43:28 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:43:28 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.84,1.85 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv7404/Lib Modified Files: pickle.py Log Message: Added XXX about save()'s special-casing of tuples -- I don't get it. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.84 retrieving revision 1.85 diff -C2 -d -r1.84 -r1.85 *** pickle.py 28 Jan 2003 00:26:14 -0000 1.84 --- pickle.py 28 Jan 2003 00:43:26 -0000 1.85 *************** *** 256,259 **** --- 256,260 ---- t = type(object) + # XXX Why are tuples a special case here? if (t is TupleType) and (len(object) == 0): if self.bin: From tim_one@users.sourceforge.net Tue Jan 28 00:48:11 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 16:48:11 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.85,1.86 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv10017/Lib Modified Files: pickle.py Log Message: save(): Fiddled the control flow to put the normal case where it belongs. This is a much smaller change than it may appear: the bulk of the function merely got unindented by one level. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.85 retrieving revision 1.86 diff -C2 -d -r1.85 -r1.86 *** pickle.py 28 Jan 2003 00:43:26 -0000 1.85 --- pickle.py 28 Jan 2003 00:48:09 -0000 1.86 *************** *** 271,329 **** f = self.dispatch[t] except KeyError: ! try: ! issc = issubclass(t, TypeType) ! except TypeError: # t is not a class ! issc = 0 ! if issc: ! self.save_global(object) ! return try: ! reduce = dispatch_table[t] ! except KeyError: ! try: ! reduce = object.__reduce__ ! except AttributeError: ! raise PicklingError, \ ! "can't pickle %s object: %s" % (`t.__name__`, ! `object`) ! else: ! tup = reduce() else: ! tup = reduce(object) ! ! if type(tup) is StringType: ! self.save_global(object, tup) ! return ! if type(tup) is not TupleType: ! raise PicklingError, "Value returned by %s must be a " \ ! "tuple" % reduce ! l = len(tup) ! if (l != 2) and (l != 3): ! raise PicklingError, "tuple returned by %s must contain " \ ! "only two or three elements" % reduce ! callable = tup[0] ! arg_tup = tup[1] ! if l > 2: ! state = tup[2] ! else: ! state = None ! if type(arg_tup) is not TupleType and arg_tup is not None: ! raise PicklingError, "Second element of tuple returned " \ ! "by %s must be a tuple" % reduce ! self.save_reduce(callable, arg_tup, state) ! memo_len = len(memo) ! self.write(self.put(memo_len)) ! memo[d] = (memo_len, object) ! return ! f(self, object) def persistent_id(self, object): --- 271,332 ---- f = self.dispatch[t] except KeyError: ! pass ! else: ! f(self, object) ! return + # The dispatch table doesn't know about type t. + try: + issc = issubclass(t, TypeType) + except TypeError: # t is not a class + issc = 0 + if issc: + self.save_global(object) + return + + try: + reduce = dispatch_table[t] + except KeyError: try: ! reduce = object.__reduce__ ! except AttributeError: ! raise PicklingError, \ ! "can't pickle %s object: %s" % (`t.__name__`, ! `object`) else: ! tup = reduce() ! else: ! tup = reduce(object) ! if type(tup) is StringType: ! self.save_global(object, tup) ! return ! if type(tup) is not TupleType: ! raise PicklingError, "Value returned by %s must be a " \ ! "tuple" % reduce ! l = len(tup) ! if (l != 2) and (l != 3): ! raise PicklingError, "tuple returned by %s must contain " \ ! "only two or three elements" % reduce ! callable = tup[0] ! arg_tup = tup[1] ! if l > 2: ! state = tup[2] ! else: ! state = None ! if type(arg_tup) is not TupleType and arg_tup is not None: ! raise PicklingError, "Second element of tuple returned " \ ! "by %s must be a tuple" % reduce ! self.save_reduce(callable, arg_tup, state) ! memo_len = len(memo) ! self.write(self.put(memo_len)) ! memo[d] = (memo_len, object) def persistent_id(self, object): From tim_one@users.sourceforge.net Tue Jan 28 01:00:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:00:41 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.86,1.87 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv17145/Lib Modified Files: pickle.py Log Message: Several routines appeared to inline the guts of memoize(), possibly for some notion of low-level efficiency. Undid that, but left one routine alone: save_inst() claims it has a reason for not using memoize(). I don't understand that comment, so added an XXX comment there. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.86 retrieving revision 1.87 diff -C2 -d -r1.86 -r1.87 *** pickle.py 28 Jan 2003 00:48:09 -0000 1.86 --- pickle.py 28 Jan 2003 01:00:38 -0000 1.87 *************** *** 216,223 **** # scheme allows the Unpickler memo to be implemented as a plain (but # growable) array, indexed by memo key. - d = id(obj) memo_len = len(self.memo) self.write(self.put(memo_len)) ! self.memo[d] = memo_len, obj # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i. --- 216,222 ---- # scheme allows the Unpickler memo to be implemented as a plain (but # growable) array, indexed by memo key. memo_len = len(self.memo) self.write(self.put(memo_len)) ! self.memo[id(obj)] = memo_len, obj # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i. *************** *** 326,332 **** self.save_reduce(callable, arg_tup, state) ! memo_len = len(memo) ! self.write(self.put(memo_len)) ! memo[d] = (memo_len, object) def persistent_id(self, object): --- 325,329 ---- self.save_reduce(callable, arg_tup, state) ! self.memoize(object) def persistent_id(self, object): *************** *** 473,479 **** return ! memo_len = len(memo) ! self.write(TUPLE + self.put(memo_len)) ! memo[d] = (memo_len, object) dispatch[TupleType] = save_tuple --- 470,475 ---- return ! self.write(TUPLE) ! self.memoize(object) dispatch[TupleType] = save_tuple *************** *** 567,570 **** --- 563,569 ---- # This method does not use memoize() so that it can handle # the special case for non-binary mode. + # XXX What did that comment mean? That is, what "special case for + # XXX non-binary mode? It sure *looks* like nothing special is + # XXX happening in the INST case. memo_len = len(memo) if self.bin: *************** *** 613,620 **** (object, module, name)) ! memo_len = len(memo) ! write(GLOBAL + module + '\n' + name + '\n' + ! self.put(memo_len)) ! memo[id(object)] = (memo_len, object) dispatch[ClassType] = save_global dispatch[FunctionType] = save_global --- 612,617 ---- (object, module, name)) ! write(GLOBAL + module + '\n' + name + '\n') ! self.memoize(object) dispatch[ClassType] = save_global dispatch[FunctionType] = save_global From tim_one@users.sourceforge.net Tue Jan 28 01:03:12 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:03:12 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.87,1.88 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19136/Lib Modified Files: pickle.py Log Message: save_pers(): Switched the order of cases, to get rid of a "not", and to make the bin-vs-not-bin order consistent with what other routines try to do (they almost all handle the bin case first). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.87 retrieving revision 1.88 diff -C2 -d -r1.87 -r1.88 *** pickle.py 28 Jan 2003 01:00:38 -0000 1.87 --- pickle.py 28 Jan 2003 01:03:10 -0000 1.88 *************** *** 331,339 **** def save_pers(self, pid): ! if not self.bin: ! self.write(PERSID + str(pid) + '\n') ! else: self.save(pid) self.write(BINPERSID) def save_reduce(self, acallable, arg_tup, state = None): --- 331,339 ---- def save_pers(self, pid): ! if self.bin: self.save(pid) self.write(BINPERSID) + else: + self.write(PERSID + str(pid) + '\n') def save_reduce(self, acallable, arg_tup, state = None): From rhettinger@users.sourceforge.net Tue Jan 28 01:05:31 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:05:31 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.12,1.13 libitertools.tex,1.11,1.12 test_itertools.py,1.7,1.8 todo.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv20327 Modified Files: itertools.c libitertools.tex test_itertools.py todo.txt Log Message: Adopted Skip's suggestion to have imap(func, *args) accept a None value for func. Reduces the conceptual distance from map(). Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** itertools.c 28 Jan 2003 00:19:45 -0000 1.12 --- itertools.c 28 Jan 2003 01:05:28 -0000 1.13 *************** *** 668,671 **** --- 668,676 ---- numargs = PyTuple_Size(lz->iters); + if (lz->func == Py_None) { + argtuple = PyTuple_New(numargs); + if (argtuple == NULL) + return NULL; + } for (i=0 ; ifunc == Py_None) + return argtuple; return PyObject_Call(lz->func, argtuple, NULL); } Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** libitertools.tex 28 Jan 2003 00:19:45 -0000 1.11 --- libitertools.tex 28 Jan 2003 01:05:29 -0000 1.12 *************** *** 120,127 **** \begin{funcdesc}{imap}{func, *iterables} Make an iterator that computes the function using arguments from ! each of the iterables. Like \function{map()} except 1) that it returns ! an iterator instead of a list, 2) that it stops when the shortest ! iterable is exhausted instead of filling in \code{None} for shorter ! iterables, and 3) that it does not accept \code{None} for \var{func}. Equivalent to: --- 120,128 ---- \begin{funcdesc}{imap}{func, *iterables} Make an iterator that computes the function using arguments from ! each of the iterables. If \var{func} is set to \code{None}, then ! \function{imap()} returns the arguments as a tuple. Like ! \function{map()} except that it returns an iterator instead of a ! list and that it stops when the shortest iterable is exhausted ! instead of filling in \code{None} for shorter iterables. Equivalent to: *************** *** 131,135 **** while True: args = [i.next() for i in iterables] ! yield func(*args) \end{verbatim} \end{funcdesc} --- 132,139 ---- while True: args = [i.next() for i in iterables] ! if func is None: ! yield tuple(args) ! else: ! yield func(*args) \end{verbatim} \end{funcdesc} Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_itertools.py 27 Jan 2003 23:33:26 -0000 1.7 --- test_itertools.py 28 Jan 2003 01:05:29 -0000 1.8 *************** *** 37,40 **** --- 37,42 ---- self.assertEqual(list(imap(operator.pow, range(3), range(1,7))), [0**1, 1**2, 2**3]) + self.assertEqual(list(imap(None, 'abc', range(5))), + [('a',0),('b',1),('c',2)]) self.assertRaises(TypeError, imap) self.assertRaises(TypeError, imap, operator.neg) Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** todo.txt 28 Jan 2003 00:19:45 -0000 1.11 --- todo.txt 28 Jan 2003 01:05:29 -0000 1.12 *************** *** 1,4 **** Comments from Skip and Jack: - func=None in map provide in-line motivating examples ? add default arg to times() --- 1,3 ---- From tim_one@users.sourceforge.net Tue Jan 28 01:07:12 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:07:12 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.88,1.89 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv22106/Lib Modified Files: pickle.py Log Message: save_list(): removed unused local "memo". Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.88 retrieving revision 1.89 diff -C2 -d -r1.88 -r1.89 *** pickle.py 28 Jan 2003 01:03:10 -0000 1.88 --- pickle.py 28 Jan 2003 01:07:10 -0000 1.89 *************** *** 483,487 **** write = self.write save = self.save - memo = self.memo if self.bin: --- 483,486 ---- From tim_one@users.sourceforge.net Tue Jan 28 01:07:50 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:07:50 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.89,1.90 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv22482/Lib Modified Files: pickle.py Log Message: save_list(): removed unused local "d". Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.89 retrieving revision 1.90 diff -C2 -d -r1.89 -r1.90 *** pickle.py 28 Jan 2003 01:07:10 -0000 1.89 --- pickle.py 28 Jan 2003 01:07:48 -0000 1.90 *************** *** 479,484 **** def save_list(self, object): - d = id(object) - write = self.write save = self.save --- 479,482 ---- From tim_one@users.sourceforge.net Tue Jan 28 01:15:49 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:15:49 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.90,1.91 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv27565/Lib Modified Files: pickle.py Log Message: save_list(): Rewrote, to untangle the proto 0 from the proto 1 cases. The code is much easier to follow now, and I bet it's faster too. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -d -r1.90 -r1.91 *** pickle.py 28 Jan 2003 01:07:48 -0000 1.90 --- pickle.py 28 Jan 2003 01:15:46 -0000 1.91 *************** *** 484,505 **** if self.bin: write(EMPTY_LIST) ! else: ! write(MARK + LIST) ! ! self.memoize(object) ! ! using_appends = (self.bin and (len(object) > 1)) ! ! if using_appends: ! write(MARK) ! ! for element in object: ! save(element) ! if not using_appends: write(APPEND) - if using_appends: - write(APPENDS) dispatch[ListType] = save_list --- 484,507 ---- if self.bin: write(EMPTY_LIST) ! self.memoize(object) ! n = len(object) ! if n > 1: ! write(MARK) ! for element in object: ! save(element) ! write(APPENDS) ! elif n: ! assert n == 1 ! save(object[0]) ! write(APPEND) ! # else the list is empty, and we're already done ! else: # proto 0 -- can't use EMPTY_LIST or APPENDS ! write(MARK + LIST) ! self.memoize(object) ! for element in object: ! save(element) write(APPEND) dispatch[ListType] = save_list From tim_one@users.sourceforge.net Tue Jan 28 01:34:48 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:34:48 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.91,1.92 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv7730/Lib Modified Files: pickle.py Log Message: save_dict(): Untangled most of the bin-vs-not-bin logic. Also used iteritems() instead of materializing a (possibly giant) list of the items. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** pickle.py 28 Jan 2003 01:15:46 -0000 1.91 --- pickle.py 28 Jan 2003 01:34:43 -0000 1.92 *************** *** 509,535 **** write = self.write save = self.save if self.bin: write(EMPTY_DICT) ! else: ! write(MARK + DICT) ! ! self.memoize(object) ! ! using_setitems = (self.bin and (len(object) > 1)) ! if using_setitems: ! write(MARK) ! items = object.items() for key, value in items: save(key) save(value) ! ! if not using_setitems: ! write(SETITEM) ! ! if using_setitems: ! write(SETITEMS) dispatch[DictionaryType] = save_dict --- 509,534 ---- write = self.write save = self.save + items = object.iteritems() if self.bin: write(EMPTY_DICT) ! self.memoize(object) ! if len(object) > 1: ! write(MARK) ! for key, value in items: ! save(key) ! save(value) ! write(SETITEMS) ! return ! else: # proto 0 -- can't use EMPTY_DICT or SETITEMS ! write(MARK + DICT) ! self.memoize(object) ! # proto 0 or len(object) < 2 for key, value in items: save(key) save(value) ! write(SETITEM) dispatch[DictionaryType] = save_dict From tim_one@users.sourceforge.net Tue Jan 28 01:41:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:41:53 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.92,1.93 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv12765/Lib Modified Files: pickle.py Log Message: Comments. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.92 retrieving revision 1.93 diff -C2 -d -r1.92 -r1.93 *** pickle.py 28 Jan 2003 01:34:43 -0000 1.92 --- pickle.py 28 Jan 2003 01:41:51 -0000 1.93 *************** *** 562,566 **** # the special case for non-binary mode. # XXX What did that comment mean? That is, what "special case for ! # XXX non-binary mode? It sure *looks* like nothing special is # XXX happening in the INST case. memo_len = len(memo) --- 562,566 ---- # the special case for non-binary mode. # XXX What did that comment mean? That is, what "special case for ! # XXX non-binary mode"? It sure *looks* like nothing special is # XXX happening in the INST case. memo_len = len(memo) *************** *** 700,703 **** --- 700,711 ---- return stopinst.value + # Return largest index k such that self.stack[k] is self.mark. + # If the stack doesn't contain a mark, eventually raises IndexError. + # This could be sped by maintaining another stack, of indices at which + # the mark appears. For that matter, the latter stack would suffice, + # and we wouldn't need to push mark objects on self.stack at all. + # Doing so is probably a good thing, though, since if the pickle is + # corrupt (or hostile) we may get a clue from finding self.mark embedded + # in unpickled objects. def marker(self): stack = self.stack From tim_one@users.sourceforge.net Tue Jan 28 01:44:47 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 17:44:47 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.93,1.94 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14327/Lib Modified Files: pickle.py Log Message: load_appends(): replaced .append() loop with an .extend(). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -d -r1.93 -r1.94 *** pickle.py 28 Jan 2003 01:41:51 -0000 1.93 --- pickle.py 28 Jan 2003 01:44:45 -0000 1.94 *************** *** 1022,1028 **** mark = self.marker() list = stack[mark - 1] ! for i in range(mark + 1, len(stack)): ! list.append(stack[i]) ! del stack[mark:] dispatch[APPENDS] = load_appends --- 1022,1026 ---- mark = self.marker() list = stack[mark - 1] ! list.extend(stack[mark + 1:]) del stack[mark:] dispatch[APPENDS] = load_appends From rhettinger@users.sourceforge.net Tue Jan 28 02:02:29 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 18:02:29 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.12,1.13 test_itertools.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv24656 Modified Files: libitertools.tex test_itertools.py Log Message: Sync-up python definition of ifilter() with the C definition. Make the related docstrings match and added a test for the case where func is None. Fixed spelling in docs. Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** libitertools.tex 28 Jan 2003 01:05:29 -0000 1.12 --- libitertools.tex 28 Jan 2003 02:02:25 -0000 1.13 *************** *** 23,27 **** For instance, SML provides a tabulation tool: \code{tabulate(\var{f})} which produces a sequence \code{f(0), f(1), ...}. This toolbox ! takes a diffenct approach of providing \function{imap()} and \function{count()} which can be combined to form \code{imap(\var{f}, count())} and produce an equivalent result. --- 23,27 ---- For instance, SML provides a tabulation tool: \code{tabulate(\var{f})} which produces a sequence \code{f(0), f(1), ...}. This toolbox ! takes a different approach of providing \function{imap()} and \function{count()} which can be combined to form \code{imap(\var{f}, count())} and produce an equivalent result. *************** *** 34,38 **** loops over the sequence elements and then starts again when the sequence is exhausted. The surprising behavior is the need for ! significant auxilliary storage (unusual for iterators). Also, it is trivially implemented in python with almost no performance penalty. --- 34,38 ---- loops over the sequence elements and then starts again when the sequence is exhausted. The surprising behavior is the need for ! significant auxiliary storage (unusual for iterators). Also, it is trivially implemented in python with almost no performance penalty. *************** *** 105,108 **** --- 105,111 ---- is \code{True}, then reverse the process and pass through only those elements for which the function evaluates to \code{False}. + If function is \code{None}, return the items that are true (unless + \var{invert} is set). + Equivalent to: *************** *** 112,116 **** while True: x = iterable.next() ! b = bool(func(x)) if not invert and b or invert and not b: yield x --- 115,122 ---- while True: x = iterable.next() ! if func is None: ! b = bool(x) ! else: ! b = bool(func(x)) if not invert and b or invert and not b: yield x *************** *** 141,145 **** \begin{funcdesc}{islice}{iterable, \optional{start,} stop \optional{, step}} Make an iterator that returns selected elements from the iterable. ! If \var{start} is non-zero, then elements from the iterable are skiped until start is reached. Afterward, elements are returned consecutively unless \var{step} is set higher than one which results in items being --- 147,151 ---- \begin{funcdesc}{islice}{iterable, \optional{start,} stop \optional{, step}} Make an iterator that returns selected elements from the iterable. ! If \var{start} is non-zero, then elements from the iterable are skipped until start is reached. Afterward, elements are returned consecutively unless \var{step} is set higher than one which results in items being Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_itertools.py 28 Jan 2003 01:05:29 -0000 1.8 --- test_itertools.py 28 Jan 2003 02:02:26 -0000 1.9 *************** *** 14,17 **** --- 14,18 ---- self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4]) self.assertEqual(list(ifilter(isEven, range(6), True)), [1,3,5]) + self.assertEqual(list(ifilter(None, [0,1,0,2,0])), [1,2]) self.assertRaises(TypeError, ifilter) self.assertRaises(TypeError, ifilter, 3) From montanaro@users.sourceforge.net Tue Jan 28 02:06:25 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 27 Jan 2003 18:06:25 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv - New directory Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv27738/csv Log Message: Directory /cvsroot/python/python/nondist/sandbox/csv added to the repository From montanaro@users.sourceforge.net Tue Jan 28 02:07:49 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Mon, 27 Jan 2003 18:07:49 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv README,NONE,1.1 _csv.c,NONE,1.1 csv.py,NONE,1.1 setup.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv28413 Added Files: README _csv.c csv.py setup.py Log Message: initial placeholders --- NEW FILE: README --- This little corner of the sandbox aims to create a module to read and write CSV files. Involved parties are currently Kevin Altis, Dave Cole, Skip Montanaro and Cliff Wells. Stay tuned... --- NEW FILE: _csv.c --- /* placeholder */ --- NEW FILE: csv.py --- # placeholder --- NEW FILE: setup.py --- # placeholder From tim_one@users.sourceforge.net Tue Jan 28 02:09:58 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 18:09:58 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.94,1.95 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv29045/Lib Modified Files: pickle.py Log Message: save_tuple(): Minor rewriting, and added a comment about the subtlety created by recursive tuples. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.94 retrieving revision 1.95 diff -C2 -d -r1.94 -r1.95 *** pickle.py 28 Jan 2003 01:44:45 -0000 1.94 --- pickle.py 28 Jan 2003 02:09:55 -0000 1.95 *************** *** 455,473 **** memo = self.memo - d = id(object) - write(MARK) - for element in object: save(element) ! if len(object) and d in memo: if self.bin: ! write(POP_MARK + self.get(memo[d][0])) ! return ! ! write(POP * (len(object) + 1) + self.get(memo[d][0])) return self.write(TUPLE) self.memoize(object) --- 455,478 ---- memo = self.memo write(MARK) for element in object: save(element) ! if object and id(object) in memo: ! # Subtle. d was not in memo when we entered save_tuple(), so ! # the process of saving the tuple's elements must have saved ! # the tuple itself: the tuple is recursive. The proper action ! # now is to throw away everything we put on the stack, and ! # simply GET the tuple (it's already constructed). This check ! # could have been done in the "for element" loop instead, but ! # recursive tuples are a rare thing. ! get = self.get(memo[id(object)][0]) if self.bin: ! write(POP_MARK + get) ! else: # proto 0 -- POP_MARK not available ! write(POP * (len(object) + 1) + get) return + # No recursion (including the empty-tuple case). self.write(TUPLE) self.memoize(object) From rhettinger@users.sourceforge.net Tue Jan 28 02:16:16 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 27 Jan 2003 18:16:16 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv965 Modified Files: itertools.c Log Message: Fix-up docstrings. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** itertools.c 28 Jan 2003 01:05:28 -0000 1.13 --- itertools.c 28 Jan 2003 02:16:13 -0000 1.14 *************** *** 239,245 **** PyDoc_STRVAR(takewhile_doc, ! "takewhile(predicate, sequence) --> takewhile object\n\ \n\ ! Return those items of sequence while the predicate is true."); PyTypeObject takewhile_type = { --- 239,246 ---- PyDoc_STRVAR(takewhile_doc, ! "takewhile(predicate, iterable) --> takewhile object\n\ \n\ ! Return successive entries from an iterable as long as the \n\ ! predicate evaluates to true for each entry."); PyTypeObject takewhile_type = { *************** *** 404,411 **** PyDoc_STRVAR(islice_doc, ! "islice(function, sequence) --> islice object\n\ \n\ ! Return an iterator whose values are returned from the function evaluated\n\ ! with a argument tuple taken from the given sequence."); PyTypeObject islice_type = { --- 405,416 ---- PyDoc_STRVAR(islice_doc, ! "islice(iterable, [start,] stop [, step]) --> islice object\n\ \n\ ! Return an iterator whose next() method returns selected values from an\n\ ! iterable. If start is specified, will skip all preceding elements;\n\ ! otherwise, start defaults to zero. Step defaults to one. If\n\ ! specified as another value, step determines how many values are \n\ ! skipped between successive calls. Works like a slice() on a list\n\ ! but returns an iterator."); PyTypeObject islice_type = { *************** *** 696,703 **** \n\ Make an iterator that computes the function using arguments from\n\ ! each of the iterables. Like map() except 1) that it returns\n\ ! an iterator instead of a list, 2) that it stops when the shortest\n\ iterable is exhausted instead of filling in None for shorter\n\ ! iterables, and 3) that it does not accept None for func."); PyTypeObject imap_type = { --- 701,708 ---- \n\ Make an iterator that computes the function using arguments from\n\ ! each of the iterables. Like map() except that it returns\n\ ! an iterator instead of a list and that it stops when the shortest\n\ iterable is exhausted instead of filling in None for shorter\n\ ! iterables."); PyTypeObject imap_type = { From gvanrossum@users.sourceforge.net Tue Jan 28 03:03:12 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 19:03:12 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.95,1.96 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv27673 Modified Files: pickle.py Log Message: Got rid of mdumps; I timed it, and struct.pack("> 31 # note that Python shift sign-extends if high_bits == 0 or high_bits == -1: # All high bits are copies of bit 2**31, so the value # fits in a 4-byte signed int. ! i = mdumps(object)[1:] ! assert len(i) == 4 ! if i[-2:] == '\000\000': # fits in 2-byte unsigned int ! if i[-3] == '\000': # fits in 1-byte unsigned int ! self.write(BININT1 + i[0]) ! else: ! self.write(BININT2 + i[:2]) ! else: ! self.write(BININT + i) return # Text pickle, or int too big to fit in signed 4-byte format. --- 359,381 ---- dispatch[bool] = save_bool ! def save_int(self, object, pack=struct.pack): if self.bin: # If the int is small enough to fit in a signed 4-byte 2's-comp # format, we can store it more efficiently than the general # case. + # First one- and two-byte unsigned ints: + if object >= 0: + if object < 0xff: + self.write(BININT1 + chr(object)) + return + if object < 0xffff: + self.write(BININT2 + chr(object&0xff) + chr(object>>8)) + return + # Next check for 4-byte signed ints: high_bits = object >> 31 # note that Python shift sign-extends if high_bits == 0 or high_bits == -1: # All high bits are copies of bit 2**31, so the value # fits in a 4-byte signed int. ! self.write(BININT + pack(" References: Message-ID: <20030128030418.GG24222@epoch.metaslash.com> > ! using_setitems = (self.bin and (len(object) > 1)) > > ! if using_setitems: > ! write(MARK) > > ! items = object.items() > for key, value in items: > save(key) > save(value) > ! > ! if not using_setitems: > ! write(SETITEM) > ! > ! if using_setitems: > ! write(SETITEMS) > > dispatch[DictionaryType] = save_dict > --- 509,534 ---- > write = self.write > save = self.save > + items = object.iteritems() > > if self.bin: > write(EMPTY_DICT) > ! self.memoize(object) > ! if len(object) > 1: > ! write(MARK) > ! for key, value in items: > ! save(key) > ! save(value) > ! write(SETITEMS) > ! return In the case where self.bin and len(object) == 1, the code looks like it does something different. The old code would save(key) & save(value) since the for loop is executed. The new code doesn't execute the loop though. Am I missing something? Neal From gvanrossum@users.sourceforge.net Tue Jan 28 03:17:23 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 19:17:23 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.96,1.97 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv4351 Modified Files: pickle.py Log Message: Add a comment explaining that struct.pack() beats marshal.dumps(), but marshal.loads() beats struct.unpack()! Possibly because the latter creates a one-tuple. :-( Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -d -r1.96 -r1.97 *** pickle.py 28 Jan 2003 03:03:08 -0000 1.96 --- pickle.py 28 Jan 2003 03:17:21 -0000 1.97 *************** *** 46,49 **** --- 46,52 ---- ] # Old format versions we can read + # Why use struct.pack() for pickling but marshal.loads() for + # unpickling? struct.pack() is 40% faster than marshal.loads(), but + # marshal.loads() is twice as fast as struct.unpack()! mloads = marshal.loads From guido@python.org Tue Jan 28 03:21:57 2003 From: guido@python.org (Guido van Rossum) Date: Mon, 27 Jan 2003 22:21:57 -0500 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.91,1.92 In-Reply-To: Your message of "Mon, 27 Jan 2003 22:04:18 EST." <20030128030418.GG24222@epoch.metaslash.com> References: <20030128030418.GG24222@epoch.metaslash.com> Message-ID: <200301280321.h0S3LvH05050@pcp02138704pcs.reston01.va.comcast.net> > > ! using_setitems = (self.bin and (len(object) > 1)) > > > > ! if using_setitems: > > ! write(MARK) > > > > ! items = object.items() > > for key, value in items: > > save(key) > > save(value) > > ! > > ! if not using_setitems: > > ! write(SETITEM) > > ! > > ! if using_setitems: > > ! write(SETITEMS) > > > > dispatch[DictionaryType] = save_dict > > --- 509,534 ---- > > write = self.write > > save = self.save > > + items = object.iteritems() > > > > if self.bin: > > write(EMPTY_DICT) > > ! self.memoize(object) > > ! if len(object) > 1: > > ! write(MARK) > > ! for key, value in items: > > ! save(key) > > ! save(value) > > ! write(SETITEMS) > > ! return > > In the case where self.bin and len(object) == 1, the code looks > like it does something different. > > The old code would save(key) & save(value) since the for loop is > executed. The new code doesn't execute the loop though. > > Am I missing something? It falls through to the next block: # proto 0 or len(object) < 2 for key, value in items: save(key) save(value) write(SETITEM) --Guido van Rossum (home page: http://www.python.org/~guido/) From tim.one@comcast.net Tue Jan 28 03:33:27 2003 From: tim.one@comcast.net (Tim Peters) Date: Mon, 27 Jan 2003 22:33:27 -0500 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.91,1.92 In-Reply-To: <20030128030418.GG24222@epoch.metaslash.com> Message-ID: [Neal Norwitz, on save_dict() rewrite] > In the case where self.bin and len(object) == 1, the code looks > like it does something different. > > The old code would save(key) & save(value) since the for loop is > executed. The new code doesn't execute the loop though. > > Am I missing something? Guido explained this already. It makes me wonder whether I shouldn't duplicate that block of code, though -- the point of these rewrites was largely to make the code more evident, by eliminating mounds of fiddly little "internal" branches. I originally did duplicate the loop, but it was such blatant code duplication then that I nuked the first copy and let it fall thru instead. IOW, I can't win this one . From tim_one@users.sourceforge.net Tue Jan 28 03:40:54 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 19:40:54 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.97,1.98 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19264/Lib Modified Files: pickle.py Log Message: save_int(): Fixed two new off-by-1 glitches. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -d -r1.97 -r1.98 *** pickle.py 28 Jan 2003 03:17:21 -0000 1.97 --- pickle.py 28 Jan 2003 03:40:52 -0000 1.98 *************** *** 369,376 **** # First one- and two-byte unsigned ints: if object >= 0: ! if object < 0xff: self.write(BININT1 + chr(object)) return ! if object < 0xffff: self.write(BININT2 + chr(object&0xff) + chr(object>>8)) return --- 369,376 ---- # First one- and two-byte unsigned ints: if object >= 0: ! if object <= 0xff: self.write(BININT1 + chr(object)) return ! if object <= 0xffff: self.write(BININT2 + chr(object&0xff) + chr(object>>8)) return From tim_one@users.sourceforge.net Tue Jan 28 03:41:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 19:41:56 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.98,1.99 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19906/Lib Modified Files: pickle.py Log Message: Fixed odd whitespace after "if", which I believe I introduced long ago. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -d -r1.98 -r1.99 *** pickle.py 28 Jan 2003 03:40:52 -0000 1.98 --- pickle.py 28 Jan 2003 03:41:54 -0000 1.99 *************** *** 377,381 **** # Next check for 4-byte signed ints: high_bits = object >> 31 # note that Python shift sign-extends ! if high_bits == 0 or high_bits == -1: # All high bits are copies of bit 2**31, so the value # fits in a 4-byte signed int. --- 377,381 ---- # Next check for 4-byte signed ints: high_bits = object >> 31 # note that Python shift sign-extends ! if high_bits == 0 or high_bits == -1: # All high bits are copies of bit 2**31, so the value # fits in a 4-byte signed int. From gvanrossum@users.sourceforge.net Tue Jan 28 03:49:55 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 19:49:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25222/test Modified Files: pickletester.py Log Message: First baby steps towards implementing protocol 2: PROTO, LONG1 and LONG4. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** pickletester.py 13 Nov 2002 22:10:47 -0000 1.20 --- pickletester.py 28 Jan 2003 03:49:52 -0000 1.21 *************** *** 268,271 **** --- 268,285 ---- self.assertEqual(t, u) + # Tests for protocol 2 + + def test_long1(self): + x = 12345678910111213141516178920L + s = self.dumps(x, 2) + y = self.loads(s) + self.assertEqual(x, y) + + def test_long4(self): + x = 12345678910111213141516178920L << (256*8) + s = self.dumps(x, 2) + y = self.loads(s) + self.assertEqual(x, y) + class AbstractPickleModuleTests(unittest.TestCase): From gvanrossum@users.sourceforge.net Tue Jan 28 03:49:54 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 19:49:54 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.99,1.100 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25222 Modified Files: pickle.py Log Message: First baby steps towards implementing protocol 2: PROTO, LONG1 and LONG4. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.99 retrieving revision 1.100 diff -C2 -d -r1.99 -r1.100 *** pickle.py 28 Jan 2003 03:41:54 -0000 1.99 --- pickle.py 28 Jan 2003 03:49:52 -0000 1.100 *************** *** 177,180 **** --- 177,182 ---- """ + if not 0 <= proto <= 2: + raise ValueError, "pickle protocol must be 0, 1 or 2" self.write = file.write self.memo = {} *************** *** 200,203 **** --- 202,207 ---- """ + if self.proto >= 2: + self.write(PROTO + chr(self.proto)) self.save(object) self.write(STOP) *************** *** 386,390 **** dispatch[IntType] = save_int ! def save_long(self, object): self.write(LONG + `object` + '\n') dispatch[LongType] = save_long --- 390,401 ---- dispatch[IntType] = save_int ! def save_long(self, object, pack=struct.pack): ! if self.proto >= 2: ! bytes = encode_long(object) ! n = len(bytes) ! if n < 256: ! self.write(LONG1 + chr(n) + bytes) ! else: ! self.write(LONG4 + pack(">> encode_long(255L) + '\xff\x00' + >>> encode_long(32767L) + '\xff\x7f' + >>> encode_long(-256L) + '\x00\xff' + >>> encode_long(-32768L) + '\x00\x80' + >>> encode_long(-128L) + '\x80' + >>> encode_long(127L) + '\x7f' + >>> + """ + digits = [] + while not -128 <= x < 128: + digits.append(x & 0xff) + x >>= 8 + digits.append(x & 0xff) + return "".join(map(chr, digits)) + + def decode_long(data): + r"""Decode a long from a two's complement little-endian binary string. + >>> decode_long("\xff\x00") + 255L + >>> decode_long("\xff\x7f") + 32767L + >>> decode_long("\x00\xff") + -256L + >>> decode_long("\x00\x80") + -32768L + >>> decode_long("\x80") + -128L + >>> decode_long("\x7f") + 127L + """ + x = 0L + i = 0L + for c in data: + x |= long(ord(c)) << i + i += 8L + if data and ord(c) >= 0x80: + x -= 1L << i + return x + # Shorthands *************** *** 1103,1104 **** --- 1181,1191 ---- file = StringIO(str) return Unpickler(file).load() + + # Doctest + + def _test(): + import doctest + return doctest.testmod() + + if __name__ == "__main__": + _test() From tim_one@users.sourceforge.net Tue Jan 28 03:51:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 19:51:38 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.100,1.101 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv26041/Lib Modified Files: pickle.py Log Message: save_inst(): Rewrote to have only one branch on self.bin. Also got rid of my recent XXX comment, taking a (what appears to be vanishingly small) chance and calling self.memoize() instead. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -d -r1.100 -r1.101 *** pickle.py 28 Jan 2003 03:49:52 -0000 1.100 --- pickle.py 28 Jan 2003 03:51:36 -0000 1.101 *************** *** 552,556 **** def save_inst(self, object): - d = id(object) cls = object.__class__ --- 552,555 ---- *************** *** 570,590 **** if self.bin: save(cls) ! ! for arg in args: ! save(arg) ! ! # This method does not use memoize() so that it can handle ! # the special case for non-binary mode. ! # XXX What did that comment mean? That is, what "special case for ! # XXX non-binary mode"? It sure *looks* like nothing special is ! # XXX happening in the INST case. ! memo_len = len(memo) ! if self.bin: ! write(OBJ + self.put(memo_len)) else: ! write(INST + cls.__module__ + '\n' + cls.__name__ + '\n' + ! self.put(memo_len)) ! memo[d] = (memo_len, object) try: --- 569,581 ---- if self.bin: save(cls) ! for arg in args: ! save(arg) ! write(OBJ) else: ! for arg in args: ! save(arg) ! write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') ! self.memoize(object) try: *************** *** 597,600 **** --- 588,592 ---- save(stuff) write(BUILD) + dispatch[InstanceType] = save_inst *************** *** 627,630 **** --- 619,623 ---- write(GLOBAL + module + '\n' + name + '\n') self.memoize(object) + dispatch[ClassType] = save_global dispatch[FunctionType] = save_global From gvanrossum@users.sourceforge.net Tue Jan 28 03:51:55 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 19:51:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_pickle.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv26666 Modified Files: test_pickle.py Log Message: Rename 'bin' arg to 'proto'. Keep the default at 0 lest the tests change in meaning. Index: test_pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pickle.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_pickle.py 13 Nov 2002 22:01:27 -0000 1.12 --- test_pickle.py 28 Jan 2003 03:51:53 -0000 1.13 *************** *** 19,25 **** error = KeyError ! def dumps(self, arg, bin=0): f = StringIO() ! p = pickle.Pickler(f, bin) p.dump(arg) f.seek(0) --- 19,25 ---- error = KeyError ! def dumps(self, arg, proto=0): f = StringIO() ! p = pickle.Pickler(f, proto) p.dump(arg) f.seek(0) *************** *** 33,42 **** class PersPicklerTests(AbstractPersistentPicklerTests): ! def dumps(self, arg, bin=0): class PersPickler(pickle.Pickler): def persistent_id(subself, obj): return self.persistent_id(obj) f = StringIO() ! p = PersPickler(f, bin) p.dump(arg) f.seek(0) --- 33,42 ---- class PersPicklerTests(AbstractPersistentPicklerTests): ! def dumps(self, arg, proto=0): class PersPickler(pickle.Pickler): def persistent_id(subself, obj): return self.persistent_id(obj) f = StringIO() ! p = PersPickler(f, proto) p.dump(arg) f.seek(0) From gvanrossum@users.sourceforge.net Tue Jan 28 04:14:53 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 20:14:53 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv17311/test Modified Files: pickletester.py Log Message: More protocol 2: TUPLE1, TUPLE2, TUPLE3. Also moved the special case for empty tuples from save() to save_tuple(). Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** pickletester.py 28 Jan 2003 03:49:52 -0000 1.21 --- pickletester.py 28 Jan 2003 04:14:51 -0000 1.22 *************** *** 282,285 **** --- 282,297 ---- self.assertEqual(x, y) + def test_short_tuples(self): + a = () + b = (12,) + c = (6, 6) + d = (4, 4, 4) + e = (3, 3, 3, 3) + for proto in 0, 1, 2: + for x in a, b, c, d, e: + s = self.dumps(x, proto) + y = self.loads(s) + self.assertEqual(x, y, (proto, x, s, y)) + class AbstractPickleModuleTests(unittest.TestCase): From gvanrossum@users.sourceforge.net Tue Jan 28 04:14:53 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 20:14:53 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.101,1.102 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv17311 Modified Files: pickle.py Log Message: More protocol 2: TUPLE1, TUPLE2, TUPLE3. Also moved the special case for empty tuples from save() to save_tuple(). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -d -r1.101 -r1.102 *** pickle.py 28 Jan 2003 03:51:36 -0000 1.101 --- pickle.py 28 Jan 2003 04:14:50 -0000 1.102 *************** *** 151,154 **** --- 151,156 ---- LONG4 = '\x8b' # push really big long + _tuplesize2code = [EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3] + __all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)]) *************** *** 258,269 **** t = type(object) - # XXX Why are tuples a special case here? - if (t is TupleType) and (len(object) == 0): - if self.bin: - self.save_empty_tuple(object) - else: - self.save_tuple(object) - return - if d in memo: self.write(self.get(memo[d][0])) --- 260,263 ---- *************** *** 464,467 **** --- 458,479 ---- save = self.save memo = self.memo + proto = self.proto + + if proto >= 1: + n = len(object) + if n <= 3: + if not object: + write(EMPTY_TUPLE) + return + if proto >= 2: + for element in object: + save(element) + # Subtle. Same as in the big comment below + if id(object) in memo: + get = self.get(memo[id(object)][0]) + write(POP_MARK + get) + else: + write(_tuplesize2code[n]) + return write(MARK) *************** *** 478,482 **** # recursive tuples are a rare thing. get = self.get(memo[id(object)][0]) ! if self.bin: write(POP_MARK + get) else: # proto 0 -- POP_MARK not available --- 490,494 ---- # recursive tuples are a rare thing. get = self.get(memo[id(object)][0]) ! if proto: write(POP_MARK + get) else: # proto 0 -- POP_MARK not available *************** *** 484,490 **** return ! # No recursion (including the empty-tuple case). self.write(TUPLE) ! self.memoize(object) dispatch[TupleType] = save_tuple --- 496,502 ---- return ! # No recursion (including the empty-tuple case for protocol 0). self.write(TUPLE) ! self.memoize(object) # XXX shouldn't memoize empty tuple?! dispatch[TupleType] = save_tuple *************** *** 876,879 **** --- 888,903 ---- self.stack.append(()) dispatch[EMPTY_TUPLE] = load_empty_tuple + + def load_tuple1(self): + self.stack[-1] = (self.stack[-1],) + dispatch[TUPLE1] = load_tuple1 + + def load_tuple2(self): + self.stack[-2:] = [(self.stack[-2], self.stack[-1])] + dispatch[TUPLE2] = load_tuple2 + + def load_tuple3(self): + self.stack[-3:] = [(self.stack[-3], self.stack[-2], self.stack[-1])] + dispatch[TUPLE3] = load_tuple3 def load_empty_list(self): From neal@metaslash.com Tue Jan 28 04:15:07 2003 From: neal@metaslash.com (Neal Norwitz) Date: Mon, 27 Jan 2003 23:15:07 -0500 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.91,1.92 In-Reply-To: References: <20030128030418.GG24222@epoch.metaslash.com> Message-ID: <20030128041507.GH24222@epoch.metaslash.com> On Mon, Jan 27, 2003 at 10:33:27PM -0500, Tim Peters wrote: > [Neal Norwitz, on save_dict() rewrite] > > In the case where self.bin and len(object) == 1, the code looks > > like it does something different. > > > > The old code would save(key) & save(value) since the for loop is > > executed. The new code doesn't execute the loop though. > > > > Am I missing something? > > Guido explained this already. It makes me wonder whether I shouldn't > duplicate that block of code, though -- the point of these rewrites was > largely to make the code more evident, by eliminating mounds of fiddly > little "internal" branches. I originally did duplicate the loop, but it was > such blatant code duplication then that I nuked the first copy and let it > fall thru instead. I like the version you checked in. But every time I look at the code, even after Guido pointed it out, I see the wrong flow. Time for new eyes and/or brain. The only way I could see the correct flow was to remove the blank line before the else and move the code before the return into a function: if self.bin: write(EMPTY_DICT) self.memoize(object) if len(object) > 1: save_dict_items(items) return else: # proto 0 -- can't use EMPTY_DICT or SETITEMS # ... However, I don't really think the above code is much of an improvement. > IOW, I can't win this one . Of course. :-) Neal From gvanrossum@users.sourceforge.net Tue Jan 28 04:20:05 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 20:20:05 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv23608 Modified Files: pickletester.py Log Message: Shouldn't test short tuples with all items equal -- one potential bug would be that the tuple is reversed on unpickling, and we should catch that. :-) Goodnight -- that's it for toniht! Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** pickletester.py 28 Jan 2003 04:14:51 -0000 1.22 --- pickletester.py 28 Jan 2003 04:20:02 -0000 1.23 *************** *** 284,291 **** def test_short_tuples(self): a = () ! b = (12,) ! c = (6, 6) ! d = (4, 4, 4) ! e = (3, 3, 3, 3) for proto in 0, 1, 2: for x in a, b, c, d, e: --- 284,291 ---- def test_short_tuples(self): a = () ! b = (1,) ! c = (1, 2) ! d = (1, 2, 3) ! e = (1, 2, 3, 4) for proto in 0, 1, 2: for x in a, b, c, d, e: From gvanrossum@users.sourceforge.net Tue Jan 28 04:25:29 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 20:25:29 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv28427/test Modified Files: pickletester.py Log Message: OK, this is really the last one tonight! NEWFALSE and NEWTRUE. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** pickletester.py 28 Jan 2003 04:20:02 -0000 1.23 --- pickletester.py 28 Jan 2003 04:25:27 -0000 1.24 *************** *** 294,297 **** --- 294,304 ---- self.assertEqual(x, y, (proto, x, s, y)) + def test_singletons(self): + for proto in 0, 1, 2: + for x in None, False, True: + s = self.dumps(x, proto) + y = self.loads(s) + self.assert_(x is y, (proto, x, s, y)) + class AbstractPickleModuleTests(unittest.TestCase): From gvanrossum@users.sourceforge.net Tue Jan 28 04:25:29 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Mon, 27 Jan 2003 20:25:29 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.102,1.103 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28427 Modified Files: pickle.py Log Message: OK, this is really the last one tonight! NEWFALSE and NEWTRUE. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.102 retrieving revision 1.103 diff -C2 -d -r1.102 -r1.103 *** pickle.py 28 Jan 2003 04:14:50 -0000 1.102 --- pickle.py 28 Jan 2003 04:25:26 -0000 1.103 *************** *** 357,361 **** def save_bool(self, object): ! self.write(object and TRUE or FALSE) dispatch[bool] = save_bool --- 357,364 ---- def save_bool(self, object): ! if self.proto >= 2: ! self.write(object and NEWTRUE or NEWFALSE) ! else: ! self.write(object and TRUE or FALSE) dispatch[bool] = save_bool *************** *** 760,763 **** --- 763,774 ---- self.append(None) dispatch[NONE] = load_none + + def load_false(self): + self.append(False) + dispatch[NEWFALSE] = load_false + + def load_true(self): + self.append(True) + dispatch[NEWTRUE] = load_true def load_int(self): From tim_one@users.sourceforge.net Tue Jan 28 04:56:35 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 20:56:35 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv17741/Lib Modified Files: pickletools.py Log Message: Now that proto2 is defined, replaced XXX blocks with text about it. Also moved the proto2 opcode descriptors into the sections they fit (like TUPLE{1,2,3} in the group of tuple-building opcodes; etc). Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pickletools.py 28 Jan 2003 00:20:41 -0000 1.11 --- pickletools.py 28 Jan 2003 04:56:33 -0000 1.12 *************** *** 71,78 **** pickle opcodes never go away, not even when better ways to do a thing get invented. The repertoire of the PM just keeps growing over time. ! So, e.g., there are now five distinct opcodes for building a Python integer, ! four of them devoted to "short" integers. Even so, the only way to pickle ! a Python long int takes time quadratic in the number of digits, for both ! pickling and unpickling. This isn't so much a subtlety as a source of wearying complication. --- 71,80 ---- pickle opcodes never go away, not even when better ways to do a thing get invented. The repertoire of the PM just keeps growing over time. ! For example, protocol 0 had two opcodes for building Python integers (INT ! and LONG), protocol 1 added three more for more-efficient pickling of short ! integers, and protocol 2 added two more for more-efficient pickling of ! long integers (before protocol 2, the only ways to pickle a Python long ! took time quadratic in the number of digits, for both pickling and ! unpickling). "Opcode bloat" isn't so much a subtlety as a source of wearying complication. *************** *** 94,98 **** "text mode" before Python 2.3. The entire pickle bytestream is made up of printable 7-bit ASCII characters, plus the newline character, in protocol 0. ! That's why it was called text mode. The second major set of additions is now called "protocol 1", and was called --- 96,101 ---- "text mode" before Python 2.3. The entire pickle bytestream is made up of printable 7-bit ASCII characters, plus the newline character, in protocol 0. ! That's why it was called text mode. Protocol 0 is small and elegant, but ! sometimes painfully inefficient. The second major set of additions is now called "protocol 1", and was called *************** *** 102,109 **** text mode pickles, and sometimes faster too; e.g., BININT represents a 4-byte int as 4 bytes following the opcode, which is cheaper to unpickle than the ! (perhaps) 11-character decimal string attached to INT. The third major set of additions came in Python 2.3, and is called "protocol ! 2". XXX Write a short blurb when Guido figures out what they are . XXX """ --- 105,129 ---- text mode pickles, and sometimes faster too; e.g., BININT represents a 4-byte int as 4 bytes following the opcode, which is cheaper to unpickle than the ! (perhaps) 11-character decimal string attached to INT. Protocol 1 also added ! a number of opcodes that operate on many stack elements at once (like APPENDS ! and SETITEMS). The third major set of additions came in Python 2.3, and is called "protocol ! 2". This added: ! ! - A better way to pickle instances of new-style classes (NEWOBJ). ! ! - A way for a pickle to identify its protocol (PROTO). ! ! - Time- and space- efficient pickling of long ints (LONG{1,4}). ! ! - Shortcuts for small tuples (TUPLE{1,2,3}}. ! ! - Dedicated opcodes for bools (NEWTRUE, NEWFALSE). ! ! - The "extension registry", a vector of popular objects that can be pushed ! efficiently by index (EXT{1,2,4}). This is akin to the memo and GET, but ! the registry contents are predefined (there's nothing akin to the memo's ! PUT). """ *************** *** 890,906 **** """), - I(name='LONG', - code='L', - arg=decimalnl_long, - stack_before=[], - stack_after=[pylong], - proto=0, - doc="""Push a long integer. - - The same as INT, except that the literal ends with 'L', and always - unpickles to a Python long. There doesn't seem a real purpose to the - trailing 'L'. - """), - I(name='BININT', code='J', --- 910,913 ---- *************** *** 942,945 **** --- 949,992 ---- """), + I(name='LONG', + code='L', + arg=decimalnl_long, + stack_before=[], + stack_after=[pylong], + proto=0, + doc="""Push a long integer. + + The same as INT, except that the literal ends with 'L', and always + unpickles to a Python long. There doesn't seem a real purpose to the + trailing 'L'. + + Note that LONG takes time quadratic in the number of digits when + unpickling (this is simply due to the nature of decimal->binary + conversion). Proto 2 added linear-time (in C; still quadratic-time + in Python) LONG1 and LONG4 opcodes. + """), + + I(name="LONG1", + code='\x8a', + arg=long1, + stack_before=[], + stack_after=[pylong], + proto=2, + doc="""Long integer using one-byte length. + + A more efficient encoding of a Python long; the long1 encoding + says it all."""), + + I(name="LONG4", + code='\x8b', + arg=long4, + stack_before=[], + stack_after=[pylong], + proto=2, + doc="""Long integer using found-byte length. + + A more efficient encoding of a Python long; the long4 encoding + says it all."""), + # Ways to spell strings (8-bit, not Unicode). *************** *** 993,996 **** --- 1040,1066 ---- doc="Push None on the stack."), + # Ways to spell bools, starting with proto 2. See INT for how this was + # done before proto 2. + + I(name='NEWTRUE', + code='\x88', + arg=None, + stack_before=[], + stack_after=[pybool], + proto=2, + doc="""True. + + Push True onto the stack."""), + + I(name='NEWFALSE', + code='\x89', + arg=None, + stack_before=[], + stack_after=[pybool], + proto=2, + doc="""True. + + Push False onto the stack."""), + # Ways to spell Unicode strings. *************** *** 1135,1138 **** --- 1205,1250 ---- """), + I(name='TUPLE1', + code='\x85', + arg=None, + stack_before=[anyobject], + stack_after=[pytuple], + proto=2, + doc="""One-tuple. + + This code pops one value off the stack and pushes a tuple of + length 1 whose one item is that value back onto it. IOW: + + stack[-1] = tuple(stack[-1:]) + """), + + I(name='TUPLE2', + code='\x86', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[pytuple], + proto=2, + doc="""One-tuple. + + This code pops two values off the stack and pushes a tuple + of length 2 whose items are those values back onto it. IOW: + + stack[-2:] = [tuple(stack[-2:])] + """), + + I(name='TUPLE3', + code='\x87', + arg=None, + stack_before=[anyobject, anyobject, anyobject], + stack_after=[pytuple], + proto=2, + doc="""One-tuple. + + This code pops three values off the stack and pushes a tuple + of length 3 whose items are those values back onto it. IOW: + + stack[-3:] = [tuple(stack[-3:])] + """), + # Ways to build dicts. *************** *** 1318,1321 **** --- 1430,1480 ---- """), + # Access the extension registry (predefined objects). Akin to the GET + # family. + + I(name='EXT1', + code='\x82', + arg=uint1, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + This code and the similar EXT2 and EXT4 allow using a registry + of popular objects that are pickled by name, typically classes. + It is envisioned that through a global negotiation and + registration process, third parties can set up a mapping between + ints and object names. + + In order to guarantee pickle interchangeability, the extension + code registry ought to be global, although a range of codes may + be reserved for private use. + + EXT1 has a 1-byte integer argument. This is used to index into the + extension registry, and the object at that index is pushed on the stack. + """), + + I(name='EXT2', + code='\x83', + arg=uint2, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + See EXT1. EXT2 has a two-byte integer argument. + """), + + I(name='EXT4', + code='\x84', + arg=int4, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + See EXT1. EXT4 has a four-byte integer argument. + """), + # Push a class object, or module function, on the stack, via its module # and name. *************** *** 1488,1493 **** --- 1647,1679 ---- """), + I(name='NEWOBJ', + code='\x81', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[anyobject], + proto=2, + doc="""Build an object instance. + + The stack before should be thought of as containing a class + object followed by an argument tuple (the tuple being the stack + top). Call these cls and args. They are popped off the stack, + and the value returned by cls.__new__(cls, *args) is pushed back + onto the stack. + """), + # Machine control. + I(name='PROTO', + code='\x80', + arg=uint1, + stack_before=[], + stack_after=[], + proto=2, + doc="""Protocol version indicator. + + For protocol 2 and above, a pickle must start with this opcode. + The argument is the protocol version, an int in range(2, 256). + """), + I(name='STOP', code='.', *************** *** 1535,1693 **** returns is pushed on the stack. See PERSID for more detail. """), - - # Protocol 2 opcodes - - I(name='PROTO', - code='\x80', - arg=uint1, - stack_before=[], - stack_after=[], - proto=2, - doc="""Protocol version indicator. - - For protocol 2 and above, a pickle must start with this opcode. - The argument is the protocol version, an int in range(2, 256). - """), - - I(name='NEWOBJ', - code='\x81', - arg=None, - stack_before=[anyobject, anyobject], - stack_after=[anyobject], - proto=2, - doc="""Build an object instance. - - The stack before should be thought of as containing a class - object followed by an argument tuple (the tuple being the stack - top). Call these cls and args. They are popped off the stack, - and the value returned by cls.__new__(cls, *args) is pushed back - onto the stack. - """), - - I(name='EXT1', - code='\x82', - arg=uint1, - stack_before=[], - stack_after=[anyobject], - proto=2, - doc="""Extension code. - - This code and the similar EXT2 and EXT4 allow using a registry - of popular objects that are pickled by name, typically classes. - It is envisioned that through a global negotiation and - registration process, third parties can set up a mapping between - ints and object names. - - In order to guarantee pickle interchangeability, the extension - code registry ought to be global, although a range of codes may - be reserved for private use. - """), - - I(name='EXT2', - code='\x83', - arg=uint2, - stack_before=[], - stack_after=[anyobject], - proto=2, - doc="""Extension code. - - See EXT1. - """), - - I(name='EXT4', - code='\x84', - arg=int4, - stack_before=[], - stack_after=[anyobject], - proto=2, - doc="""Extension code. - - See EXT1. - """), - - I(name='TUPLE1', - code='\x85', - arg=None, - stack_before=[anyobject], - stack_after=[pytuple], - proto=2, - doc="""One-tuple. - - This code pops one value off the stack and pushes a tuple of - length 1 whose one item is that value back onto it. IOW: - - stack[-1] = tuple(stack[-1:]) - """), - - I(name='TUPLE2', - code='\x86', - arg=None, - stack_before=[anyobject, anyobject], - stack_after=[pytuple], - proto=2, - doc="""One-tuple. - - This code pops two values off the stack and pushes a tuple - of length 2 whose items are those values back onto it. IOW: - - stack[-2:] = [tuple(stack[-2:])] - """), - - I(name='TUPLE3', - code='\x87', - arg=None, - stack_before=[anyobject, anyobject, anyobject], - stack_after=[pytuple], - proto=2, - doc="""One-tuple. - - This code pops three values off the stack and pushes a tuple - of length 3 whose items are those values back onto it. IOW: - - stack[-3:] = [tuple(stack[-3:])] - """), - - I(name='NEWTRUE', - code='\x88', - arg=None, - stack_before=[], - stack_after=[pybool], - proto=2, - doc="""True. - - Push True onto the stack."""), - - I(name='NEWFALSE', - code='\x89', - arg=None, - stack_before=[], - stack_after=[pybool], - proto=2, - doc="""True. - - Push False onto the stack."""), - - I(name="LONG1", - code='\x8a', - arg=long1, - stack_before=[], - stack_after=[pylong], - proto=2, - doc="""Long integer using one-byte length. - - A more efficient encoding of a Python long; the long1 encoding - says it all."""), - - I(name="LONG4", - code='\x8b', - arg=long4, - stack_before=[], - stack_after=[pylong], - proto=2, - doc="""Long integer using found-byte length. - - A more efficient encoding of a Python long; the long4 encoding - says it all."""), - ] del I --- 1721,1724 ---- From tim_one@users.sourceforge.net Tue Jan 28 05:12:11 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 21:12:11 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25898/Lib Modified Files: pickletools.py Log Message: Comments. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pickletools.py 28 Jan 2003 04:56:33 -0000 1.12 --- pickletools.py 28 Jan 2003 05:12:08 -0000 1.13 *************** *** 107,111 **** (perhaps) 11-character decimal string attached to INT. Protocol 1 also added a number of opcodes that operate on many stack elements at once (like APPENDS ! and SETITEMS). The third major set of additions came in Python 2.3, and is called "protocol --- 107,111 ---- (perhaps) 11-character decimal string attached to INT. Protocol 1 also added a number of opcodes that operate on many stack elements at once (like APPENDS ! and SETITEMS), and "shortcut" opcodes (like EMPTY_DICT and EMPTY_TUPLE). The third major set of additions came in Python 2.3, and is called "protocol *************** *** 1149,1152 **** --- 1149,1154 ---- Stack before: ... pylist anyobject Stack after: ... pylist+[anyobject] + + although pylist is really extended in-place. """), *************** *** 1161,1164 **** --- 1163,1168 ---- Stack before: ... pylist markobject stackslice Stack after: ... pylist+stackslice + + although pylist is really extended in-place. """), From tim.one@comcast.net Tue Jan 28 05:24:11 2003 From: tim.one@comcast.net (Tim Peters) Date: Tue, 28 Jan 2003 00:24:11 -0500 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.101,1.102 In-Reply-To: Message-ID: > Modified Files: > =09pickle.py > Log Message: > More protocol 2: TUPLE1, TUPLE2, TUPLE3. > > Also moved the special case for empty tuples from save() to save_tu= ple(). > + if proto >=3D 1: > + n =3D len(object) > + if n <=3D 3: > + if not object: > + write(EMPTY_TUPLE) > + return > + if proto >=3D 2: > + for element in object: > + save(element) > + # Subtle. Same as in the big comment below > + if id(object) in memo: > + get =3D self.get(memo[id(object)][0]) > + write(POP_MARK + get) > + else: > + write(_tuplesize2code[n]) > + return When proto >=3D 2 and n in (1, 2, 3), the resulting tuple never gets = memoized, so it doesn't seem possible for "id(object) in memo" to be true. If = it were possible, then the POP_MARK opcode is going to look back for a MARK t= hat was never pushed ... OK, if I try pickling the one-element tuple T containing a one-elemen= t list L containing T under proto 2, the opcodes are: 0: =C7 PROTO 2 2: ] EMPTY_LIST 3: q BINPUT 0 5: h BINGET 0 7: =E0 TUPLE1 8: a APPEND 9: =E0 TUPLE1 10: . STOP That isn't right, but is what happens if "id(object) in memo" is neve= r true. I'll try to fix it. From tim_one@users.sourceforge.net Tue Jan 28 05:34:56 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 21:34:56 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.103,1.104 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv10844/Lib Modified Files: pickle.py Log Message: save_tuple(): I believe the new code for TUPLE{1,2,3} in proto 2 was incorrect for recursive tuples. Tried to repair; seems to work OK, but there are no checked-in tests for this yet. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.103 retrieving revision 1.104 diff -C2 -d -r1.103 -r1.104 *** pickle.py 28 Jan 2003 04:25:26 -0000 1.103 --- pickle.py 28 Jan 2003 05:34:53 -0000 1.104 *************** *** 472,483 **** for element in object: save(element) ! # Subtle. Same as in the big comment below if id(object) in memo: get = self.get(memo[id(object)][0]) ! write(POP_MARK + get) else: write(_tuplesize2code[n]) return write(MARK) for element in object: --- 472,486 ---- for element in object: save(element) ! # Subtle. Same as in the big comment below. if id(object) in memo: get = self.get(memo[id(object)][0]) ! write(POP * n + get) else: write(_tuplesize2code[n]) + self.memoize(object) return + # proto 0, or proto 1 and tuple isn't empty, or proto > 1 and tuple + # has more than 3 elements. write(MARK) for element in object: From tim_one@users.sourceforge.net Tue Jan 28 05:48:31 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 27 Jan 2003 21:48:31 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.104,1.105 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25979/Lib Modified Files: pickle.py Log Message: save_tuple(): So long as the charter is rewriting for clarity, the snaky control flow had to be simplified. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.104 retrieving revision 1.105 diff -C2 -d -r1.104 -r1.105 *** pickle.py 28 Jan 2003 05:34:53 -0000 1.104 --- pickle.py 28 Jan 2003 05:48:29 -0000 1.105 *************** *** 459,483 **** def save_tuple(self, object): write = self.write - save = self.save - memo = self.memo proto = self.proto ! if proto >= 1: ! n = len(object) ! if n <= 3: ! if not object: ! write(EMPTY_TUPLE) ! return ! if proto >= 2: ! for element in object: ! save(element) ! # Subtle. Same as in the big comment below. ! if id(object) in memo: ! get = self.get(memo[id(object)][0]) ! write(POP * n + get) ! else: ! write(_tuplesize2code[n]) ! self.memoize(object) ! return # proto 0, or proto 1 and tuple isn't empty, or proto > 1 and tuple --- 459,482 ---- def save_tuple(self, object): write = self.write proto = self.proto ! n = len(object) ! if n == 0 and proto: ! write(EMPTY_TUPLE) ! return ! ! save = self.save ! memo = self.memo ! if n <= 3 and proto >= 2: ! for element in object: ! save(element) ! # Subtle. Same as in the big comment below. ! if id(object) in memo: ! get = self.get(memo[id(object)][0]) ! write(POP * n + get) ! else: ! write(_tuplesize2code[n]) ! self.memoize(object) ! return # proto 0, or proto 1 and tuple isn't empty, or proto > 1 and tuple *************** *** 487,491 **** save(element) ! if object and id(object) in memo: # Subtle. d was not in memo when we entered save_tuple(), so # the process of saving the tuple's elements must have saved --- 486,490 ---- save(element) ! if n and id(object) in memo: # Subtle. d was not in memo when we entered save_tuple(), so # the process of saving the tuple's elements must have saved *************** *** 499,503 **** write(POP_MARK + get) else: # proto 0 -- POP_MARK not available ! write(POP * (len(object) + 1) + get) return --- 498,502 ---- write(POP_MARK + get) else: # proto 0 -- POP_MARK not available ! write(POP * (n+1) + get) return From fdrake@users.sourceforge.net Tue Jan 28 06:42:42 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Mon, 27 Jan 2003 22:42:42 -0800 Subject: [Python-checkins] python/dist/src/Modules/expat xmlparse.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules/expat In directory sc8-pr-cvs1:/tmp/cvs-serv7149 Modified Files: xmlparse.c Log Message: Update to the final version released as Expat 1.95.6 (maintaining Martin's integration changes). Index: xmlparse.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/expat/xmlparse.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** xmlparse.c 26 Jan 2003 08:40:46 -0000 1.4 --- xmlparse.c 28 Jan 2003 06:42:40 -0000 1.5 *************** *** 310,315 **** static enum XML_Error ! storeAtts(XML_Parser parser, const ENCODING *, ! const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr); static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, --- 310,315 ---- static enum XML_Error ! storeAtts(XML_Parser parser, const ENCODING *, const char *s, ! TAG_NAME *tagNamePtr, BINDING **bindingsPtr); static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, *************** *** 2098,2106 **** tag->name.str = (XML_Char *)tag->buf; *toPtr = XML_T('\0'); - if (!startElementHandler && (tok == XML_TOK_START_TAG_NO_ATTS)) { - if (defaultHandler) - reportDefault(parser, enc, s, next); - break; - } result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); if (result) --- 2098,2101 ---- *************** *** 2115,2125 **** } case XML_TOK_EMPTY_ELEMENT_NO_ATTS: - if (!startElementHandler && !endElementHandler) { - if (defaultHandler) - reportDefault(parser, enc, s, next); - if (tagLevel == 0) - return epilogProcessor(parser, next, end, nextPtr); - break; - } /* fall through */ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: --- 2110,2113 ---- *************** *** 2135,2145 **** return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); ! if (startElementHandler || ! (tok == XML_TOK_EMPTY_ELEMENT_WITH_ATTS)) { ! result = storeAtts(parser, enc, s, &name, &bindings); ! if (result) ! return result; ! poolFinish(&tempPool); ! } if (startElementHandler) { startElementHandler(handlerArg, name.str, (const XML_Char **)atts); --- 2123,2130 ---- return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); ! result = storeAtts(parser, enc, s, &name, &bindings); ! if (result) ! return result; ! poolFinish(&tempPool); if (startElementHandler) { startElementHandler(handlerArg, name.str, (const XML_Char **)atts); *************** *** 2344,2349 **** } ! /* If tagNamePtr is non-null, build a real list of attributes, ! otherwise just check the attributes for well-formedness. */ static enum XML_Error --- 2329,2341 ---- } ! /* Precondition: all arguments must be non-NULL; ! Purpose: ! - normalize attributes ! - check attributes for well-formedness ! - generate namespace aware attribute names (URI, prefix) ! - build list of attributes for startElementHandler ! - default attributes ! - process namespace declarations (check and report them) ! - generate namespace aware element name (URI, prefix) */ static enum XML_Error *************** *** 2366,2384 **** /* lookup the element type name */ ! if (tagNamePtr) { ! elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0); ! if (!elementType) { ! const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); ! if (!name) ! return XML_ERROR_NO_MEMORY; ! elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name, ! sizeof(ELEMENT_TYPE)); ! if (!elementType) ! return XML_ERROR_NO_MEMORY; ! if (ns && !setElementTypePrefix(parser, elementType)) ! return XML_ERROR_NO_MEMORY; ! } ! nDefaultAtts = elementType->nDefaultAtts; } /* get the attributes from the tokenizer */ n = XmlGetAttributes(enc, attStr, attsSize, atts); --- 2358,2375 ---- /* lookup the element type name */ ! elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0); ! if (!elementType) { ! const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); ! if (!name) ! return XML_ERROR_NO_MEMORY; ! elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name, ! sizeof(ELEMENT_TYPE)); ! if (!elementType) ! return XML_ERROR_NO_MEMORY; ! if (ns && !setElementTypePrefix(parser, elementType)) ! return XML_ERROR_NO_MEMORY; } + nDefaultAtts = elementType->nDefaultAtts; + /* get the attributes from the tokenizer */ n = XmlGetAttributes(enc, attStr, attsSize, atts); *************** *** 2394,2397 **** --- 2385,2389 ---- XmlGetAttributes(enc, attStr, n, atts); } + appAtts = (const XML_Char **)atts; for (i = 0; i < n; i++) { *************** *** 2431,2442 **** if (result) return result; ! if (tagNamePtr) { ! appAtts[attIndex] = poolStart(&tempPool); ! poolFinish(&tempPool); ! } ! else ! poolDiscard(&tempPool); } ! else if (tagNamePtr) { /* the value did not need normalizing */ appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, --- 2423,2430 ---- if (result) return result; ! appAtts[attIndex] = poolStart(&tempPool); ! poolFinish(&tempPool); } ! else { /* the value did not need normalizing */ appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, *************** *** 2447,2451 **** } /* handle prefixed attribute names */ ! if (attId->prefix && tagNamePtr) { if (attId->xmlns) { /* deal with namespace declarations here */ --- 2435,2439 ---- } /* handle prefixed attribute names */ ! if (attId->prefix) { if (attId->xmlns) { /* deal with namespace declarations here */ *************** *** 2466,2508 **** attIndex++; } ! if (tagNamePtr) { ! int j; ! nSpecifiedAtts = attIndex; ! if (elementType->idAtt && (elementType->idAtt->name)[-1]) { ! for (i = 0; i < attIndex; i += 2) ! if (appAtts[i] == elementType->idAtt->name) { ! idAttIndex = i; ! break; ! } ! } ! else ! idAttIndex = -1; ! /* do attribute defaulting */ ! for (j = 0; j < nDefaultAtts; j++) { ! const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j; ! if (!(da->id->name)[-1] && da->value) { ! if (da->id->prefix) { ! if (da->id->xmlns) { ! enum XML_Error result = addBinding(parser, da->id->prefix, da->id, ! da->value, bindingsPtr); ! if (result) ! return result; ! } ! else { ! (da->id->name)[-1] = 2; ! nPrefixes++; ! appAtts[attIndex++] = da->id->name; ! appAtts[attIndex++] = da->value; ! } } else { ! (da->id->name)[-1] = 1; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } } } - appAtts[attIndex] = 0; } i = 0; if (nPrefixes) { --- 2454,2497 ---- attIndex++; } ! ! /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ ! nSpecifiedAtts = attIndex; ! if (elementType->idAtt && (elementType->idAtt->name)[-1]) { ! for (i = 0; i < attIndex; i += 2) ! if (appAtts[i] == elementType->idAtt->name) { ! idAttIndex = i; ! break; ! } ! } ! else ! idAttIndex = -1; ! ! /* do attribute defaulting */ ! for (i = 0; i < nDefaultAtts; i++) { ! const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; ! if (!(da->id->name)[-1] && da->value) { ! if (da->id->prefix) { ! if (da->id->xmlns) { ! enum XML_Error result = addBinding(parser, da->id->prefix, da->id, ! da->value, bindingsPtr); ! if (result) ! return result; } else { ! (da->id->name)[-1] = 2; ! nPrefixes++; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } } + else { + (da->id->name)[-1] = 1; + appAtts[attIndex++] = da->id->name; + appAtts[attIndex++] = da->value; + } } } + appAtts[attIndex] = 0; + i = 0; if (nPrefixes) { *************** *** 2549,2556 **** for (; i < attIndex; i += 2) ((XML_Char *)(appAtts[i]))[-1] = 0; - if (!tagNamePtr) - return XML_ERROR_NONE; for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) binding->attId->name[-1] = 0; /* expand the element type name */ if (elementType->prefix) { --- 2538,2544 ---- for (; i < attIndex; i += 2) ((XML_Char *)(appAtts[i]))[-1] = 0; for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) binding->attId->name[-1] = 0; + /* expand the element type name */ if (elementType->prefix) { From walter@livinglogic.de Tue Jan 28 11:30:33 2003 From: walter@livinglogic.de (=?ISO-8859-15?Q?Walter_D=F6rwald?=) Date: Tue, 28 Jan 2003 12:30:33 +0100 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 In-Reply-To: References: <3E352ADE.3090908@livinglogic.de> Message-ID: <3E3669D9.3090807@livinglogic.de> Martin v. Löwis wrote: > Walter Dörwald writes: > >>This interprets negative indizes as being relative to the >>end of the input. All other encoders treat <0 as ==0. > > > Hmm. This appears to be unspecified in the PEP. What is the rationale > for equating <0 to =0? It just was the simplest solution. > It appears that this indicates a bug in the > error callback, which should not pass silently. So would a position that is beyond the end of the input. > In any case, I'ld like to request that the documentation is clarified > in this aspect (preferable, the "proper" documentation, not (just) the > PEP). Once that clarification is added, the incorrect codecs should be > corrected. So how should we handle these cases? a) Treat negative positions as relative to the end b) Treat negative positions as 0 c) Clip out of bounds positions to the length of the input d) Raise an exception I'd vote for a) + d) If that's what we want to do I'll update the PEP, the documentation and the implemenation. Bye, Walter Dörwald From perky@fallin.lv Tue Jan 28 11:55:07 2003 From: perky@fallin.lv (Hye-Shik Chang) Date: Tue, 28 Jan 2003 20:55:07 +0900 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 In-Reply-To: <3E3669D9.3090807@livinglogic.de> References: <3E352ADE.3090908@livinglogic.de> <3E3669D9.3090807@livinglogic.de> Message-ID: <20030128115507.GA20057@fallin.lv> On Tue, Jan 28, 2003 at 12:30:33PM +0100, Walter D?rwald wrote: > Martin v. L?wis wrote: > > >Walter D?rwald writes: > > > >>This interprets negative indizes as being relative to the > >>end of the input. All other encoders treat <0 as ==0. > > > > > >Hmm. This appears to be unspecified in the PEP. What is the rationale > >for equating <0 to =0? > > It just was the simplest solution. I'd like raising IndexError than regarding <0 as =0 > > >It appears that this indicates a bug in the > >error callback, which should not pass silently. > > So would a position that is beyond the end of the input. > > >In any case, I'ld like to request that the documentation is clarified > >in this aspect (preferable, the "proper" documentation, not (just) the > >PEP). Once that clarification is added, the incorrect codecs should be > >corrected. > > So how should we handle these cases? > > a) Treat negative positions as relative to the end +1 > b) Treat negative positions as 0 -1 > c) Clip out of bounds positions to the length of the input -0 > d) Raise an exception +0 > > I'd vote for a) + d) > > If that's what we want to do I'll update the PEP, the documentation > and the implemenation. > > Bye, > Walter D?rwald > > Regards, Hye-Shik =) From gvanrossum@users.sourceforge.net Tue Jan 28 14:40:24 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 06:40:24 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.105,1.106 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv32274 Modified Files: pickle.py Log Message: Don't memoize the empty tuple in protocol 0. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.105 retrieving revision 1.106 diff -C2 -d -r1.105 -r1.106 *** pickle.py 28 Jan 2003 05:48:29 -0000 1.105 --- pickle.py 28 Jan 2003 14:40:16 -0000 1.106 *************** *** 503,507 **** # No recursion (including the empty-tuple case for protocol 0). self.write(TUPLE) ! self.memoize(object) # XXX shouldn't memoize empty tuple?! dispatch[TupleType] = save_tuple --- 503,508 ---- # No recursion (including the empty-tuple case for protocol 0). self.write(TUPLE) ! if object: # No need to memoize empty tuple ! self.memoize(object) dispatch[TupleType] = save_tuple From gvanrossum@users.sourceforge.net Tue Jan 28 15:09:13 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:09:13 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv11829 Modified Files: pickletools.py Log Message: Fix one disassembly output now that empty tuples are no longer memoized in text mode. Fixed some variable names in the disassembler doctest. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pickletools.py 28 Jan 2003 05:12:08 -0000 1.13 --- pickletools.py 28 Jan 2003 15:09:10 -0000 1.14 *************** *** 1903,1908 **** >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] ! >>> pik = pickle.dumps(x, 0) ! >>> dis(pik) 0: ( MARK 1: l LIST (MARK at 0) --- 1903,1908 ---- >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] ! >>> pkl = pickle.dumps(x, 0) ! >>> dis(pkl) 0: ( MARK 1: l LIST (MARK at 0) *************** *** 1931,1936 **** Try again with a "binary" pickle. ! >>> pik = pickle.dumps(x, 1) ! >>> dis(pik) 0: ] EMPTY_LIST 1: q BINPUT 0 --- 1931,1936 ---- Try again with a "binary" pickle. ! >>> pkl = pickle.dumps(x, 1) ! >>> dis(pkl) 0: ] EMPTY_LIST 1: q BINPUT 0 *************** *** 1976,1986 **** 47: ( MARK 48: t TUPLE (MARK at 47) ! 49: p PUT 4 ! 52: s SETITEM ! 53: b BUILD ! 54: a APPEND ! 55: g GET 1 ! 58: a APPEND ! 59: . STOP >>> dis(pickle.dumps(x, 1)) --- 1976,1985 ---- 47: ( MARK 48: t TUPLE (MARK at 47) ! 49: s SETITEM ! 50: b BUILD ! 51: a APPEND ! 52: g GET 1 ! 55: a APPEND ! 56: . STOP >>> dis(pickle.dumps(x, 1)) *************** *** 2072,2076 **** """ ! __test__ = {'dissassembler_test': _dis_test, } --- 2071,2075 ---- """ ! __test__ = {'disassembler_test': _dis_test, } From gvanrossum@users.sourceforge.net Tue Jan 28 15:10:27 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:10:27 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.106,1.107 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv12345 Modified Files: pickle.py Log Message: Rename all variables 'object' to 'obj' to avoid conflicts with the type 'object'. Also minor docstring tweakage, and rearranged a few lines in save(). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.106 retrieving revision 1.107 diff -C2 -d -r1.106 -r1.107 *** pickle.py 28 Jan 2003 14:40:16 -0000 1.106 --- pickle.py 28 Jan 2003 15:10:22 -0000 1.107 *************** *** 197,202 **** self.memo.clear() ! def dump(self, object): ! """Write a pickled representation of object to the open file object. Either the binary or ASCII format will be used, depending on the --- 197,202 ---- self.memo.clear() ! def dump(self, obj): ! """Write a pickled representation of obj to the open file. Either the binary or ASCII format will be used, depending on the *************** *** 206,210 **** if self.proto >= 2: self.write(PROTO + chr(self.proto)) ! self.save(object) self.write(STOP) --- 206,210 ---- if self.proto >= 2: self.write(PROTO + chr(self.proto)) ! self.save(obj) self.write(STOP) *************** *** 248,267 **** return GET + `i` + '\n' ! def save(self, object): ! memo = self.memo ! ! pid = self.persistent_id(object) if pid is not None: self.save_pers(pid) return ! d = id(object) ! ! t = type(object) ! if d in memo: self.write(self.get(memo[d][0])) return try: f = self.dispatch[t] --- 248,264 ---- return GET + `i` + '\n' ! def save(self, obj): ! pid = self.persistent_id(obj) if pid is not None: self.save_pers(pid) return ! memo = self.memo ! d = id(obj) if d in memo: self.write(self.get(memo[d][0])) return + t = type(obj) try: f = self.dispatch[t] *************** *** 269,273 **** pass else: ! f(self, object) return --- 266,270 ---- pass else: ! f(self, obj) return *************** *** 278,282 **** issc = 0 if issc: ! self.save_global(object) return --- 275,279 ---- issc = 0 if issc: ! self.save_global(obj) return *************** *** 285,300 **** except KeyError: try: ! reduce = object.__reduce__ except AttributeError: raise PicklingError, \ "can't pickle %s object: %s" % (`t.__name__`, ! `object`) else: tup = reduce() else: ! tup = reduce(object) if type(tup) is StringType: ! self.save_global(object, tup) return --- 282,297 ---- except KeyError: try: ! reduce = obj.__reduce__ except AttributeError: raise PicklingError, \ "can't pickle %s object: %s" % (`t.__name__`, ! `obj`) else: tup = reduce() else: ! tup = reduce(obj) if type(tup) is StringType: ! self.save_global(obj, tup) return *************** *** 322,328 **** self.save_reduce(callable, arg_tup, state) ! self.memoize(object) ! def persistent_id(self, object): return None --- 319,325 ---- self.save_reduce(callable, arg_tup, state) ! self.memoize(obj) ! def persistent_id(self, obj): return None *************** *** 352,367 **** dispatch = {} ! def save_none(self, object): self.write(NONE) dispatch[NoneType] = save_none ! def save_bool(self, object): if self.proto >= 2: ! self.write(object and NEWTRUE or NEWFALSE) else: ! self.write(object and TRUE or FALSE) dispatch[bool] = save_bool ! def save_int(self, object, pack=struct.pack): if self.bin: # If the int is small enough to fit in a signed 4-byte 2's-comp --- 349,364 ---- dispatch = {} ! def save_none(self, obj): self.write(NONE) dispatch[NoneType] = save_none ! def save_bool(self, obj): if self.proto >= 2: ! self.write(obj and NEWTRUE or NEWFALSE) else: ! self.write(obj and TRUE or FALSE) dispatch[bool] = save_bool ! def save_int(self, obj, pack=struct.pack): if self.bin: # If the int is small enough to fit in a signed 4-byte 2's-comp *************** *** 369,393 **** # case. # First one- and two-byte unsigned ints: ! if object >= 0: ! if object <= 0xff: ! self.write(BININT1 + chr(object)) return ! if object <= 0xffff: ! self.write(BININT2 + chr(object&0xff) + chr(object>>8)) return # Next check for 4-byte signed ints: ! high_bits = object >> 31 # note that Python shift sign-extends if high_bits == 0 or high_bits == -1: # All high bits are copies of bit 2**31, so the value # fits in a 4-byte signed int. ! self.write(BININT + pack("= 2: ! bytes = encode_long(object) n = len(bytes) if n < 256: --- 366,390 ---- # case. # First one- and two-byte unsigned ints: ! if obj >= 0: ! if obj <= 0xff: ! self.write(BININT1 + chr(obj)) return ! if obj <= 0xffff: ! self.write(BININT2 + chr(obj&0xff) + chr(obj>>8)) return # Next check for 4-byte signed ints: ! high_bits = obj >> 31 # note that Python shift sign-extends if high_bits == 0 or high_bits == -1: # All high bits are copies of bit 2**31, so the value # fits in a 4-byte signed int. ! self.write(BININT + pack("= 2: ! bytes = encode_long(obj) n = len(bytes) if n < 256: *************** *** 395,465 **** else: self.write(LONG4 + pack("d', object)) else: ! self.write(FLOAT + `object` + '\n') dispatch[FloatType] = save_float ! def save_string(self, object, pack=struct.pack): if self.bin: ! n = len(object) if n < 256: ! self.write(SHORT_BINSTRING + chr(n) + object) else: ! self.write(BINSTRING + pack("d', obj)) else: ! self.write(FLOAT + `obj` + '\n') dispatch[FloatType] = save_float ! def save_string(self, obj, pack=struct.pack): if self.bin: ! n = len(obj) if n < 256: ! self.write(SHORT_BINSTRING + chr(n) + obj) else: ! self.write(BINSTRING + pack("= 2: ! for element in object: save(element) # Subtle. Same as in the big comment below. ! if id(object) in memo: ! get = self.get(memo[id(object)][0]) write(POP * n + get) else: write(_tuplesize2code[n]) ! self.memoize(object) return --- 466,478 ---- memo = self.memo if n <= 3 and proto >= 2: ! for element in obj: save(element) # Subtle. Same as in the big comment below. ! if id(obj) in memo: ! get = self.get(memo[id(obj)][0]) write(POP * n + get) else: write(_tuplesize2code[n]) ! self.memoize(obj) return *************** *** 483,490 **** # has more than 3 elements. write(MARK) ! for element in object: save(element) ! if n and id(object) in memo: # Subtle. d was not in memo when we entered save_tuple(), so # the process of saving the tuple's elements must have saved --- 480,487 ---- # has more than 3 elements. write(MARK) ! for element in obj: save(element) ! if n and id(obj) in memo: # Subtle. d was not in memo when we entered save_tuple(), so # the process of saving the tuple's elements must have saved *************** *** 494,498 **** # could have been done in the "for element" loop instead, but # recursive tuples are a rare thing. ! get = self.get(memo[id(object)][0]) if proto: write(POP_MARK + get) --- 491,495 ---- # could have been done in the "for element" loop instead, but # recursive tuples are a rare thing. ! get = self.get(memo[id(obj)][0]) if proto: write(POP_MARK + get) *************** *** 503,515 **** # No recursion (including the empty-tuple case for protocol 0). self.write(TUPLE) ! if object: # No need to memoize empty tuple ! self.memoize(object) dispatch[TupleType] = save_tuple ! def save_empty_tuple(self, object): self.write(EMPTY_TUPLE) ! def save_list(self, object): write = self.write save = self.save --- 500,512 ---- # No recursion (including the empty-tuple case for protocol 0). self.write(TUPLE) ! if obj: # No need to memoize empty tuple ! self.memoize(obj) dispatch[TupleType] = save_tuple ! def save_empty_tuple(self, obj): self.write(EMPTY_TUPLE) ! def save_list(self, obj): write = self.write save = self.save *************** *** 517,530 **** if self.bin: write(EMPTY_LIST) ! self.memoize(object) ! n = len(object) if n > 1: write(MARK) ! for element in object: save(element) write(APPENDS) elif n: assert n == 1 ! save(object[0]) write(APPEND) # else the list is empty, and we're already done --- 514,527 ---- if self.bin: write(EMPTY_LIST) ! self.memoize(obj) ! n = len(obj) if n > 1: write(MARK) ! for element in obj: save(element) write(APPENDS) elif n: assert n == 1 ! save(obj[0]) write(APPEND) # else the list is empty, and we're already done *************** *** 532,537 **** else: # proto 0 -- can't use EMPTY_LIST or APPENDS write(MARK + LIST) ! self.memoize(object) ! for element in object: save(element) write(APPEND) --- 529,534 ---- else: # proto 0 -- can't use EMPTY_LIST or APPENDS write(MARK + LIST) ! self.memoize(obj) ! for element in obj: save(element) write(APPEND) *************** *** 539,551 **** dispatch[ListType] = save_list ! def save_dict(self, object): write = self.write save = self.save ! items = object.iteritems() if self.bin: write(EMPTY_DICT) ! self.memoize(object) ! if len(object) > 1: write(MARK) for key, value in items: --- 536,548 ---- dispatch[ListType] = save_list ! def save_dict(self, obj): write = self.write save = self.save ! items = obj.iteritems() if self.bin: write(EMPTY_DICT) ! self.memoize(obj) ! if len(obj) > 1: write(MARK) for key, value in items: *************** *** 557,563 **** else: # proto 0 -- can't use EMPTY_DICT or SETITEMS write(MARK + DICT) ! self.memoize(object) ! # proto 0 or len(object) < 2 for key, value in items: save(key) --- 554,560 ---- else: # proto 0 -- can't use EMPTY_DICT or SETITEMS write(MARK + DICT) ! self.memoize(obj) ! # proto 0 or len(obj) < 2 for key, value in items: save(key) *************** *** 569,574 **** dispatch[PyStringMap] = save_dict ! def save_inst(self, object): ! cls = object.__class__ memo = self.memo --- 566,571 ---- dispatch[PyStringMap] = save_dict ! def save_inst(self, obj): ! cls = obj.__class__ memo = self.memo *************** *** 576,581 **** save = self.save ! if hasattr(object, '__getinitargs__'): ! args = object.__getinitargs__() len(args) # XXX Assert it's a sequence _keep_alive(args, memo) --- 573,578 ---- save = self.save ! if hasattr(obj, '__getinitargs__'): ! args = obj.__getinitargs__() len(args) # XXX Assert it's a sequence _keep_alive(args, memo) *************** *** 595,604 **** write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') ! self.memoize(object) try: ! getstate = object.__getstate__ except AttributeError: ! stuff = object.__dict__ else: stuff = getstate() --- 592,601 ---- write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') ! self.memoize(obj) try: ! getstate = obj.__getstate__ except AttributeError: ! stuff = obj.__dict__ else: stuff = getstate() *************** *** 609,623 **** dispatch[InstanceType] = save_inst ! def save_global(self, object, name = None): write = self.write memo = self.memo if name is None: ! name = object.__name__ try: ! module = object.__module__ except AttributeError: ! module = whichmodule(object, name) try: --- 606,620 ---- dispatch[InstanceType] = save_inst ! def save_global(self, obj, name = None): write = self.write memo = self.memo if name is None: ! name = obj.__name__ try: ! module = obj.__module__ except AttributeError: ! module = whichmodule(obj, name) try: *************** *** 628,640 **** raise PicklingError( "Can't pickle %r: it's not found as %s.%s" % ! (object, module, name)) else: ! if klass is not object: raise PicklingError( "Can't pickle %r: it's not the same object as %s.%s" % ! (object, module, name)) write(GLOBAL + module + '\n' + name + '\n') ! self.memoize(object) dispatch[ClassType] = save_global --- 625,637 ---- raise PicklingError( "Can't pickle %r: it's not found as %s.%s" % ! (obj, module, name)) else: ! if klass is not obj: raise PicklingError( "Can't pickle %r: it's not the same object as %s.%s" % ! (obj, module, name)) write(GLOBAL + module + '\n' + name + '\n') ! self.memoize(obj) dispatch[ClassType] = save_global *************** *** 701,705 **** object can be a file object opened for reading, a StringIO object, or any other custom object that meets this interface. - """ self.readline = file.readline --- 698,701 ---- *************** *** 708,716 **** def load(self): ! """Read a pickled object representation from the open file object. ! ! Return the reconstituted object hierarchy specified in the file ! object. """ self.mark = object() # any new unique object --- 704,710 ---- def load(self): ! """Read a pickled object representation from the open file. + Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object *************** *** 992,995 **** --- 986,996 ---- dispatch[OBJ] = load_obj + def load_newobj(self): + args = self.stack.pop() + cls = self.stack[-1] + obj = cls.__new__(cls, *args) + self.stack[-1:] = obj + dispatch[NEWOBJ] = load_newobj + def load_global(self): module = self.readline()[:-1] *************** *** 1198,1207 **** from StringIO import StringIO ! def dump(object, file, proto=1): ! Pickler(file, proto).dump(object) ! def dumps(object, proto=1): file = StringIO() ! Pickler(file, proto).dump(object) return file.getvalue() --- 1199,1208 ---- from StringIO import StringIO ! def dump(obj, file, proto=1): ! Pickler(file, proto).dump(obj) ! def dumps(obj, proto=1): file = StringIO() ! Pickler(file, proto).dump(obj) return file.getvalue() From gvanrossum@users.sourceforge.net Tue Jan 28 15:19:58 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:19:58 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.107,1.108 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv18102 Modified Files: pickle.py Log Message: Add a few comments. Change the way the protocol is checked (it must be one of 0, 1 or 2). I should note that the previous checkin also added NEWOBJ support to the unpickler -- but there's nothing yet that generates this. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.107 retrieving revision 1.108 diff -C2 -d -r1.107 -r1.108 *** pickle.py 28 Jan 2003 15:10:22 -0000 1.107 --- pickle.py 28 Jan 2003 15:19:53 -0000 1.108 *************** *** 159,162 **** --- 159,165 ---- _quotes = ["'", '"'] + + # Pickling machinery + class Pickler: *************** *** 179,187 **** """ ! if not 0 <= proto <= 2: raise ValueError, "pickle protocol must be 0, 1 or 2" self.write = file.write self.memo = {} ! self.proto = proto self.bin = proto >= 1 --- 182,190 ---- """ ! if proto not in (0, 1, 2): raise ValueError, "pickle protocol must be 0, 1 or 2" self.write = file.write self.memo = {} ! self.proto = int(proto) self.bin = proto >= 1 *************** *** 640,643 **** --- 643,647 ---- dispatch[TypeType] = save_global + # Pickling helpers def _keep_alive(x, memo): *************** *** 683,686 **** --- 687,692 ---- return name + + # Unpickling machinery class Unpickler: From tim_one@users.sourceforge.net Tue Jan 28 15:28:01 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:28:01 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv20514/lib Modified Files: pickletools.py Log Message: dis(): Not all opcodes are printable anymore, so print the repr of the opcode character instead (but stripping the quotes). Added a proto 2 test section for the canonical recursive-tuple case. Note that since pickle's save_tuple() takes different paths depending on tuple length now, beefier tests are really needed (but not in pickletools); the "short tuple" case tried here was actually broken yesterday, and it's subtle stuff so needs to be tested. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** pickletools.py 28 Jan 2003 15:09:10 -0000 1.14 --- pickletools.py 28 Jan 2003 15:27:57 -0000 1.15 *************** *** 1875,1881 **** print >> out, "%5d:" % pos, ! line = "%s %s%s" % (opcode.code, ! indentchunk * len(markstack), ! opcode.name) markmsg = None --- 1875,1881 ---- print >> out, "%5d:" % pos, ! line = "%-4s %s%s" % (repr(opcode.code)[1:-1], ! indentchunk * len(markstack), ! opcode.name) markmsg = None *************** *** 1905,1931 **** >>> pkl = pickle.dumps(x, 0) >>> dis(pkl) ! 0: ( MARK ! 1: l LIST (MARK at 0) ! 2: p PUT 0 ! 5: I INT 1 ! 8: a APPEND ! 9: I INT 2 ! 12: a APPEND ! 13: ( MARK ! 14: I INT 3 ! 17: I INT 4 ! 20: t TUPLE (MARK at 13) ! 21: p PUT 1 ! 24: a APPEND ! 25: ( MARK ! 26: d DICT (MARK at 25) ! 27: p PUT 2 ! 30: S STRING 'abc' ! 37: p PUT 3 ! 40: V UNICODE u'def' ! 45: p PUT 4 ! 48: s SETITEM ! 49: a APPEND ! 50: . STOP Try again with a "binary" pickle. --- 1905,1931 ---- >>> pkl = pickle.dumps(x, 0) >>> dis(pkl) ! 0: ( MARK ! 1: l LIST (MARK at 0) ! 2: p PUT 0 ! 5: I INT 1 ! 8: a APPEND ! 9: I INT 2 ! 12: a APPEND ! 13: ( MARK ! 14: I INT 3 ! 17: I INT 4 ! 20: t TUPLE (MARK at 13) ! 21: p PUT 1 ! 24: a APPEND ! 25: ( MARK ! 26: d DICT (MARK at 25) ! 27: p PUT 2 ! 30: S STRING 'abc' ! 37: p PUT 3 ! 40: V UNICODE u'def' ! 45: p PUT 4 ! 48: s SETITEM ! 49: a APPEND ! 50: . STOP Try again with a "binary" pickle. *************** *** 1933,1955 **** >>> pkl = pickle.dumps(x, 1) >>> dis(pkl) ! 0: ] EMPTY_LIST ! 1: q BINPUT 0 ! 3: ( MARK ! 4: K BININT1 1 ! 6: K BININT1 2 ! 8: ( MARK ! 9: K BININT1 3 ! 11: K BININT1 4 ! 13: t TUPLE (MARK at 8) ! 14: q BINPUT 1 ! 16: } EMPTY_DICT ! 17: q BINPUT 2 ! 19: U SHORT_BINSTRING 'abc' ! 24: q BINPUT 3 ! 26: X BINUNICODE u'def' ! 34: q BINPUT 4 ! 36: s SETITEM ! 37: e APPENDS (MARK at 3) ! 38: . STOP Exercise the INST/OBJ/BUILD family. --- 1933,1955 ---- >>> pkl = pickle.dumps(x, 1) >>> dis(pkl) ! 0: ] EMPTY_LIST ! 1: q BINPUT 0 ! 3: ( MARK ! 4: K BININT1 1 ! 6: K BININT1 2 ! 8: ( MARK ! 9: K BININT1 3 ! 11: K BININT1 4 ! 13: t TUPLE (MARK at 8) ! 14: q BINPUT 1 ! 16: } EMPTY_DICT ! 17: q BINPUT 2 ! 19: U SHORT_BINSTRING 'abc' ! 24: q BINPUT 3 ! 26: X BINUNICODE u'def' ! 34: q BINPUT 4 ! 36: s SETITEM ! 37: e APPENDS (MARK at 3) ! 38: . STOP Exercise the INST/OBJ/BUILD family. *************** *** 1957,2005 **** >>> import random >>> dis(pickle.dumps(random.random, 0)) ! 0: c GLOBAL 'random random' ! 15: p PUT 0 ! 18: . STOP >>> x = [pickle.PicklingError()] * 2 >>> dis(pickle.dumps(x, 0)) ! 0: ( MARK ! 1: l LIST (MARK at 0) ! 2: p PUT 0 ! 5: ( MARK ! 6: i INST 'pickle PicklingError' (MARK at 5) ! 28: p PUT 1 ! 31: ( MARK ! 32: d DICT (MARK at 31) ! 33: p PUT 2 ! 36: S STRING 'args' ! 44: p PUT 3 ! 47: ( MARK ! 48: t TUPLE (MARK at 47) ! 49: s SETITEM ! 50: b BUILD ! 51: a APPEND ! 52: g GET 1 ! 55: a APPEND ! 56: . STOP >>> dis(pickle.dumps(x, 1)) ! 0: ] EMPTY_LIST ! 1: q BINPUT 0 ! 3: ( MARK ! 4: ( MARK ! 5: c GLOBAL 'pickle PicklingError' ! 27: q BINPUT 1 ! 29: o OBJ (MARK at 4) ! 30: q BINPUT 2 ! 32: } EMPTY_DICT ! 33: q BINPUT 3 ! 35: U SHORT_BINSTRING 'args' ! 41: q BINPUT 4 ! 43: ) EMPTY_TUPLE ! 44: s SETITEM ! 45: b BUILD ! 46: h BINGET 2 ! 48: e APPENDS (MARK at 3) ! 49: . STOP Try "the canonical" recursive-object test. --- 1957,2005 ---- >>> import random >>> dis(pickle.dumps(random.random, 0)) ! 0: c GLOBAL 'random random' ! 15: p PUT 0 ! 18: . STOP >>> x = [pickle.PicklingError()] * 2 >>> dis(pickle.dumps(x, 0)) ! 0: ( MARK ! 1: l LIST (MARK at 0) ! 2: p PUT 0 ! 5: ( MARK ! 6: i INST 'pickle PicklingError' (MARK at 5) ! 28: p PUT 1 ! 31: ( MARK ! 32: d DICT (MARK at 31) ! 33: p PUT 2 ! 36: S STRING 'args' ! 44: p PUT 3 ! 47: ( MARK ! 48: t TUPLE (MARK at 47) ! 49: s SETITEM ! 50: b BUILD ! 51: a APPEND ! 52: g GET 1 ! 55: a APPEND ! 56: . STOP >>> dis(pickle.dumps(x, 1)) ! 0: ] EMPTY_LIST ! 1: q BINPUT 0 ! 3: ( MARK ! 4: ( MARK ! 5: c GLOBAL 'pickle PicklingError' ! 27: q BINPUT 1 ! 29: o OBJ (MARK at 4) ! 30: q BINPUT 2 ! 32: } EMPTY_DICT ! 33: q BINPUT 3 ! 35: U SHORT_BINSTRING 'args' ! 41: q BINPUT 4 ! 43: ) EMPTY_TUPLE ! 44: s SETITEM ! 45: b BUILD ! 46: h BINGET 2 ! 48: e APPENDS (MARK at 3) ! 49: . STOP Try "the canonical" recursive-object test. *************** *** 2017,2038 **** True >>> dis(pickle.dumps(L, 0)) ! 0: ( MARK ! 1: l LIST (MARK at 0) ! 2: p PUT 0 ! 5: ( MARK ! 6: g GET 0 ! 9: t TUPLE (MARK at 5) ! 10: p PUT 1 ! 13: a APPEND ! 14: . STOP >>> dis(pickle.dumps(L, 1)) ! 0: ] EMPTY_LIST ! 1: q BINPUT 0 ! 3: ( MARK ! 4: h BINGET 0 ! 6: t TUPLE (MARK at 3) ! 7: q BINPUT 1 ! 9: a APPEND ! 10: . STOP The protocol 0 pickle of the tuple causes the disassembly to get confused, --- 2017,2038 ---- True >>> dis(pickle.dumps(L, 0)) ! 0: ( MARK ! 1: l LIST (MARK at 0) ! 2: p PUT 0 ! 5: ( MARK ! 6: g GET 0 ! 9: t TUPLE (MARK at 5) ! 10: p PUT 1 ! 13: a APPEND ! 14: . STOP >>> dis(pickle.dumps(L, 1)) ! 0: ] EMPTY_LIST ! 1: q BINPUT 0 ! 3: ( MARK ! 4: h BINGET 0 ! 6: t TUPLE (MARK at 3) ! 7: q BINPUT 1 ! 9: a APPEND ! 10: . STOP The protocol 0 pickle of the tuple causes the disassembly to get confused, *************** *** 2044,2072 **** >>> dis(pickle.dumps(T, 0)) ! 0: ( MARK ! 1: ( MARK ! 2: l LIST (MARK at 1) ! 3: p PUT 0 ! 6: ( MARK ! 7: g GET 0 ! 10: t TUPLE (MARK at 6) ! 11: p PUT 1 ! 14: a APPEND ! 15: 0 POP ! 16: 0 POP ! 17: g GET 1 ! 20: . STOP >>> dis(pickle.dumps(T, 1)) ! 0: ( MARK ! 1: ] EMPTY_LIST ! 2: q BINPUT 0 ! 4: ( MARK ! 5: h BINGET 0 ! 7: t TUPLE (MARK at 4) ! 8: q BINPUT 1 ! 10: a APPEND ! 11: 1 POP_MARK (MARK at 0) ! 12: h BINGET 1 ! 14: . STOP """ --- 2044,2096 ---- >>> dis(pickle.dumps(T, 0)) ! 0: ( MARK ! 1: ( MARK ! 2: l LIST (MARK at 1) ! 3: p PUT 0 ! 6: ( MARK ! 7: g GET 0 ! 10: t TUPLE (MARK at 6) ! 11: p PUT 1 ! 14: a APPEND ! 15: 0 POP ! 16: 0 POP ! 17: g GET 1 ! 20: . STOP >>> dis(pickle.dumps(T, 1)) ! 0: ( MARK ! 1: ] EMPTY_LIST ! 2: q BINPUT 0 ! 4: ( MARK ! 5: h BINGET 0 ! 7: t TUPLE (MARK at 4) ! 8: q BINPUT 1 ! 10: a APPEND ! 11: 1 POP_MARK (MARK at 0) ! 12: h BINGET 1 ! 14: . STOP ! ! Try protocol 2. ! ! >>> dis(pickle.dumps(L, 2)) ! 0: \x80 PROTO 2 ! 2: ] EMPTY_LIST ! 3: q BINPUT 0 ! 5: h BINGET 0 ! 7: \x85 TUPLE1 ! 8: q BINPUT 1 ! 10: a APPEND ! 11: . STOP ! ! >>> dis(pickle.dumps(T, 2)) ! 0: \x80 PROTO 2 ! 2: ] EMPTY_LIST ! 3: q BINPUT 0 ! 5: h BINGET 0 ! 7: \x85 TUPLE1 ! 8: q BINPUT 1 ! 10: a APPEND ! 11: 0 POP ! 12: h BINGET 1 ! 14: . STOP """ From bwarsaw@users.sourceforge.net Tue Jan 28 15:33:07 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:33:07 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb __init__.py,1.3,1.3.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb In directory sc8-pr-cvs1:/tmp/cvs-serv23888 Modified Files: Tag: bsddb-bsddb3-schizo-branch __init__.py Log Message: Promote the use of bsddb3.db instead of bsddb3._db for the public API, and use db everywhere in this package. Continue to provide _db for backwards compatibility. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/__init__.py,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 *** __init__.py 30 Dec 2002 20:52:07 -0000 1.3 --- __init__.py 28 Jan 2003 15:33:04 -0000 1.3.4.1 *************** *** 45,53 **** raise ! # bsddb3 calls it _db ! _db = _bsddb ! __version__ = _db.__version__ ! error = _db.DBError # So bsddb.error will mean something... #---------------------------------------------------------------------- --- 45,53 ---- raise ! # bsddb3 calls it db, but provide _db for backwards compatibility ! db = _db = _bsddb ! __version__ = db.__version__ ! error = db.DBError # So bsddb.error will mean something... #---------------------------------------------------------------------- *************** *** 153,157 **** flags = _checkflag(flag) ! d = _db.DB() d.set_flags(hflags) if cachesize is not None: d.set_cachesize(0, cachesize) --- 153,157 ---- flags = _checkflag(flag) ! d = db.DB() d.set_flags(hflags) if cachesize is not None: d.set_cachesize(0, cachesize) *************** *** 160,164 **** if ffactor is not None: d.set_h_ffactor(ffactor) if nelem is not None: d.set_h_nelem(nelem) ! d.open(file, _db.DB_HASH, flags, mode) return _DBWithCursor(d) --- 160,164 ---- if ffactor is not None: d.set_h_ffactor(ffactor) if nelem is not None: d.set_h_nelem(nelem) ! d.open(file, db.DB_HASH, flags, mode) return _DBWithCursor(d) *************** *** 170,174 **** flags = _checkflag(flag) ! d = _db.DB() if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) --- 170,174 ---- flags = _checkflag(flag) ! d = db.DB() if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) *************** *** 177,181 **** if minkeypage is not None: d.set_bt_minkey(minkeypage) if maxkeypage is not None: d.set_bt_maxkey(maxkeypage) ! d.open(file, _db.DB_BTREE, flags, mode) return _DBWithCursor(d) --- 177,181 ---- if minkeypage is not None: d.set_bt_minkey(minkeypage) if maxkeypage is not None: d.set_bt_maxkey(maxkeypage) ! d.open(file, db.DB_BTREE, flags, mode) return _DBWithCursor(d) *************** *** 188,192 **** flags = _checkflag(flag) ! d = _db.DB() if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) --- 188,192 ---- flags = _checkflag(flag) ! d = db.DB() if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) *************** *** 197,201 **** if source is not None: d.set_re_source(source) if pad is not None: d.set_re_pad(pad) ! d.open(file, _db.DB_RECNO, flags, mode) return _DBWithCursor(d) --- 197,201 ---- if source is not None: d.set_re_source(source) if pad is not None: d.set_re_pad(pad) ! d.open(file, db.DB_RECNO, flags, mode) return _DBWithCursor(d) *************** *** 205,220 **** def _checkflag(flag): if flag == 'r': ! flags = _db.DB_RDONLY elif flag == 'rw': flags = 0 elif flag == 'w': ! flags = _db.DB_CREATE elif flag == 'c': ! flags = _db.DB_CREATE elif flag == 'n': ! flags = _db.DB_CREATE | _db.DB_TRUNCATE else: raise error, "flags should be one of 'r', 'w', 'c' or 'n'" ! return flags | _db.DB_THREAD #---------------------------------------------------------------------- --- 205,220 ---- def _checkflag(flag): if flag == 'r': ! flags = db.DB_RDONLY elif flag == 'rw': flags = 0 elif flag == 'w': ! flags = db.DB_CREATE elif flag == 'c': ! flags = db.DB_CREATE elif flag == 'n': ! flags = db.DB_CREATE | db.DB_TRUNCATE else: raise error, "flags should be one of 'r', 'w', 'c' or 'n'" ! return flags | db.DB_THREAD #---------------------------------------------------------------------- *************** *** 232,236 **** del thread except ImportError: ! _db.DB_THREAD = 0 --- 232,236 ---- del thread except ImportError: ! db.DB_THREAD = 0 From bwarsaw@users.sourceforge.net Tue Jan 28 15:34:22 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:34:22 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb dbshelve.py,1.4,1.4.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb In directory sc8-pr-cvs1:/tmp/cvs-serv24482 Modified Files: Tag: bsddb-bsddb3-schizo-branch dbshelve.py Log Message: Add compatibility idiom, which tries to get bsddb.db first, falling back to bsddb3.db Index: dbshelve.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/dbshelve.py,v retrieving revision 1.4 retrieving revision 1.4.4.1 diff -C2 -d -r1.4 -r1.4.4.1 *** dbshelve.py 30 Dec 2002 20:52:07 -0000 1.4 --- dbshelve.py 28 Jan 2003 15:34:20 -0000 1.4.4.1 *************** *** 31,35 **** import cPickle ! from bsddb import db #------------------------------------------------------------------------ --- 31,40 ---- import cPickle ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db #------------------------------------------------------------------------ From gvanrossum@users.sourceforge.net Tue Jan 28 15:37:18 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:37:18 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv26305 Modified Files: pickletools.py Log Message: _dis_test should be a raw string now that it contains \x escapes. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** pickletools.py 28 Jan 2003 15:27:57 -0000 1.15 --- pickletools.py 28 Jan 2003 15:37:13 -0000 1.16 *************** *** 1900,1904 **** ! _dis_test = """ >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] --- 1900,1904 ---- ! _dis_test = r""" >>> import pickle >>> x = [1, 2, (3, 4), {'abc': u"def"}] From bwarsaw@users.sourceforge.net Tue Jan 28 15:46:28 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:46:28 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb dbtables.py,1.6,1.6.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb In directory sc8-pr-cvs1:/tmp/cvs-serv31040 Modified Files: Tag: bsddb-bsddb3-schizo-branch dbtables.py Log Message: Add compatibility idiom, which tries to get bsddb.db first, falling back to bsddb3.db Also various code cleanups: - remove the need for the string module - always use cPickle module - fix type comparisons - more consistent formatting Index: dbtables.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/dbtables.py,v retrieving revision 1.6 retrieving revision 1.6.4.1 diff -C2 -d -r1.6 -r1.6.4.1 *** dbtables.py 30 Dec 2002 20:52:07 -0000 1.6 --- dbtables.py 28 Jan 2003 15:46:25 -0000 1.6.4.1 *************** *** 18,38 **** _cvsid = '$Id$' - import string - import sys - try: - import cPickle - pickle = cPickle - except ImportError: - import pickle - import whrandom - import xdrlib import re import copy ! from bsddb.db import * ! class TableDBError(StandardError): pass ! class TableAlreadyExists(TableDBError): pass --- 18,41 ---- _cvsid = '$Id$' import re + import sys import copy + import xdrlib + import whrandom + from types import ListType, StringType + import cPickle as pickle ! try: ! # For Python 2.3 ! from bsddb.db import * ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3.db import * ! class TableDBError(StandardError): ! pass ! class TableAlreadyExists(TableDBError): ! pass *************** *** 73,79 **** chars_to_escape = '.*+()[]?' for char in chars_to_escape : ! likestr = string.replace(likestr, char, '\\'+char) # convert %s to wildcards ! self.likestr = string.replace(likestr, '%', '.*') self.re = re.compile('^'+self.likestr+'$', re_flags) def __call__(self, s): --- 76,82 ---- chars_to_escape = '.*+()[]?' for char in chars_to_escape : ! likestr = likestr.replace(char, '\\'+char) # convert %s to wildcards ! self.likestr = likestr.replace('%', '.*') self.re = re.compile('^'+self.likestr+'$', re_flags) def __call__(self, s): *************** *** 85,89 **** _table_names_key = '__TABLE_NAMES__' # list of the tables in this db _columns = '._COLUMNS__' # table_name+this key contains a list of columns ! def _columns_key(table) : return table + _columns # --- 88,94 ---- _table_names_key = '__TABLE_NAMES__' # list of the tables in this db _columns = '._COLUMNS__' # table_name+this key contains a list of columns ! ! def _columns_key(table): ! return table + _columns # *************** *** 94,102 **** # row in the table. (no data is stored) _rowid_str_len = 8 # length in bytes of the unique rowid strings ! def _data_key(table, col, rowid) : return table + _data + col + _data + rowid ! def _search_col_data_key(table, col) : return table + _data + col + _data ! def _search_all_data_key(table) : return table + _data ! def _rowid_key(table, rowid) : return table + _rowid + rowid + _rowid ! def _search_rowid_key(table) : return table + _rowid def contains_metastrings(s) : --- 99,117 ---- # row in the table. (no data is stored) _rowid_str_len = 8 # length in bytes of the unique rowid strings ! ! def _data_key(table, col, rowid): ! return table + _data + col + _data + rowid ! ! def _search_col_data_key(table, col): ! return table + _data + col + _data ! ! def _search_all_data_key(table): ! return table + _data ! ! def _rowid_key(table, rowid): ! return table + _rowid + rowid + _rowid ! ! def _search_rowid_key(table): ! return table + _rowid def contains_metastrings(s) : *************** *** 104,113 **** metadata strings that might interfere with dbtables database operation. """ ! if string.find(s, _table_names_key) >= 0 or \ ! string.find(s, _columns) >= 0 or \ ! string.find(s, _data) >= 0 or \ ! string.find(s, _rowid) >= 0 : return 1 ! else : return 0 --- 119,129 ---- metadata strings that might interfere with dbtables database operation. """ ! if (s.find(_table_names_key) >= 0 or ! s.find(_columns) >= 0 or ! s.find(_data) >= 0 or ! s.find(_rowid) >= 0): ! # Then return 1 ! else: return 0 *************** *** 115,119 **** class bsdTableDB : def __init__(self, filename, dbhome, create=0, truncate=0, mode=0600, ! recover=0, dbflags=0) : """bsdTableDB.open(filename, dbhome, create=0, truncate=0, mode=0600) Open database name in the dbhome BerkeleyDB directory. --- 131,135 ---- class bsdTableDB : def __init__(self, filename, dbhome, create=0, truncate=0, mode=0600, ! recover=0, dbflags=0): """bsdTableDB.open(filename, dbhome, create=0, truncate=0, mode=0600) Open database name in the dbhome BerkeleyDB directory. *************** *** 187,191 **** try: key, data = cur.first() ! while 1 : print `{key: data}` next = cur.next() --- 203,207 ---- try: key, data = cur.first() ! while 1: print `{key: data}` next = cur.next() *************** *** 203,207 **** raises TableDBError if it already exists or for other DB errors. """ ! assert type(columns) == type([]) txn = None try: --- 219,223 ---- raises TableDBError if it already exists or for other DB errors. """ ! assert isinstance(columns, ListType) txn = None try: *************** *** 234,240 **** txn.commit() txn = None - except DBError, dberror: ! if txn : txn.abort() raise TableDBError, dberror[1] --- 250,255 ---- txn.commit() txn = None except DBError, dberror: ! if txn: txn.abort() raise TableDBError, dberror[1] *************** *** 245,250 **** [] if the table doesn't exist. """ ! assert type(table) == type('') ! if contains_metastrings(table) : raise ValueError, "bad table name: contains reserved metastrings" --- 260,265 ---- [] if the table doesn't exist. """ ! assert isinstance(table, StringType) ! if contains_metastrings(table): raise ValueError, "bad table name: contains reserved metastrings" *************** *** 274,278 **** all of its current columns. """ ! assert type(columns) == type([]) try: self.CreateTable(table, columns) --- 289,293 ---- all of its current columns. """ ! assert isinstance(columns, ListType) try: self.CreateTable(table, columns) *************** *** 332,336 **** """Create a new unique row identifier""" unique = 0 ! while not unique : # Generate a random 64-bit row ID string # (note: this code has <64 bits of randomness --- 347,351 ---- """Create a new unique row identifier""" unique = 0 ! while not unique: # Generate a random 64-bit row ID string # (note: this code has <64 bits of randomness *************** *** 359,370 **** txn = None try: ! if not self.db.has_key(_columns_key(table)) : raise TableDBError, "unknown table" # check the validity of each column name ! if not self.__tablecolumns.has_key(table) : self.__load_column_info(table) for column in rowdict.keys() : ! if not self.__tablecolumns[table].count(column) : raise TableDBError, "unknown column: "+`column` --- 374,385 ---- txn = None try: ! if not self.db.has_key(_columns_key(table)): raise TableDBError, "unknown table" # check the validity of each column name ! if not self.__tablecolumns.has_key(table): self.__load_column_info(table) for column in rowdict.keys() : ! if not self.__tablecolumns[table].count(column): raise TableDBError, "unknown column: "+`column` *************** *** 374,378 **** # insert the row values into the table database ! for column, dataitem in rowdict.items() : # store the value self.db.put(_data_key(table, column, rowid), dataitem, txn=txn) --- 389,393 ---- # insert the row values into the table database ! for column, dataitem in rowdict.items(): # store the value self.db.put(_data_key(table, column, rowid), dataitem, txn=txn) *************** *** 393,397 **** ! def Modify(self, table, conditions={}, mappings={}) : """Modify(table, conditions) - Modify in rows matching 'conditions' using mapping functions in 'mappings' --- 408,412 ---- ! def Modify(self, table, conditions={}, mappings={}): """Modify(table, conditions) - Modify in rows matching 'conditions' using mapping functions in 'mappings' *************** *** 408,415 **** # modify only requested columns columns = mappings.keys() ! for rowid in matching_rowids.keys() : txn = None try: ! for column in columns : txn = self.env.txn_begin() # modify the requested column --- 423,430 ---- # modify only requested columns columns = mappings.keys() ! for rowid in matching_rowids.keys(): txn = None try: ! for column in columns: txn = self.env.txn_begin() # modify the requested column *************** *** 434,438 **** except DBError, dberror: ! if txn : txn.abort() raise --- 449,453 ---- except DBError, dberror: ! if txn: txn.abort() raise *************** *** 441,445 **** raise TableDBError, dberror[1] ! def Delete(self, table, conditions={}) : """Delete(table, conditions) - Delete items matching the given conditions from the table. --- 456,460 ---- raise TableDBError, dberror[1] ! def Delete(self, table, conditions={}): """Delete(table, conditions) - Delete items matching the given conditions from the table. *************** *** 453,461 **** # delete row data from all columns columns = self.__tablecolumns[table] ! for rowid in matching_rowids.keys() : txn = None try: txn = self.env.txn_begin() ! for column in columns : # delete the data key try: --- 468,476 ---- # delete row data from all columns columns = self.__tablecolumns[table] ! for rowid in matching_rowids.keys(): txn = None try: txn = self.env.txn_begin() ! for column in columns: # delete the data key try: *************** *** 474,486 **** txn = None except DBError, dberror: ! if txn : txn.abort() raise - except DBError, dberror: raise TableDBError, dberror[1] ! def Select(self, table, columns, conditions={}) : """Select(table, conditions) - retrieve specific row data Returns a list of row column->value mapping dictionaries. --- 489,500 ---- txn = None except DBError, dberror: ! if txn: txn.abort() raise except DBError, dberror: raise TableDBError, dberror[1] ! def Select(self, table, columns, conditions={}): """Select(table, conditions) - retrieve specific row data Returns a list of row column->value mapping dictionaries. *************** *** 492,508 **** """ try: ! if not self.__tablecolumns.has_key(table) : self.__load_column_info(table) ! if columns is None : columns = self.__tablecolumns[table] matching_rowids = self.__Select(table, columns, conditions) except DBError, dberror: raise TableDBError, dberror[1] - # return the matches as a list of dictionaries return matching_rowids.values() ! def __Select(self, table, columns, conditions) : """__Select() - Used to implement Select and Delete (above) Returns a dictionary keyed on rowids containing dicts --- 506,521 ---- """ try: ! if not self.__tablecolumns.has_key(table): self.__load_column_info(table) ! if columns is None: columns = self.__tablecolumns[table] matching_rowids = self.__Select(table, columns, conditions) except DBError, dberror: raise TableDBError, dberror[1] # return the matches as a list of dictionaries return matching_rowids.values() ! def __Select(self, table, columns, conditions): """__Select() - Used to implement Select and Delete (above) Returns a dictionary keyed on rowids containing dicts *************** *** 514,523 **** """ # check the validity of each column name ! if not self.__tablecolumns.has_key(table) : self.__load_column_info(table) ! if columns is None : columns = self.tablecolumns[table] ! for column in (columns + conditions.keys()) : ! if not self.__tablecolumns[table].count(column) : raise TableDBError, "unknown column: "+`column` --- 527,536 ---- """ # check the validity of each column name ! if not self.__tablecolumns.has_key(table): self.__load_column_info(table) ! if columns is None: columns = self.tablecolumns[table] ! for column in (columns + conditions.keys()): ! if not self.__tablecolumns[table].count(column): raise TableDBError, "unknown column: "+`column` *************** *** 525,530 **** # column names containing the data for that row and column. matching_rowids = {} ! ! rejected_rowids = {} # keys are rowids that do not match # attempt to sort the conditions in such a way as to minimize full --- 538,543 ---- # column names containing the data for that row and column. matching_rowids = {} ! # keys are rowids that do not match ! rejected_rowids = {} # attempt to sort the conditions in such a way as to minimize full *************** *** 533,537 **** a = atuple[1] b = btuple[1] ! if type(a) == type(b) : if isinstance(a, PrefixCond) and isinstance(b, PrefixCond): # longest prefix first --- 546,550 ---- a = atuple[1] b = btuple[1] ! if type(a) is type(b): if isinstance(a, PrefixCond) and isinstance(b, PrefixCond): # longest prefix first *************** *** 558,586 **** cur = self.db.cursor() column_num = -1 ! for column, condition in conditionlist : column_num = column_num + 1 searchkey = _search_col_data_key(table, column) # speedup: don't linear search columns within loop ! if column in columns : savethiscolumndata = 1 # save the data for return ! else : savethiscolumndata = 0 # data only used for selection try: key, data = cur.set_range(searchkey) ! while key[:len(searchkey)] == searchkey : # extract the rowid from the key rowid = key[-_rowid_str_len:] ! if not rejected_rowids.has_key(rowid) : # if no condition was specified or the condition # succeeds, add row to our match list. ! if not condition or condition(data) : ! if not matching_rowids.has_key(rowid) : matching_rowids[rowid] = {} ! if savethiscolumndata : matching_rowids[rowid][column] = data ! else : ! if matching_rowids.has_key(rowid) : del matching_rowids[rowid] rejected_rowids[rowid] = rowid --- 571,599 ---- cur = self.db.cursor() column_num = -1 ! for column, condition in conditionlist: column_num = column_num + 1 searchkey = _search_col_data_key(table, column) # speedup: don't linear search columns within loop ! if column in columns: savethiscolumndata = 1 # save the data for return ! else: savethiscolumndata = 0 # data only used for selection try: key, data = cur.set_range(searchkey) ! while key[:len(searchkey)] == searchkey: # extract the rowid from the key rowid = key[-_rowid_str_len:] ! if not rejected_rowids.has_key(rowid): # if no condition was specified or the condition # succeeds, add row to our match list. ! if not condition or condition(data): ! if not matching_rowids.has_key(rowid): matching_rowids[rowid] = {} ! if savethiscolumndata: matching_rowids[rowid][column] = data ! else: ! if matching_rowids.has_key(rowid): del matching_rowids[rowid] rejected_rowids[rowid] = rowid *************** *** 589,593 **** except DBError, dberror: ! if dberror[0] != DB_NOTFOUND : raise continue --- 602,606 ---- except DBError, dberror: ! if dberror[0] != DB_NOTFOUND: raise continue *************** *** 600,607 **** # extract any remaining desired column data from the # database for the matching rows. ! if len(columns) > 0 : ! for rowid, rowdata in matching_rowids.items() : ! for column in columns : ! if rowdata.has_key(column) : continue try: --- 613,620 ---- # extract any remaining desired column data from the # database for the matching rows. ! if len(columns) > 0: ! for rowid, rowdata in matching_rowids.items(): ! for column in columns: ! if rowdata.has_key(column): continue try: *************** *** 609,613 **** _data_key(table, column, rowid)) except DBError, dberror: ! if dberror[0] != DB_NOTFOUND : raise rowdata[column] = None --- 622,626 ---- _data_key(table, column, rowid)) except DBError, dberror: ! if dberror[0] != DB_NOTFOUND: raise rowdata[column] = None *************** *** 617,623 **** ! def Drop(self, table) : ! """Remove an entire table from the database ! """ txn = None try: --- 630,635 ---- ! def Drop(self, table): ! """Remove an entire table from the database""" txn = None try: *************** *** 631,635 **** # delete all keys containing this tables column and row info table_key = _search_all_data_key(table) ! while 1 : try: key, data = cur.set_range(table_key) --- 643,647 ---- # delete all keys containing this tables column and row info table_key = _search_all_data_key(table) ! while 1: try: key, data = cur.set_range(table_key) *************** *** 637,641 **** break # only delete items in this table ! if key[:len(table_key)] != table_key : break cur.delete() --- 649,653 ---- break # only delete items in this table ! if key[:len(table_key)] != table_key: break cur.delete() *************** *** 643,647 **** # delete all rowids used by this table table_key = _search_rowid_key(table) ! while 1 : try: key, data = cur.set_range(table_key) --- 655,659 ---- # delete all rowids used by this table table_key = _search_rowid_key(table) ! while 1: try: key, data = cur.set_range(table_key) *************** *** 649,653 **** break # only delete items in this table ! if key[:len(table_key)] != table_key : break cur.delete() --- 661,665 ---- break # only delete items in this table ! if key[:len(table_key)] != table_key: break cur.delete() *************** *** 670,678 **** txn = None ! if self.__tablecolumns.has_key(table) : del self.__tablecolumns[table] except DBError, dberror: ! if txn : txn.abort() raise TableDBError, dberror[1] --- 682,690 ---- txn = None ! if self.__tablecolumns.has_key(table): del self.__tablecolumns[table] except DBError, dberror: ! if txn: txn.abort() raise TableDBError, dberror[1] From bwarsaw@users.sourceforge.net Tue Jan 28 15:48:29 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 28 Jan 2003 07:48:29 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb dbutils.py,1.5,1.5.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb In directory sc8-pr-cvs1:/tmp/cvs-serv32139 Modified Files: Tag: bsddb-bsddb3-schizo-branch dbutils.py Log Message: Add compatibility idiom, which tries to get bsddb.db first, falling back to bsddb3.db Index: dbutils.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/dbutils.py,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -C2 -d -r1.5 -r1.5.4.1 *** dbutils.py 30 Dec 2002 20:52:08 -0000 1.5 --- dbutils.py 28 Jan 2003 15:48:26 -0000 1.5.4.1 *************** *** 27,31 **** from time import sleep as _sleep ! from bsddb import _db # always sleep at least N seconds between retrys --- 27,36 ---- from time import sleep as _sleep ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db # always sleep at least N seconds between retrys *************** *** 61,65 **** try: return function(*_args, **_kwargs) ! except _db.DBLockDeadlockError: if _deadlock_VerboseFile: _deadlock_VerboseFile.write( --- 66,70 ---- try: return function(*_args, **_kwargs) ! except db.DBLockDeadlockError: if _deadlock_VerboseFile: _deadlock_VerboseFile.write( From tim_one@users.sourceforge.net Tue Jan 28 16:01:35 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 08:01:35 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv6545/Lib Modified Files: pickletools.py Log Message: Use raw-mode docstring whenever there's an escape code in an example -- they're easier to read this way. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** pickletools.py 28 Jan 2003 15:37:13 -0000 1.16 --- pickletools.py 28 Jan 2003 16:01:25 -0000 1.17 *************** *** 186,192 **** def read_uint1(f): ! """ >>> import StringIO ! >>> read_uint1(StringIO.StringIO('\\xff')) 255 """ --- 186,192 ---- def read_uint1(f): ! r""" >>> import StringIO ! >>> read_uint1(StringIO.StringIO('\xff')) 255 """ *************** *** 205,213 **** def read_uint2(f): ! """ >>> import StringIO ! >>> read_uint2(StringIO.StringIO('\\xff\\x00')) 255 ! >>> read_uint2(StringIO.StringIO('\\xff\\xff')) 65535 """ --- 205,213 ---- def read_uint2(f): ! r""" >>> import StringIO ! >>> read_uint2(StringIO.StringIO('\xff\x00')) 255 ! >>> read_uint2(StringIO.StringIO('\xff\xff')) 65535 """ *************** *** 226,234 **** def read_int4(f): ! """ >>> import StringIO ! >>> read_int4(StringIO.StringIO('\\xff\\x00\\x00\\x00')) 255 ! >>> read_int4(StringIO.StringIO('\\x00\\x00\\x00\\x80')) == -(2**31) True """ --- 226,234 ---- def read_int4(f): ! r""" >>> import StringIO ! >>> read_int4(StringIO.StringIO('\xff\x00\x00\x00')) 255 ! >>> read_int4(StringIO.StringIO('\x00\x00\x00\x80')) == -(2**31) True """ *************** *** 247,264 **** def read_stringnl(f, decode=True, stripquotes=True): ! """ >>> import StringIO ! >>> read_stringnl(StringIO.StringIO("'abcd'\\nefg\\n")) 'abcd' ! >>> read_stringnl(StringIO.StringIO("\\n")) Traceback (most recent call last): ... ValueError: no string quotes around '' ! >>> read_stringnl(StringIO.StringIO("\\n"), stripquotes=False) '' ! >>> read_stringnl(StringIO.StringIO("''\\n")) '' --- 247,264 ---- def read_stringnl(f, decode=True, stripquotes=True): ! r""" >>> import StringIO ! >>> read_stringnl(StringIO.StringIO("'abcd'\nefg\n")) 'abcd' ! >>> read_stringnl(StringIO.StringIO("\n")) Traceback (most recent call last): ... ValueError: no string quotes around '' ! >>> read_stringnl(StringIO.StringIO("\n"), stripquotes=False) '' ! >>> read_stringnl(StringIO.StringIO("''\n")) '' *************** *** 269,274 **** Embedded escapes are undone in the result. ! >>> read_stringnl(StringIO.StringIO("'a\\\\nb\\x00c\\td'\\n'e'")) ! 'a\\nb\\x00c\\td' """ --- 269,274 ---- Embedded escapes are undone in the result. ! >>> read_stringnl(StringIO.StringIO(r"'a\n\\b\x00c\td'" + "\n'e'")) ! 'a\n\\b\x00c\td' """ *************** *** 320,326 **** def read_stringnl_noescape_pair(f): ! """ >>> import StringIO ! >>> read_stringnl_noescape_pair(StringIO.StringIO("Queue\\nEmpty\\njunk")) 'Queue Empty' """ --- 320,326 ---- def read_stringnl_noescape_pair(f): ! r""" >>> import StringIO ! >>> read_stringnl_noescape_pair(StringIO.StringIO("Queue\nEmpty\njunk")) 'Queue Empty' """ *************** *** 342,352 **** def read_string4(f): ! """ >>> import StringIO ! >>> read_string4(StringIO.StringIO("\\x00\\x00\\x00\\x00abc")) '' ! >>> read_string4(StringIO.StringIO("\\x03\\x00\\x00\\x00abcdef")) 'abc' ! >>> read_string4(StringIO.StringIO("\\x00\\x00\\x00\\x03abcdef")) Traceback (most recent call last): ... --- 342,352 ---- def read_string4(f): ! r""" >>> import StringIO ! >>> read_string4(StringIO.StringIO("\x00\x00\x00\x00abc")) '' ! >>> read_string4(StringIO.StringIO("\x03\x00\x00\x00abcdef")) 'abc' ! >>> read_string4(StringIO.StringIO("\x00\x00\x00\x03abcdef")) Traceback (most recent call last): ... *************** *** 376,384 **** def read_string1(f): ! """ >>> import StringIO ! >>> read_string1(StringIO.StringIO("\\x00")) '' ! >>> read_string1(StringIO.StringIO("\\x03abcdef")) 'abc' """ --- 376,384 ---- def read_string1(f): ! r""" >>> import StringIO ! >>> read_string1(StringIO.StringIO("\x00")) '' ! >>> read_string1(StringIO.StringIO("\x03abcdef")) 'abc' """ *************** *** 405,412 **** def read_unicodestringnl(f): ! """ >>> import StringIO ! >>> read_unicodestringnl(StringIO.StringIO("abc\\uabcd\\njunk")) ! u'abc\\uabcd' """ --- 405,412 ---- def read_unicodestringnl(f): ! r""" >>> import StringIO ! >>> read_unicodestringnl(StringIO.StringIO("abc\uabcd\njunk")) ! u'abc\uabcd' """ *************** *** 430,439 **** def read_unicodestring4(f): ! """ >>> import StringIO ! >>> s = u'abcd\\uabcd' >>> enc = s.encode('utf-8') >>> enc ! 'abcd\\xea\\xaf\\x8d' >>> n = chr(len(enc)) + chr(0) * 3 # little-endian 4-byte length >>> t = read_unicodestring4(StringIO.StringIO(n + enc + 'junk')) --- 430,439 ---- def read_unicodestring4(f): ! r""" >>> import StringIO ! >>> s = u'abcd\uabcd' >>> enc = s.encode('utf-8') >>> enc ! 'abcd\xea\xaf\x8d' >>> n = chr(len(enc)) + chr(0) * 3 # little-endian 4-byte length >>> t = read_unicodestring4(StringIO.StringIO(n + enc + 'junk')) *************** *** 470,479 **** def read_decimalnl_short(f): ! """ >>> import StringIO ! >>> read_decimalnl_short(StringIO.StringIO("1234\\n56")) 1234 ! >>> read_decimalnl_short(StringIO.StringIO("1234L\\n56")) Traceback (most recent call last): ... --- 470,479 ---- def read_decimalnl_short(f): ! r""" >>> import StringIO ! >>> read_decimalnl_short(StringIO.StringIO("1234\n56")) 1234 ! >>> read_decimalnl_short(StringIO.StringIO("1234L\n56")) Traceback (most recent call last): ... *************** *** 499,506 **** def read_decimalnl_long(f): ! """ >>> import StringIO ! >>> read_decimalnl_long(StringIO.StringIO("1234\\n56")) Traceback (most recent call last): ... --- 499,506 ---- def read_decimalnl_long(f): ! r""" >>> import StringIO ! >>> read_decimalnl_long(StringIO.StringIO("1234\n56")) Traceback (most recent call last): ... *************** *** 509,516 **** Someday the trailing 'L' will probably go away from this output. ! >>> read_decimalnl_long(StringIO.StringIO("1234L\\n56")) 1234L ! >>> read_decimalnl_long(StringIO.StringIO("123456789012345678901234L\\n6")) 123456789012345678901234L """ --- 509,516 ---- Someday the trailing 'L' will probably go away from this output. ! >>> read_decimalnl_long(StringIO.StringIO("1234L\n56")) 1234L ! >>> read_decimalnl_long(StringIO.StringIO("123456789012345678901234L\n6")) 123456789012345678901234L """ *************** *** 547,553 **** def read_floatnl(f): ! """ >>> import StringIO ! >>> read_floatnl(StringIO.StringIO("-1.25\\n6")) -1.25 """ --- 547,553 ---- def read_floatnl(f): ! r""" >>> import StringIO ! >>> read_floatnl(StringIO.StringIO("-1.25\n6")) -1.25 """ *************** *** 569,578 **** def read_float8(f): ! """ >>> import StringIO, struct >>> raw = struct.pack(">d", -1.25) >>> raw ! '\\xbf\\xf4\\x00\\x00\\x00\\x00\\x00\\x00' ! >>> read_float8(StringIO.StringIO(raw + "\\n")) -1.25 """ --- 569,578 ---- def read_float8(f): ! r""" >>> import StringIO, struct >>> raw = struct.pack(">d", -1.25) >>> raw ! '\xbf\xf4\x00\x00\x00\x00\x00\x00' ! >>> read_float8(StringIO.StringIO(raw + "\n")) -1.25 """ From bwarsaw@users.sourceforge.net Tue Jan 28 16:10:18 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 28 Jan 2003 08:10:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb/test test_all.py,1.1,1.1.4.1 test_associate.py,1.3,1.3.4.1 test_basics.py,1.5,1.5.2.1 test_compat.py,1.3,1.3.4.1 test_dbobj.py,1.3,1.3.4.1 test_dbshelve.py,1.4,1.4.4.1 test_dbtables.py,1.4,1.4.4.1 test_env_close.py,1.4,1.4.4.1 test_get_none.py,1.3,1.3.4.1 test_lock.py,1.2,1.2.4.1 test_misc.py,1.2,1.2.4.1 test_queue.py,1.2,1.2.4.1 test_recno.py,1.5,1.5.2.1 test_thread.py,1.4,1.4.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb/test In directory sc8-pr-cvs1:/tmp/cvs-serv10949/test Modified Files: Tag: bsddb-bsddb3-schizo-branch test_all.py test_associate.py test_basics.py test_compat.py test_dbobj.py test_dbshelve.py test_dbtables.py test_env_close.py test_get_none.py test_lock.py test_misc.py test_queue.py test_recno.py test_thread.py Log Message: Compatibility idiom Index: test_all.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_all.py,v retrieving revision 1.1 retrieving revision 1.1.4.1 diff -C2 -d -r1.1 -r1.1.4.1 *** test_all.py 30 Dec 2002 20:52:08 -0000 1.1 --- test_all.py 28 Jan 2003 16:09:55 -0000 1.1.4.1 *************** *** 17,21 **** def print_versions(): ! from bsddb import db print print '-=' * 38 --- 17,26 ---- def print_versions(): ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db print print '-=' * 38 Index: test_associate.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_associate.py,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 *** test_associate.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_associate.py 28 Jan 2003 16:09:56 -0000 1.3.4.1 *************** *** 17,21 **** from test_all import verbose ! from bsddb import db, dbshelve --- 17,26 ---- from test_all import verbose ! try: ! # For Python 2.3 ! from bsddb import db, dbshelve ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbshelve Index: test_basics.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_basics.py,v retrieving revision 1.5 retrieving revision 1.5.2.1 diff -C2 -d -r1.5 -r1.5.2.1 *** test_basics.py 17 Jan 2003 08:42:50 -0000 1.5 --- test_basics.py 28 Jan 2003 16:09:56 -0000 1.5.2.1 *************** *** 13,17 **** import unittest ! from bsddb import db from test_all import verbose --- 13,22 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db from test_all import verbose Index: test_compat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_compat.py,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 *** test_compat.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_compat.py 28 Jan 2003 16:09:56 -0000 1.3.4.1 *************** *** 5,9 **** import sys, os, string - from bsddb import hashopen, btopen, rnopen import bsddb import unittest --- 5,8 ---- *************** *** 12,15 **** --- 11,20 ---- from test_all import verbose + try: + # For Python 2.3 + from bsddb import db, hashopen, btopen, rnopen + except ImportError: + # For earlier Pythons w/distutils pybsddb + from bsddb3 import db, hashopen, btopen, rnopen *************** *** 127,131 **** else: if verbose: print "truth test: false" ! except bsddb.error: pass else: --- 132,136 ---- else: if verbose: print "truth test: false" ! except db.DBError: pass else: Index: test_dbobj.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_dbobj.py,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 *** test_dbobj.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_dbobj.py 28 Jan 2003 16:09:56 -0000 1.3.4.1 *************** *** 4,8 **** import glob ! from bsddb import db, dbobj --- 4,13 ---- import glob ! try: ! # For Python 2.3 ! from bsddb import db, dbobj ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbobj Index: test_dbshelve.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_dbshelve.py,v retrieving revision 1.4 retrieving revision 1.4.4.1 diff -C2 -d -r1.4 -r1.4.4.1 *** test_dbshelve.py 30 Dec 2002 20:52:08 -0000 1.4 --- test_dbshelve.py 28 Jan 2003 16:09:56 -0000 1.4.4.1 *************** *** 9,13 **** import unittest ! from bsddb import dbshelve, db from test_all import verbose --- 9,18 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db, dbshelve ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbshelve from test_all import verbose Index: test_dbtables.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_dbtables.py,v retrieving revision 1.4 retrieving revision 1.4.4.1 diff -C2 -d -r1.4 -r1.4.4.1 *** test_dbtables.py 30 Dec 2002 20:52:08 -0000 1.4 --- test_dbtables.py 28 Jan 2003 16:09:56 -0000 1.4.4.1 *************** *** 31,35 **** from test_all import verbose ! from bsddb import db, dbtables --- 31,40 ---- from test_all import verbose ! try: ! # For Python 2.3 ! from bsddb import db, dbtables ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbtables Index: test_env_close.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_env_close.py,v retrieving revision 1.4 retrieving revision 1.4.4.1 diff -C2 -d -r1.4 -r1.4.4.1 *** test_env_close.py 31 Dec 2002 18:21:43 -0000 1.4 --- test_env_close.py 28 Jan 2003 16:09:57 -0000 1.4.4.1 *************** *** 9,13 **** import unittest ! from bsddb import db from test_all import verbose --- 9,18 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db from test_all import verbose Index: test_get_none.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_get_none.py,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 *** test_get_none.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_get_none.py 28 Jan 2003 16:09:57 -0000 1.3.4.1 *************** *** 8,12 **** import unittest ! from bsddb import db from test_all import verbose --- 8,17 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db from test_all import verbose Index: test_lock.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_lock.py,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -C2 -d -r1.2 -r1.2.4.1 *** test_lock.py 30 Dec 2002 20:52:08 -0000 1.2 --- test_lock.py 28 Jan 2003 16:09:57 -0000 1.2.4.1 *************** *** 19,23 **** from test_all import verbose ! from bsddb import db --- 19,28 ---- from test_all import verbose ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db Index: test_misc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_misc.py,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -C2 -d -r1.2 -r1.2.4.1 *** test_misc.py 30 Dec 2002 20:52:08 -0000 1.2 --- test_misc.py 28 Jan 2003 16:09:57 -0000 1.2.4.1 *************** *** 6,11 **** import unittest ! from bsddb import db ! from bsddb import dbshelve from test.test_support import verbose --- 6,15 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db, dbshelve ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbshelve from test.test_support import verbose Index: test_queue.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_queue.py,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -C2 -d -r1.2 -r1.2.4.1 *** test_queue.py 30 Dec 2002 20:52:08 -0000 1.2 --- test_queue.py 28 Jan 2003 16:09:57 -0000 1.2.4.1 *************** *** 8,12 **** import unittest ! from bsddb import db from test_all import verbose --- 8,17 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db from test_all import verbose Index: test_recno.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_recno.py,v retrieving revision 1.5 retrieving revision 1.5.2.1 diff -C2 -d -r1.5 -r1.5.2.1 *** test_recno.py 10 Jan 2003 19:28:15 -0000 1.5 --- test_recno.py 28 Jan 2003 16:09:57 -0000 1.5.2.1 *************** *** 9,14 **** import unittest - from bsddb import db from test_all import verbose letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' --- 9,20 ---- import unittest from test_all import verbose + + try: + # For Python 2.3 + from bsddb import db + except ImportError: + # For earlier Pythons w/distutils pybsddb + from bsddb3 import db letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' Index: test_thread.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_thread.py,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -C2 -d -r1.4 -r1.4.2.1 *** test_thread.py 10 Jan 2003 19:03:29 -0000 1.4 --- test_thread.py 28 Jan 2003 16:09:57 -0000 1.4.2.1 *************** *** 27,31 **** import unittest from test_all import verbose ! from bsddb import db, dbutils #---------------------------------------------------------------------- --- 27,38 ---- import unittest from test_all import verbose ! ! try: ! # For Python 2.3 ! from bsddb import db, dbutils ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbutils ! #---------------------------------------------------------------------- From tim_one@users.sourceforge.net Tue Jan 28 16:23:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 08:23:36 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.108,1.109 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv18771/Lib Modified Files: pickle.py Log Message: Got rid of the _quotes global. Used only once, and is trivial. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.108 retrieving revision 1.109 diff -C2 -d -r1.108 -r1.109 *** pickle.py 28 Jan 2003 15:19:53 -0000 1.108 --- pickle.py 28 Jan 2003 16:23:33 -0000 1.109 *************** *** 157,162 **** del x - _quotes = ["'", '"'] - # Pickling machinery --- 157,160 ---- *************** *** 827,831 **** def load_string(self): rep = self.readline()[:-1] ! for q in _quotes: if rep.startswith(q): if not rep.endswith(q): --- 825,829 ---- def load_string(self): rep = self.readline()[:-1] ! for q in "\"'": # double or single quote if rep.startswith(q): if not rep.endswith(q): From gvanrossum@users.sourceforge.net Tue Jan 28 16:34:25 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 08:34:25 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv24598 Modified Files: pickle.py Log Message: Made save() fit on a page, while adding comments. (I moved some type checks to save_reduce(), which can also be called from a subclass.) Also tweaked some more comments. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.109 retrieving revision 1.110 diff -C2 -d -r1.109 -r1.110 *** pickle.py 28 Jan 2003 16:23:33 -0000 1.109 --- pickle.py 28 Jan 2003 16:34:19 -0000 1.110 *************** *** 33,36 **** --- 33,37 ---- import struct import re + import warnings __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", *************** *** 40,44 **** format_version = "2.0" # File format version we write compatible_formats = ["1.0", # Original protocol 0 ! "1.1", # Protocol 0 with class supprt added "1.2", # Original protocol 1 "1.3", # Protocol 1 with BINFLOAT added --- 41,45 ---- format_version = "2.0" # File format version we write compatible_formats = ["1.0", # Original protocol 0 ! "1.1", # Protocol 0 with INST added "1.2", # Original protocol 1 "1.3", # Protocol 1 with BINFLOAT added *************** *** 250,277 **** def save(self, obj): pid = self.persistent_id(obj) ! if pid is not None: self.save_pers(pid) return ! memo = self.memo ! d = id(obj) ! if d in memo: ! self.write(self.get(memo[d][0])) return t = type(obj) ! try: ! f = self.dispatch[t] ! except KeyError: ! pass ! else: ! f(self, obj) return ! # The dispatch table doesn't know about type t. try: issc = issubclass(t, TypeType) ! except TypeError: # t is not a class issc = 0 if issc: --- 251,277 ---- def save(self, obj): + # Check for persistent id (defined by a subclass) pid = self.persistent_id(obj) ! if pid: self.save_pers(pid) return ! # Check the memo ! x = self.memo.get(id(obj)) ! if x: ! self.write(self.get(x[0])) return + # Check the type dispatch table t = type(obj) ! f = self.dispatch.get(t) ! if f: ! f(self, obj) # Call unbound method with explicit self return ! # Check for a class with a custom metaclass; treat as regular class try: issc = issubclass(t, TypeType) ! except TypeError: # t is not a class (old Boost; see SF #502085) issc = 0 if issc: *************** *** 279,329 **** return ! try: ! reduce = dispatch_table[t] ! except KeyError: ! try: ! reduce = obj.__reduce__ ! except AttributeError: ! raise PicklingError, \ ! "can't pickle %s object: %s" % (`t.__name__`, ! `obj`) ! else: ! tup = reduce() else: ! tup = reduce(obj) ! if type(tup) is StringType: ! self.save_global(obj, tup) return ! if type(tup) is not TupleType: ! raise PicklingError, "Value returned by %s must be a " \ ! "tuple" % reduce ! ! l = len(tup) ! ! if (l != 2) and (l != 3): ! raise PicklingError, "tuple returned by %s must contain " \ ! "only two or three elements" % reduce ! ! callable = tup[0] ! arg_tup = tup[1] ! if l > 2: ! state = tup[2] ! else: state = None ! if type(arg_tup) is not TupleType and arg_tup is not None: ! raise PicklingError, "Second element of tuple returned " \ ! "by %s must be a tuple" % reduce ! ! self.save_reduce(callable, arg_tup, state) self.memoize(obj) def persistent_id(self, obj): return None def save_pers(self, pid): if self.bin: self.save(pid) --- 279,324 ---- return ! # Check copy_reg.dispatch_table ! reduce = dispatch_table.get(t) ! if reduce: ! rv = reduce(obj) else: ! # Check for __reduce__ method ! reduce = getattr(obj, "__reduce__", None) ! if not reduce: ! raise PicklingError("Can't pickle %r object: %r" % ! (t.__name__, obj)) ! rv = reduce() ! # Check for string returned by reduce(), meaning "save as global" ! if type(rv) is StringType: ! self.save_global(obj, rv) return ! # Assert that reduce() returned a tuple ! if type(rv) is not TupleType: ! raise PicklingError("%s must return string or tuple" % reduce) ! # Assert that it returned a 2-tuple or 3-tuple, and unpack it ! l = len(rv) ! if l == 2: ! func, args = rv state = None + elif l == 3: + func, args, state = rv + else: + raise PicklingError("Tuple returned by %s must have " + "exactly two or three elements" % reduce) ! # Save the reduce() output and finally memoize the object ! self.save_reduce(func, args, state) self.memoize(obj) def persistent_id(self, obj): + # This exists so a subclass can override it return None def save_pers(self, pid): + # Save a persistent id reference if self.bin: self.save(pid) *************** *** 332,345 **** self.write(PERSID + str(pid) + '\n') ! def save_reduce(self, acallable, arg_tup, state = None): ! write = self.write ! save = self.save ! if not callable(acallable): ! raise PicklingError("__reduce__() must return callable as " ! "first argument, not %s" % `acallable`) ! save(acallable) ! save(arg_tup) write(REDUCE) --- 327,353 ---- self.write(PERSID + str(pid) + '\n') ! def save_reduce(self, func, args, state=None): ! # This API is be called by some subclasses ! # Assert that args is a tuple or None ! if not isinstance(args, TupleType): ! if args is None: ! # A hack for Jim Fulton's ExtensionClass, now deprecated. ! # See load_reduce() ! warnings.warn("__basicnew__ special case is deprecated", ! DeprecationWarning) ! else: ! raise PicklingError( ! "args from reduce() should be a tuple") ! # Assert that func is callable ! if not callable(func): ! raise PicklingError("func from reduce should be callable") ! ! save = self.save ! write = self.write ! ! save(func) ! save(args) write(REDUCE) *************** *** 348,351 **** --- 356,361 ---- write(BUILD) + # Methods below this point are dispatched through the dispatch table + dispatch = {} *************** *** 1029,1035 **** if arg_tup is None: ! import warnings ! warnings.warn("The None return argument form of __reduce__ is " ! "deprecated. Return a tuple of arguments instead.", DeprecationWarning) value = callable.__basicnew__() --- 1039,1044 ---- if arg_tup is None: ! # A hack for Jim Fulton's ExtensionClass, now deprecated ! warnings.warn("__basicnew__ special case is deprecated", DeprecationWarning) value = callable.__basicnew__() From tim_one@users.sourceforge.net Tue Jan 28 16:42:26 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 08:42:26 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.110,1.111 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28786/Lib Modified Files: pickle.py Log Message: _is_string_secure(): This method is no longer used; removed it. (It was used before string-escape codecs were added to the core.) Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** pickle.py 28 Jan 2003 16:34:19 -0000 1.110 --- pickle.py 28 Jan 2003 16:42:22 -0000 1.111 *************** *** 846,886 **** dispatch[STRING] = load_string - def _is_string_secure(self, s): - """Return true if s contains a string that is safe to eval - - The definition of secure string is based on the implementation - in cPickle. s is secure as long as it only contains a quoted - string and optional trailing whitespace. - """ - q = s[0] - if q not in ("'", '"'): - return 0 - # find the closing quote - offset = 1 - i = None - while 1: - try: - i = s.index(q, offset) - except ValueError: - # if there is an error the first time, there is no - # close quote - if offset == 1: - return 0 - if s[i-1] != '\\': - break - # check to see if this one is escaped - nslash = 0 - j = i - 1 - while j >= offset and s[j] == '\\': - j = j - 1 - nslash = nslash + 1 - if nslash % 2 == 0: - break - offset = i + 1 - for c in s[i+1:]: - if ord(c) > 32: - return 0 - return 1 - def load_binstring(self): len = mloads('i' + self.read(4)) --- 846,849 ---- From tim_one@users.sourceforge.net Tue Jan 28 16:48:02 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 08:48:02 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.111,1.112 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv31939/Lib Modified Files: pickle.py Log Message: save_dict(): Added a comment about the control flow NealN missed. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.111 retrieving revision 1.112 diff -C2 -d -r1.111 -r1.112 *** pickle.py 28 Jan 2003 16:42:22 -0000 1.111 --- pickle.py 28 Jan 2003 16:47:59 -0000 1.112 *************** *** 562,566 **** write(SETITEMS) return ! else: # proto 0 -- can't use EMPTY_DICT or SETITEMS write(MARK + DICT) --- 562,567 ---- write(SETITEMS) return ! # else (dict is empty or a singleton), fall through to the ! # SETITEM code at the end else: # proto 0 -- can't use EMPTY_DICT or SETITEMS write(MARK + DICT) From tim_one@users.sourceforge.net Tue Jan 28 16:58:43 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 08:58:43 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.112,1.113 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5453/Lib Modified Files: pickle.py Log Message: save_empty_tuple(): Comment on why we can't get rid of this. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.112 retrieving revision 1.113 diff -C2 -d -r1.112 -r1.113 *** pickle.py 28 Jan 2003 16:47:59 -0000 1.112 --- pickle.py 28 Jan 2003 16:58:41 -0000 1.113 *************** *** 516,519 **** --- 516,522 ---- dispatch[TupleType] = save_tuple + # save_empty_tuple() isn't used by anything in Python 2.3. However, I + # found a Pickler subclass in Zope3 that calls it, so it's not harmless + # to remove it. def save_empty_tuple(self, obj): self.write(EMPTY_TUPLE) From bwarsaw@users.sourceforge.net Tue Jan 28 17:20:45 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 28 Jan 2003 09:20:45 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb __init__.py,1.3,1.4 dbshelve.py,1.4,1.5 dbtables.py,1.6,1.7 dbutils.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb In directory sc8-pr-cvs1:/tmp/cvs-serv17192 Modified Files: __init__.py dbshelve.py dbtables.py dbutils.py Log Message: Everything worked in both the distutils distro and in Python 2.3cvs, so merge from the bsddb-bsddb3-schizo-branch back to the trunk. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/__init__.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** __init__.py 30 Dec 2002 20:52:07 -0000 1.3 --- __init__.py 28 Jan 2003 17:20:41 -0000 1.4 *************** *** 45,53 **** raise ! # bsddb3 calls it _db ! _db = _bsddb ! __version__ = _db.__version__ ! error = _db.DBError # So bsddb.error will mean something... #---------------------------------------------------------------------- --- 45,53 ---- raise ! # bsddb3 calls it db, but provide _db for backwards compatibility ! db = _db = _bsddb ! __version__ = db.__version__ ! error = db.DBError # So bsddb.error will mean something... #---------------------------------------------------------------------- *************** *** 153,157 **** flags = _checkflag(flag) ! d = _db.DB() d.set_flags(hflags) if cachesize is not None: d.set_cachesize(0, cachesize) --- 153,157 ---- flags = _checkflag(flag) ! d = db.DB() d.set_flags(hflags) if cachesize is not None: d.set_cachesize(0, cachesize) *************** *** 160,164 **** if ffactor is not None: d.set_h_ffactor(ffactor) if nelem is not None: d.set_h_nelem(nelem) ! d.open(file, _db.DB_HASH, flags, mode) return _DBWithCursor(d) --- 160,164 ---- if ffactor is not None: d.set_h_ffactor(ffactor) if nelem is not None: d.set_h_nelem(nelem) ! d.open(file, db.DB_HASH, flags, mode) return _DBWithCursor(d) *************** *** 170,174 **** flags = _checkflag(flag) ! d = _db.DB() if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) --- 170,174 ---- flags = _checkflag(flag) ! d = db.DB() if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) *************** *** 177,181 **** if minkeypage is not None: d.set_bt_minkey(minkeypage) if maxkeypage is not None: d.set_bt_maxkey(maxkeypage) ! d.open(file, _db.DB_BTREE, flags, mode) return _DBWithCursor(d) --- 177,181 ---- if minkeypage is not None: d.set_bt_minkey(minkeypage) if maxkeypage is not None: d.set_bt_maxkey(maxkeypage) ! d.open(file, db.DB_BTREE, flags, mode) return _DBWithCursor(d) *************** *** 188,192 **** flags = _checkflag(flag) ! d = _db.DB() if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) --- 188,192 ---- flags = _checkflag(flag) ! d = db.DB() if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) *************** *** 197,201 **** if source is not None: d.set_re_source(source) if pad is not None: d.set_re_pad(pad) ! d.open(file, _db.DB_RECNO, flags, mode) return _DBWithCursor(d) --- 197,201 ---- if source is not None: d.set_re_source(source) if pad is not None: d.set_re_pad(pad) ! d.open(file, db.DB_RECNO, flags, mode) return _DBWithCursor(d) *************** *** 205,220 **** def _checkflag(flag): if flag == 'r': ! flags = _db.DB_RDONLY elif flag == 'rw': flags = 0 elif flag == 'w': ! flags = _db.DB_CREATE elif flag == 'c': ! flags = _db.DB_CREATE elif flag == 'n': ! flags = _db.DB_CREATE | _db.DB_TRUNCATE else: raise error, "flags should be one of 'r', 'w', 'c' or 'n'" ! return flags | _db.DB_THREAD #---------------------------------------------------------------------- --- 205,220 ---- def _checkflag(flag): if flag == 'r': ! flags = db.DB_RDONLY elif flag == 'rw': flags = 0 elif flag == 'w': ! flags = db.DB_CREATE elif flag == 'c': ! flags = db.DB_CREATE elif flag == 'n': ! flags = db.DB_CREATE | db.DB_TRUNCATE else: raise error, "flags should be one of 'r', 'w', 'c' or 'n'" ! return flags | db.DB_THREAD #---------------------------------------------------------------------- *************** *** 232,236 **** del thread except ImportError: ! _db.DB_THREAD = 0 --- 232,236 ---- del thread except ImportError: ! db.DB_THREAD = 0 Index: dbshelve.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/dbshelve.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** dbshelve.py 30 Dec 2002 20:52:07 -0000 1.4 --- dbshelve.py 28 Jan 2003 17:20:42 -0000 1.5 *************** *** 31,35 **** import cPickle ! from bsddb import db #------------------------------------------------------------------------ --- 31,40 ---- import cPickle ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db #------------------------------------------------------------------------ Index: dbtables.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/dbtables.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** dbtables.py 30 Dec 2002 20:52:07 -0000 1.6 --- dbtables.py 28 Jan 2003 17:20:42 -0000 1.7 *************** *** 18,38 **** _cvsid = '$Id$' - import string - import sys - try: - import cPickle - pickle = cPickle - except ImportError: - import pickle - import whrandom - import xdrlib import re import copy ! from bsddb.db import * ! class TableDBError(StandardError): pass ! class TableAlreadyExists(TableDBError): pass --- 18,41 ---- _cvsid = '$Id$' import re + import sys import copy + import xdrlib + import whrandom + from types import ListType, StringType + import cPickle as pickle ! try: ! # For Python 2.3 ! from bsddb.db import * ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3.db import * ! class TableDBError(StandardError): ! pass ! class TableAlreadyExists(TableDBError): ! pass *************** *** 73,79 **** chars_to_escape = '.*+()[]?' for char in chars_to_escape : ! likestr = string.replace(likestr, char, '\\'+char) # convert %s to wildcards ! self.likestr = string.replace(likestr, '%', '.*') self.re = re.compile('^'+self.likestr+'$', re_flags) def __call__(self, s): --- 76,82 ---- chars_to_escape = '.*+()[]?' for char in chars_to_escape : ! likestr = likestr.replace(char, '\\'+char) # convert %s to wildcards ! self.likestr = likestr.replace('%', '.*') self.re = re.compile('^'+self.likestr+'$', re_flags) def __call__(self, s): *************** *** 85,89 **** _table_names_key = '__TABLE_NAMES__' # list of the tables in this db _columns = '._COLUMNS__' # table_name+this key contains a list of columns ! def _columns_key(table) : return table + _columns # --- 88,94 ---- _table_names_key = '__TABLE_NAMES__' # list of the tables in this db _columns = '._COLUMNS__' # table_name+this key contains a list of columns ! ! def _columns_key(table): ! return table + _columns # *************** *** 94,102 **** # row in the table. (no data is stored) _rowid_str_len = 8 # length in bytes of the unique rowid strings ! def _data_key(table, col, rowid) : return table + _data + col + _data + rowid ! def _search_col_data_key(table, col) : return table + _data + col + _data ! def _search_all_data_key(table) : return table + _data ! def _rowid_key(table, rowid) : return table + _rowid + rowid + _rowid ! def _search_rowid_key(table) : return table + _rowid def contains_metastrings(s) : --- 99,117 ---- # row in the table. (no data is stored) _rowid_str_len = 8 # length in bytes of the unique rowid strings ! ! def _data_key(table, col, rowid): ! return table + _data + col + _data + rowid ! ! def _search_col_data_key(table, col): ! return table + _data + col + _data ! ! def _search_all_data_key(table): ! return table + _data ! ! def _rowid_key(table, rowid): ! return table + _rowid + rowid + _rowid ! ! def _search_rowid_key(table): ! return table + _rowid def contains_metastrings(s) : *************** *** 104,113 **** metadata strings that might interfere with dbtables database operation. """ ! if string.find(s, _table_names_key) >= 0 or \ ! string.find(s, _columns) >= 0 or \ ! string.find(s, _data) >= 0 or \ ! string.find(s, _rowid) >= 0 : return 1 ! else : return 0 --- 119,129 ---- metadata strings that might interfere with dbtables database operation. """ ! if (s.find(_table_names_key) >= 0 or ! s.find(_columns) >= 0 or ! s.find(_data) >= 0 or ! s.find(_rowid) >= 0): ! # Then return 1 ! else: return 0 *************** *** 115,119 **** class bsdTableDB : def __init__(self, filename, dbhome, create=0, truncate=0, mode=0600, ! recover=0, dbflags=0) : """bsdTableDB.open(filename, dbhome, create=0, truncate=0, mode=0600) Open database name in the dbhome BerkeleyDB directory. --- 131,135 ---- class bsdTableDB : def __init__(self, filename, dbhome, create=0, truncate=0, mode=0600, ! recover=0, dbflags=0): """bsdTableDB.open(filename, dbhome, create=0, truncate=0, mode=0600) Open database name in the dbhome BerkeleyDB directory. *************** *** 187,191 **** try: key, data = cur.first() ! while 1 : print `{key: data}` next = cur.next() --- 203,207 ---- try: key, data = cur.first() ! while 1: print `{key: data}` next = cur.next() *************** *** 203,207 **** raises TableDBError if it already exists or for other DB errors. """ ! assert type(columns) == type([]) txn = None try: --- 219,223 ---- raises TableDBError if it already exists or for other DB errors. """ ! assert isinstance(columns, ListType) txn = None try: *************** *** 234,240 **** txn.commit() txn = None - except DBError, dberror: ! if txn : txn.abort() raise TableDBError, dberror[1] --- 250,255 ---- txn.commit() txn = None except DBError, dberror: ! if txn: txn.abort() raise TableDBError, dberror[1] *************** *** 245,250 **** [] if the table doesn't exist. """ ! assert type(table) == type('') ! if contains_metastrings(table) : raise ValueError, "bad table name: contains reserved metastrings" --- 260,265 ---- [] if the table doesn't exist. """ ! assert isinstance(table, StringType) ! if contains_metastrings(table): raise ValueError, "bad table name: contains reserved metastrings" *************** *** 274,278 **** all of its current columns. """ ! assert type(columns) == type([]) try: self.CreateTable(table, columns) --- 289,293 ---- all of its current columns. """ ! assert isinstance(columns, ListType) try: self.CreateTable(table, columns) *************** *** 332,336 **** """Create a new unique row identifier""" unique = 0 ! while not unique : # Generate a random 64-bit row ID string # (note: this code has <64 bits of randomness --- 347,351 ---- """Create a new unique row identifier""" unique = 0 ! while not unique: # Generate a random 64-bit row ID string # (note: this code has <64 bits of randomness *************** *** 359,370 **** txn = None try: ! if not self.db.has_key(_columns_key(table)) : raise TableDBError, "unknown table" # check the validity of each column name ! if not self.__tablecolumns.has_key(table) : self.__load_column_info(table) for column in rowdict.keys() : ! if not self.__tablecolumns[table].count(column) : raise TableDBError, "unknown column: "+`column` --- 374,385 ---- txn = None try: ! if not self.db.has_key(_columns_key(table)): raise TableDBError, "unknown table" # check the validity of each column name ! if not self.__tablecolumns.has_key(table): self.__load_column_info(table) for column in rowdict.keys() : ! if not self.__tablecolumns[table].count(column): raise TableDBError, "unknown column: "+`column` *************** *** 374,378 **** # insert the row values into the table database ! for column, dataitem in rowdict.items() : # store the value self.db.put(_data_key(table, column, rowid), dataitem, txn=txn) --- 389,393 ---- # insert the row values into the table database ! for column, dataitem in rowdict.items(): # store the value self.db.put(_data_key(table, column, rowid), dataitem, txn=txn) *************** *** 393,397 **** ! def Modify(self, table, conditions={}, mappings={}) : """Modify(table, conditions) - Modify in rows matching 'conditions' using mapping functions in 'mappings' --- 408,412 ---- ! def Modify(self, table, conditions={}, mappings={}): """Modify(table, conditions) - Modify in rows matching 'conditions' using mapping functions in 'mappings' *************** *** 408,415 **** # modify only requested columns columns = mappings.keys() ! for rowid in matching_rowids.keys() : txn = None try: ! for column in columns : txn = self.env.txn_begin() # modify the requested column --- 423,430 ---- # modify only requested columns columns = mappings.keys() ! for rowid in matching_rowids.keys(): txn = None try: ! for column in columns: txn = self.env.txn_begin() # modify the requested column *************** *** 434,438 **** except DBError, dberror: ! if txn : txn.abort() raise --- 449,453 ---- except DBError, dberror: ! if txn: txn.abort() raise *************** *** 441,445 **** raise TableDBError, dberror[1] ! def Delete(self, table, conditions={}) : """Delete(table, conditions) - Delete items matching the given conditions from the table. --- 456,460 ---- raise TableDBError, dberror[1] ! def Delete(self, table, conditions={}): """Delete(table, conditions) - Delete items matching the given conditions from the table. *************** *** 453,461 **** # delete row data from all columns columns = self.__tablecolumns[table] ! for rowid in matching_rowids.keys() : txn = None try: txn = self.env.txn_begin() ! for column in columns : # delete the data key try: --- 468,476 ---- # delete row data from all columns columns = self.__tablecolumns[table] ! for rowid in matching_rowids.keys(): txn = None try: txn = self.env.txn_begin() ! for column in columns: # delete the data key try: *************** *** 474,486 **** txn = None except DBError, dberror: ! if txn : txn.abort() raise - except DBError, dberror: raise TableDBError, dberror[1] ! def Select(self, table, columns, conditions={}) : """Select(table, conditions) - retrieve specific row data Returns a list of row column->value mapping dictionaries. --- 489,500 ---- txn = None except DBError, dberror: ! if txn: txn.abort() raise except DBError, dberror: raise TableDBError, dberror[1] ! def Select(self, table, columns, conditions={}): """Select(table, conditions) - retrieve specific row data Returns a list of row column->value mapping dictionaries. *************** *** 492,508 **** """ try: ! if not self.__tablecolumns.has_key(table) : self.__load_column_info(table) ! if columns is None : columns = self.__tablecolumns[table] matching_rowids = self.__Select(table, columns, conditions) except DBError, dberror: raise TableDBError, dberror[1] - # return the matches as a list of dictionaries return matching_rowids.values() ! def __Select(self, table, columns, conditions) : """__Select() - Used to implement Select and Delete (above) Returns a dictionary keyed on rowids containing dicts --- 506,521 ---- """ try: ! if not self.__tablecolumns.has_key(table): self.__load_column_info(table) ! if columns is None: columns = self.__tablecolumns[table] matching_rowids = self.__Select(table, columns, conditions) except DBError, dberror: raise TableDBError, dberror[1] # return the matches as a list of dictionaries return matching_rowids.values() ! def __Select(self, table, columns, conditions): """__Select() - Used to implement Select and Delete (above) Returns a dictionary keyed on rowids containing dicts *************** *** 514,523 **** """ # check the validity of each column name ! if not self.__tablecolumns.has_key(table) : self.__load_column_info(table) ! if columns is None : columns = self.tablecolumns[table] ! for column in (columns + conditions.keys()) : ! if not self.__tablecolumns[table].count(column) : raise TableDBError, "unknown column: "+`column` --- 527,536 ---- """ # check the validity of each column name ! if not self.__tablecolumns.has_key(table): self.__load_column_info(table) ! if columns is None: columns = self.tablecolumns[table] ! for column in (columns + conditions.keys()): ! if not self.__tablecolumns[table].count(column): raise TableDBError, "unknown column: "+`column` *************** *** 525,530 **** # column names containing the data for that row and column. matching_rowids = {} ! ! rejected_rowids = {} # keys are rowids that do not match # attempt to sort the conditions in such a way as to minimize full --- 538,543 ---- # column names containing the data for that row and column. matching_rowids = {} ! # keys are rowids that do not match ! rejected_rowids = {} # attempt to sort the conditions in such a way as to minimize full *************** *** 533,537 **** a = atuple[1] b = btuple[1] ! if type(a) == type(b) : if isinstance(a, PrefixCond) and isinstance(b, PrefixCond): # longest prefix first --- 546,550 ---- a = atuple[1] b = btuple[1] ! if type(a) is type(b): if isinstance(a, PrefixCond) and isinstance(b, PrefixCond): # longest prefix first *************** *** 558,586 **** cur = self.db.cursor() column_num = -1 ! for column, condition in conditionlist : column_num = column_num + 1 searchkey = _search_col_data_key(table, column) # speedup: don't linear search columns within loop ! if column in columns : savethiscolumndata = 1 # save the data for return ! else : savethiscolumndata = 0 # data only used for selection try: key, data = cur.set_range(searchkey) ! while key[:len(searchkey)] == searchkey : # extract the rowid from the key rowid = key[-_rowid_str_len:] ! if not rejected_rowids.has_key(rowid) : # if no condition was specified or the condition # succeeds, add row to our match list. ! if not condition or condition(data) : ! if not matching_rowids.has_key(rowid) : matching_rowids[rowid] = {} ! if savethiscolumndata : matching_rowids[rowid][column] = data ! else : ! if matching_rowids.has_key(rowid) : del matching_rowids[rowid] rejected_rowids[rowid] = rowid --- 571,599 ---- cur = self.db.cursor() column_num = -1 ! for column, condition in conditionlist: column_num = column_num + 1 searchkey = _search_col_data_key(table, column) # speedup: don't linear search columns within loop ! if column in columns: savethiscolumndata = 1 # save the data for return ! else: savethiscolumndata = 0 # data only used for selection try: key, data = cur.set_range(searchkey) ! while key[:len(searchkey)] == searchkey: # extract the rowid from the key rowid = key[-_rowid_str_len:] ! if not rejected_rowids.has_key(rowid): # if no condition was specified or the condition # succeeds, add row to our match list. ! if not condition or condition(data): ! if not matching_rowids.has_key(rowid): matching_rowids[rowid] = {} ! if savethiscolumndata: matching_rowids[rowid][column] = data ! else: ! if matching_rowids.has_key(rowid): del matching_rowids[rowid] rejected_rowids[rowid] = rowid *************** *** 589,593 **** except DBError, dberror: ! if dberror[0] != DB_NOTFOUND : raise continue --- 602,606 ---- except DBError, dberror: ! if dberror[0] != DB_NOTFOUND: raise continue *************** *** 600,607 **** # extract any remaining desired column data from the # database for the matching rows. ! if len(columns) > 0 : ! for rowid, rowdata in matching_rowids.items() : ! for column in columns : ! if rowdata.has_key(column) : continue try: --- 613,620 ---- # extract any remaining desired column data from the # database for the matching rows. ! if len(columns) > 0: ! for rowid, rowdata in matching_rowids.items(): ! for column in columns: ! if rowdata.has_key(column): continue try: *************** *** 609,613 **** _data_key(table, column, rowid)) except DBError, dberror: ! if dberror[0] != DB_NOTFOUND : raise rowdata[column] = None --- 622,626 ---- _data_key(table, column, rowid)) except DBError, dberror: ! if dberror[0] != DB_NOTFOUND: raise rowdata[column] = None *************** *** 617,623 **** ! def Drop(self, table) : ! """Remove an entire table from the database ! """ txn = None try: --- 630,635 ---- ! def Drop(self, table): ! """Remove an entire table from the database""" txn = None try: *************** *** 631,635 **** # delete all keys containing this tables column and row info table_key = _search_all_data_key(table) ! while 1 : try: key, data = cur.set_range(table_key) --- 643,647 ---- # delete all keys containing this tables column and row info table_key = _search_all_data_key(table) ! while 1: try: key, data = cur.set_range(table_key) *************** *** 637,641 **** break # only delete items in this table ! if key[:len(table_key)] != table_key : break cur.delete() --- 649,653 ---- break # only delete items in this table ! if key[:len(table_key)] != table_key: break cur.delete() *************** *** 643,647 **** # delete all rowids used by this table table_key = _search_rowid_key(table) ! while 1 : try: key, data = cur.set_range(table_key) --- 655,659 ---- # delete all rowids used by this table table_key = _search_rowid_key(table) ! while 1: try: key, data = cur.set_range(table_key) *************** *** 649,653 **** break # only delete items in this table ! if key[:len(table_key)] != table_key : break cur.delete() --- 661,665 ---- break # only delete items in this table ! if key[:len(table_key)] != table_key: break cur.delete() *************** *** 670,678 **** txn = None ! if self.__tablecolumns.has_key(table) : del self.__tablecolumns[table] except DBError, dberror: ! if txn : txn.abort() raise TableDBError, dberror[1] --- 682,690 ---- txn = None ! if self.__tablecolumns.has_key(table): del self.__tablecolumns[table] except DBError, dberror: ! if txn: txn.abort() raise TableDBError, dberror[1] Index: dbutils.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/dbutils.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** dbutils.py 30 Dec 2002 20:52:08 -0000 1.5 --- dbutils.py 28 Jan 2003 17:20:42 -0000 1.6 *************** *** 27,31 **** from time import sleep as _sleep ! from bsddb import _db # always sleep at least N seconds between retrys --- 27,36 ---- from time import sleep as _sleep ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db # always sleep at least N seconds between retrys *************** *** 61,65 **** try: return function(*_args, **_kwargs) ! except _db.DBLockDeadlockError: if _deadlock_VerboseFile: _deadlock_VerboseFile.write( --- 66,70 ---- try: return function(*_args, **_kwargs) ! except db.DBLockDeadlockError: if _deadlock_VerboseFile: _deadlock_VerboseFile.write( From bwarsaw@users.sourceforge.net Tue Jan 28 17:20:54 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 28 Jan 2003 09:20:54 -0800 Subject: [Python-checkins] python/dist/src/Lib/bsddb/test test_all.py,1.1,1.2 test_associate.py,1.3,1.4 test_basics.py,1.5,1.6 test_compat.py,1.3,1.4 test_dbobj.py,1.3,1.4 test_dbshelve.py,1.4,1.5 test_dbtables.py,1.4,1.5 test_env_close.py,1.4,1.5 test_get_none.py,1.3,1.4 test_lock.py,1.2,1.3 test_misc.py,1.2,1.3 test_queue.py,1.2,1.3 test_recno.py,1.5,1.6 test_thread.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/bsddb/test In directory sc8-pr-cvs1:/tmp/cvs-serv17192/test Modified Files: test_all.py test_associate.py test_basics.py test_compat.py test_dbobj.py test_dbshelve.py test_dbtables.py test_env_close.py test_get_none.py test_lock.py test_misc.py test_queue.py test_recno.py test_thread.py Log Message: Everything worked in both the distutils distro and in Python 2.3cvs, so merge from the bsddb-bsddb3-schizo-branch back to the trunk. Index: test_all.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_all.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_all.py 30 Dec 2002 20:52:08 -0000 1.1 --- test_all.py 28 Jan 2003 17:20:42 -0000 1.2 *************** *** 17,21 **** def print_versions(): ! from bsddb import db print print '-=' * 38 --- 17,26 ---- def print_versions(): ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db print print '-=' * 38 Index: test_associate.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_associate.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_associate.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_associate.py 28 Jan 2003 17:20:43 -0000 1.4 *************** *** 17,21 **** from test_all import verbose ! from bsddb import db, dbshelve --- 17,26 ---- from test_all import verbose ! try: ! # For Python 2.3 ! from bsddb import db, dbshelve ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbshelve Index: test_basics.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_basics.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_basics.py 17 Jan 2003 08:42:50 -0000 1.5 --- test_basics.py 28 Jan 2003 17:20:43 -0000 1.6 *************** *** 13,17 **** import unittest ! from bsddb import db from test_all import verbose --- 13,22 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db from test_all import verbose Index: test_compat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_compat.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_compat.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_compat.py 28 Jan 2003 17:20:43 -0000 1.4 *************** *** 5,9 **** import sys, os, string - from bsddb import hashopen, btopen, rnopen import bsddb import unittest --- 5,8 ---- *************** *** 12,15 **** --- 11,20 ---- from test_all import verbose + try: + # For Python 2.3 + from bsddb import db, hashopen, btopen, rnopen + except ImportError: + # For earlier Pythons w/distutils pybsddb + from bsddb3 import db, hashopen, btopen, rnopen *************** *** 127,131 **** else: if verbose: print "truth test: false" ! except bsddb.error: pass else: --- 132,136 ---- else: if verbose: print "truth test: false" ! except db.DBError: pass else: Index: test_dbobj.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_dbobj.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_dbobj.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_dbobj.py 28 Jan 2003 17:20:44 -0000 1.4 *************** *** 4,8 **** import glob ! from bsddb import db, dbobj --- 4,13 ---- import glob ! try: ! # For Python 2.3 ! from bsddb import db, dbobj ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbobj Index: test_dbshelve.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_dbshelve.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_dbshelve.py 30 Dec 2002 20:52:08 -0000 1.4 --- test_dbshelve.py 28 Jan 2003 17:20:44 -0000 1.5 *************** *** 9,13 **** import unittest ! from bsddb import dbshelve, db from test_all import verbose --- 9,18 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db, dbshelve ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbshelve from test_all import verbose Index: test_dbtables.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_dbtables.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_dbtables.py 30 Dec 2002 20:52:08 -0000 1.4 --- test_dbtables.py 28 Jan 2003 17:20:44 -0000 1.5 *************** *** 31,35 **** from test_all import verbose ! from bsddb import db, dbtables --- 31,40 ---- from test_all import verbose ! try: ! # For Python 2.3 ! from bsddb import db, dbtables ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbtables Index: test_env_close.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_env_close.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_env_close.py 31 Dec 2002 18:21:43 -0000 1.4 --- test_env_close.py 28 Jan 2003 17:20:44 -0000 1.5 *************** *** 9,13 **** import unittest ! from bsddb import db from test_all import verbose --- 9,18 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db from test_all import verbose Index: test_get_none.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_get_none.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_get_none.py 30 Dec 2002 20:52:08 -0000 1.3 --- test_get_none.py 28 Jan 2003 17:20:44 -0000 1.4 *************** *** 8,12 **** import unittest ! from bsddb import db from test_all import verbose --- 8,17 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db from test_all import verbose Index: test_lock.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_lock.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_lock.py 30 Dec 2002 20:52:08 -0000 1.2 --- test_lock.py 28 Jan 2003 17:20:44 -0000 1.3 *************** *** 19,23 **** from test_all import verbose ! from bsddb import db --- 19,28 ---- from test_all import verbose ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db Index: test_misc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_misc.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_misc.py 30 Dec 2002 20:52:08 -0000 1.2 --- test_misc.py 28 Jan 2003 17:20:44 -0000 1.3 *************** *** 6,11 **** import unittest ! from bsddb import db ! from bsddb import dbshelve from test.test_support import verbose --- 6,15 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db, dbshelve ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbshelve from test.test_support import verbose Index: test_queue.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_queue.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_queue.py 30 Dec 2002 20:52:08 -0000 1.2 --- test_queue.py 28 Jan 2003 17:20:44 -0000 1.3 *************** *** 8,12 **** import unittest ! from bsddb import db from test_all import verbose --- 8,17 ---- import unittest ! try: ! # For Python 2.3 ! from bsddb import db ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db from test_all import verbose Index: test_recno.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_recno.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_recno.py 10 Jan 2003 19:28:15 -0000 1.5 --- test_recno.py 28 Jan 2003 17:20:44 -0000 1.6 *************** *** 9,14 **** import unittest - from bsddb import db from test_all import verbose letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' --- 9,20 ---- import unittest from test_all import verbose + + try: + # For Python 2.3 + from bsddb import db + except ImportError: + # For earlier Pythons w/distutils pybsddb + from bsddb3 import db letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' Index: test_thread.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bsddb/test/test_thread.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_thread.py 10 Jan 2003 19:03:29 -0000 1.4 --- test_thread.py 28 Jan 2003 17:20:44 -0000 1.5 *************** *** 27,31 **** import unittest from test_all import verbose ! from bsddb import db, dbutils #---------------------------------------------------------------------- --- 27,38 ---- import unittest from test_all import verbose ! ! try: ! # For Python 2.3 ! from bsddb import db, dbutils ! except ImportError: ! # For earlier Pythons w/distutils pybsddb ! from bsddb3 import db, dbutils ! #---------------------------------------------------------------------- From bwarsaw@users.sourceforge.net Tue Jan 28 17:30:50 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 28 Jan 2003 09:30:50 -0800 Subject: [Python-checkins] python/dist/src/Modules _bsddb.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv22518 Modified Files: _bsddb.c Log Message: Bump the version number Index: _bsddb.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** _bsddb.c 17 Jan 2003 08:42:50 -0000 1.6 --- _bsddb.c 28 Jan 2003 17:30:46 -0000 1.7 *************** *** 86,90 **** #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) ! #define PY_BSDDB_VERSION "4.1.2" static char *rcs_id = "$Id$"; --- 86,90 ---- #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) ! #define PY_BSDDB_VERSION "4.1.3" static char *rcs_id = "$Id$"; From gvanrossum@users.sourceforge.net Tue Jan 28 17:48:24 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 09:48:24 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_compile.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv30703 Modified Files: test_compile.py Log Message: Verify treatment of unary minus on negative numbers SF bug #660455. Index: test_compile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_compile.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_compile.py 23 Jul 2002 19:03:46 -0000 1.12 --- test_compile.py 28 Jan 2003 17:48:21 -0000 1.13 *************** *** 133,134 **** --- 133,141 ---- expect_same("000000000000008.", 8.) expect_same("000000000000009.", 9.) + + # Verify treatment of unary minus on negative numbers SF bug #660455 + import warnings + warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning) + # XXX Of course the following test will have to be changed in Python 2.4 + expect_same("0xffffffff", -1) + expect_same("-0xffffffff", 1) From gvanrossum@users.sourceforge.net Tue Jan 28 17:55:09 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 09:55:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv2961/test Modified Files: pickletester.py Log Message: Some experimental support for generating NEWOBJ with proto=2, and fixed a bug in load_newobj(). Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** pickletester.py 28 Jan 2003 04:25:27 -0000 1.24 --- pickletester.py 28 Jan 2003 17:55:05 -0000 1.25 *************** *** 301,304 **** --- 301,343 ---- self.assert_(x is y, (proto, x, s, y)) + def test_newobj_tuple(self): + x = MyTuple([1, 2, 3], foo=42, bar="hello") + s = self.dumps(x, 2) + y = self.loads(s) + self.assertEqual(tuple(x), tuple(y)) + self.assertEqual(x.__dict__, y.__dict__) + + def test_newobj_list(self): + x = MyList([1, 2, 3], foo=42, bar="hello") + s = self.dumps(x, 2) + y = self.loads(s) + self.assertEqual(list(x), list(y)) + self.assertEqual(x.__dict__, y.__dict__) + + class MyTuple(tuple): + def __new__(cls, *args, **kwds): + # Ignore **kwds + return tuple.__new__(cls, *args) + def __getnewargs__(self): + return (tuple(self),) + def __init__(self, *args, **kwds): + for k, v in kwds.items(): + setattr(self, k, v) + + class MyList(list): + def __new__(cls, *args, **kwds): + # Ignore **kwds + return list.__new__(cls, *args) + def __init__(self, *args, **kwds): + for k, v in kwds.items(): + setattr(self, k, v) + def __getstate__(self): + return list(self), self.__dict__ + def __setstate__(self, arg): + lst, dct = arg + for x in lst: + self.append(x) + self.__init__(**dct) + class AbstractPickleModuleTests(unittest.TestCase): From gvanrossum@users.sourceforge.net Tue Jan 28 17:55:09 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 09:55:09 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.113,1.114 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv2961 Modified Files: pickle.py Log Message: Some experimental support for generating NEWOBJ with proto=2, and fixed a bug in load_newobj(). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.113 retrieving revision 1.114 diff -C2 -d -r1.113 -r1.114 *** pickle.py 28 Jan 2003 16:58:41 -0000 1.113 --- pickle.py 28 Jan 2003 17:55:01 -0000 1.114 *************** *** 78,81 **** --- 78,82 ---- self.value = value + # Jython has PyStringMap; it's a dict subclass with string keys try: from org.python.core import PyStringMap *************** *** 83,86 **** --- 84,88 ---- PyStringMap = None + # UnicodeType may or may not be exported (normally imported from types) try: UnicodeType *************** *** 250,254 **** return GET + `i` + '\n' ! def save(self, obj): # Check for persistent id (defined by a subclass) pid = self.persistent_id(obj) --- 252,259 ---- return GET + `i` + '\n' ! def save(self, obj, ! _builtin_type = (int, long, float, complex, str, unicode, ! tuple, list, dict), ! ): # Check for persistent id (defined by a subclass) pid = self.persistent_id(obj) *************** *** 279,282 **** --- 284,311 ---- return + # Check for instance of subclass of common built-in types + # XXX This block is experimental code that will go away! + if self.proto >= 2: + if isinstance(obj, _builtin_type): + assert t not in _builtin_type # Proper subclass + args = () + getnewargs = getattr(obj, "__getnewargs__", None) + if getnewargs: + args = getnewargs() # This better not reference obj + self.save_global(t) + self.save(args) + self.write(NEWOBJ) + self.memoize(obj) + getstate = getattr(obj, "__getstate__", None) + if getstate: + state = getstate() + else: + state = getattr(obj, "__dict__", None) + # XXX What about __slots__? + if state is not None: + self.save(state) + self.write(BUILD) + return + # Check copy_reg.dispatch_table reduce = dispatch_table.get(t) *************** *** 971,975 **** cls = self.stack[-1] obj = cls.__new__(cls, *args) ! self.stack[-1:] = obj dispatch[NEWOBJ] = load_newobj --- 1000,1004 ---- cls = self.stack[-1] obj = cls.__new__(cls, *args) ! self.stack[-1] = obj dispatch[NEWOBJ] = load_newobj From gvanrossum@users.sourceforge.net Tue Jan 28 18:22:38 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 10:22:38 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.114,1.115 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv16136 Modified Files: pickle.py Log Message: Move the NEWOBJ-generating code to a separate function, and invoke it after checking for __reduce__. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.114 retrieving revision 1.115 diff -C2 -d -r1.114 -r1.115 *** pickle.py 28 Jan 2003 17:55:01 -0000 1.114 --- pickle.py 28 Jan 2003 18:22:35 -0000 1.115 *************** *** 284,311 **** return - # Check for instance of subclass of common built-in types - # XXX This block is experimental code that will go away! - if self.proto >= 2: - if isinstance(obj, _builtin_type): - assert t not in _builtin_type # Proper subclass - args = () - getnewargs = getattr(obj, "__getnewargs__", None) - if getnewargs: - args = getnewargs() # This better not reference obj - self.save_global(t) - self.save(args) - self.write(NEWOBJ) - self.memoize(obj) - getstate = getattr(obj, "__getstate__", None) - if getstate: - state = getstate() - else: - state = getattr(obj, "__dict__", None) - # XXX What about __slots__? - if state is not None: - self.save(state) - self.write(BUILD) - return - # Check copy_reg.dispatch_table reduce = dispatch_table.get(t) --- 284,287 ---- *************** *** 316,319 **** --- 292,300 ---- reduce = getattr(obj, "__reduce__", None) if not reduce: + # Check for instance of subclass of common built-in types + if self.proto >= 2 and isinstance(obj, _builtin_type): + assert t not in _builtin_type # Proper subclass + self.save_newobj(obj) + return raise PicklingError("Can't pickle %r object: %r" % (t.__name__, obj)) *************** *** 384,387 **** --- 365,391 ---- save(state) write(BUILD) + + def save_newobj(self, obj): + # Save a new-style class instance, using protocol 2. + # XXX Much of this is still experimental. + t = type(obj) + args = () + getnewargs = getattr(obj, "__getnewargs__", None) + if getnewargs: + args = getnewargs() # This better not reference obj + self.save_global(t) + self.save(args) + self.write(NEWOBJ) + self.memoize(obj) + getstate = getattr(obj, "__getstate__", None) + if getstate: + state = getstate() + else: + state = getattr(obj, "__dict__", None) + # XXX What about __slots__? + if state is not None: + self.save(state) + self.write(BUILD) + return # Methods below this point are dispatched through the dispatch table From nnorwitz@users.sourceforge.net Tue Jan 28 19:21:31 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 28 Jan 2003 11:21:31 -0800 Subject: [Python-checkins] python/dist/src/Objects floatobject.c,2.118,2.119 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv8096/Objects Modified Files: floatobject.c Log Message: Fix SF bug# 676155, RuntimeWarning with tp_compare Check return value of PyLong_AsDouble(), it can return an error. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.118 retrieving revision 2.119 diff -C2 -d -r2.118 -r2.119 *** floatobject.c 21 Nov 2002 22:26:37 -0000 2.118 --- floatobject.c 28 Jan 2003 19:21:24 -0000 2.119 *************** *** 630,634 **** } else if (PyLong_Check(*pw)) { ! *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw)); Py_INCREF(*pv); return 0; --- 630,637 ---- } else if (PyLong_Check(*pw)) { ! double x = PyLong_AsDouble(*pw); ! if (x == -1.0 && PyErr_Occurred()) ! return -1; ! *pw = PyFloat_FromDouble(x); Py_INCREF(*pv); return 0; From nnorwitz@users.sourceforge.net Tue Jan 28 19:22:00 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 28 Jan 2003 11:22:00 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_builtin.py,1.5,1.6 test_long.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv8096/Lib/test Modified Files: test_builtin.py test_long.py Log Message: Fix SF bug# 676155, RuntimeWarning with tp_compare Check return value of PyLong_AsDouble(), it can return an error. Index: test_builtin.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_builtin.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_builtin.py 27 Jan 2003 15:57:14 -0000 1.5 --- test_builtin.py 28 Jan 2003 19:21:18 -0000 1.6 *************** *** 187,190 **** --- 187,191 ---- raise ValueError self.assertRaises(ValueError, coerce, 42, BadNumber()) + self.assertRaises(OverflowError, coerce, 0.5, int("12345" * 1000)) def test_compile(self): Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** test_long.py 19 Nov 2002 20:49:13 -0000 1.21 --- test_long.py 28 Jan 2003 19:21:19 -0000 1.22 *************** *** 372,378 **** verify(float(long(x)) == x) huge = 1L << 30000 mhuge = -huge ! namespace = {'huge': huge, 'mhuge': mhuge, 'math': math} for test in ["float(huge)", "float(mhuge)", "complex(huge)", "complex(mhuge)", --- 372,379 ---- verify(float(long(x)) == x) + shuge = '12345' * 1000 huge = 1L << 30000 mhuge = -huge ! namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math} for test in ["float(huge)", "float(mhuge)", "complex(huge)", "complex(mhuge)", *************** *** 387,391 **** "math.sin(huge)", "math.sin(mhuge)", "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better ! "math.floor(huge)", "math.floor(mhuge)"]: try: --- 388,393 ---- "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)"]: try: From nnorwitz@users.sourceforge.net Tue Jan 28 19:21:51 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 28 Jan 2003 11:21:51 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.630,1.631 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv8096/Misc Modified Files: NEWS Log Message: Fix SF bug# 676155, RuntimeWarning with tp_compare Check return value of PyLong_AsDouble(), it can return an error. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.630 retrieving revision 1.631 diff -C2 -d -r1.630 -r1.631 *** NEWS 27 Jan 2003 22:22:50 -0000 1.630 --- NEWS 28 Jan 2003 19:21:12 -0000 1.631 *************** *** 24,27 **** --- 24,31 ---- See SF bug #667147. + - Fixed an invalid RuntimeWarning and an undetected error when trying + to convert a long integer into a float which couldn't fit. + See SF bug #676155. + Extension modules ----------------- From nnorwitz@users.sourceforge.net Tue Jan 28 19:41:04 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 28 Jan 2003 11:41:04 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.56,1.337.2.4.2.57 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv16314a/Misc Modified Files: Tag: release22-maint NEWS Log Message: backport: Fix SF bug# 676155, RuntimeWarning with tp_compare Check return value of PyLong_AsDouble(), it can return an error. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.56 retrieving revision 1.337.2.4.2.57 diff -C2 -d -r1.337.2.4.2.56 -r1.337.2.4.2.57 *** NEWS 13 Jan 2003 20:17:22 -0000 1.337.2.4.2.56 --- NEWS 28 Jan 2003 19:40:15 -0000 1.337.2.4.2.57 *************** *** 6,9 **** --- 6,12 ---- Python 2.2. or 2.3. + - SF #676155: fixed errors when trying to convert a long integer + into a float which couldn't fit. + - SF #660476 and #513033: broken threadstate swap in readline could cause fatal errors when a readline hook was being invoked while a From nnorwitz@users.sourceforge.net Tue Jan 28 19:41:09 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 28 Jan 2003 11:41:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_b1.py,1.42.4.5,1.42.4.6 test_long.py,1.15,1.15.14.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv16314a/Lib/test Modified Files: Tag: release22-maint test_b1.py test_long.py Log Message: backport: Fix SF bug# 676155, RuntimeWarning with tp_compare Check return value of PyLong_AsDouble(), it can return an error. Index: test_b1.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/Attic/test_b1.py,v retrieving revision 1.42.4.5 retrieving revision 1.42.4.6 diff -C2 -d -r1.42.4.5 -r1.42.4.6 *** test_b1.py 8 Oct 2002 21:03:26 -0000 1.42.4.5 --- test_b1.py 28 Jan 2003 19:40:31 -0000 1.42.4.6 *************** *** 98,101 **** --- 98,105 ---- if fcmp(coerce(1L, 1.1), (1.0, 1.1)): raise TestFailed, 'coerce(1L, 1.1)' + try: coerce(0.5, long("12345" * 1000)) + except OverflowError: pass + else: raise TestFailed, 'coerce(0.5, long("12345" * 1000))' + print 'compile' compile('print 1\n', '', 'exec') Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.15 retrieving revision 1.15.14.1 diff -C2 -d -r1.15 -r1.15.14.1 *** test_long.py 5 Sep 2001 00:53:44 -0000 1.15 --- test_long.py 28 Jan 2003 19:40:33 -0000 1.15.14.1 *************** *** 340,346 **** verify(float(long(x)) == x) huge = 1L << 30000 mhuge = -huge ! namespace = {'huge': huge, 'mhuge': mhuge, 'math': math} for test in ["float(huge)", "float(mhuge)", "complex(huge)", "complex(mhuge)", --- 340,347 ---- verify(float(long(x)) == x) + shuge = '12345' * 1000 huge = 1L << 30000 mhuge = -huge ! namespace = {'huge': huge, 'mhuge': mhuge, 'shuge': shuge, 'math': math} for test in ["float(huge)", "float(mhuge)", "complex(huge)", "complex(mhuge)", *************** *** 355,359 **** "math.sin(huge)", "math.sin(mhuge)", "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better ! "math.floor(huge)", "math.floor(mhuge)"]: try: --- 356,361 ---- "math.sin(huge)", "math.sin(mhuge)", "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better ! "math.floor(huge)", "math.floor(mhuge)", ! "float(shuge) == long(shuge)"]: try: From gvanrossum@users.sourceforge.net Tue Jan 28 19:48:21 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 11:48:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv19333/test Modified Files: pickletester.py Log Message: The default __reduce__ on the base object type obscured any possibility of calling save_reduce(). Add a special hack for this. The tests for this are much simpler now (no __getstate__ or __getnewargs__ needed). Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** pickletester.py 28 Jan 2003 17:55:05 -0000 1.25 --- pickletester.py 28 Jan 2003 19:48:18 -0000 1.26 *************** *** 302,342 **** def test_newobj_tuple(self): ! x = MyTuple([1, 2, 3], foo=42, bar="hello") s = self.dumps(x, 2) y = self.loads(s) self.assertEqual(tuple(x), tuple(y)) self.assertEqual(x.__dict__, y.__dict__) def test_newobj_list(self): ! x = MyList([1, 2, 3], foo=42, bar="hello") s = self.dumps(x, 2) y = self.loads(s) self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) class MyTuple(tuple): ! def __new__(cls, *args, **kwds): ! # Ignore **kwds ! return tuple.__new__(cls, *args) ! def __getnewargs__(self): ! return (tuple(self),) ! def __init__(self, *args, **kwds): ! for k, v in kwds.items(): ! setattr(self, k, v) class MyList(list): ! def __new__(cls, *args, **kwds): ! # Ignore **kwds ! return list.__new__(cls, *args) ! def __init__(self, *args, **kwds): ! for k, v in kwds.items(): ! setattr(self, k, v) ! def __getstate__(self): ! return list(self), self.__dict__ ! def __setstate__(self, arg): ! lst, dct = arg ! for x in lst: ! self.append(x) ! self.__init__(**dct) class AbstractPickleModuleTests(unittest.TestCase): --- 302,333 ---- def test_newobj_tuple(self): ! x = MyTuple([1, 2, 3]) ! x.foo = 42 ! x.bar = "hello" s = self.dumps(x, 2) y = self.loads(s) self.assertEqual(tuple(x), tuple(y)) self.assertEqual(x.__dict__, y.__dict__) + ## import pickletools + ## print + ## pickletools.dis(s) def test_newobj_list(self): ! x = MyList([1, 2, 3]) ! x.foo = 42 ! x.bar = "hello" s = self.dumps(x, 2) y = self.loads(s) self.assertEqual(list(x), list(y)) self.assertEqual(x.__dict__, y.__dict__) + ## import pickletools + ## print + ## pickletools.dis(s) class MyTuple(tuple): ! pass class MyList(list): ! pass class AbstractPickleModuleTests(unittest.TestCase): From gvanrossum@users.sourceforge.net Tue Jan 28 19:48:21 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 11:48:21 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.115,1.116 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19333 Modified Files: pickle.py Log Message: The default __reduce__ on the base object type obscured any possibility of calling save_reduce(). Add a special hack for this. The tests for this are much simpler now (no __getstate__ or __getnewargs__ needed). Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.115 retrieving revision 1.116 diff -C2 -d -r1.115 -r1.116 *** pickle.py 28 Jan 2003 18:22:35 -0000 1.115 --- pickle.py 28 Jan 2003 19:48:16 -0000 1.116 *************** *** 28,32 **** from types import * ! from copy_reg import dispatch_table, safe_constructors import marshal import sys --- 28,32 ---- from types import * ! from copy_reg import dispatch_table, safe_constructors, _reconstructor import marshal import sys *************** *** 321,324 **** --- 321,331 ---- "exactly two or three elements" % reduce) + # XXX Temporary hack XXX + # Override the default __reduce__ for new-style class instances + if self.proto >= 2: + if func is _reconstructor: + self.save_newobj(obj) + return + # Save the reduce() output and finally memoize the object self.save_reduce(func, args, state) *************** *** 370,381 **** # XXX Much of this is still experimental. t = type(obj) - args = () getnewargs = getattr(obj, "__getnewargs__", None) if getnewargs: args = getnewargs() # This better not reference obj self.save_global(t) ! self.save(args) ! self.write(NEWOBJ) self.memoize(obj) getstate = getattr(obj, "__getstate__", None) if getstate: --- 377,411 ---- # XXX Much of this is still experimental. t = type(obj) getnewargs = getattr(obj, "__getnewargs__", None) if getnewargs: args = getnewargs() # This better not reference obj + else: + for cls in int, long, float, complex, str, unicode, tuple: + if isinstance(obj, cls): + args = (cls(obj),) + break + else: + args = () + + save = self.save + write = self.write + self.save_global(t) ! save(args) ! write(NEWOBJ) self.memoize(obj) + + if isinstance(obj, list): + write(MARK) + for x in obj: + save(x) + write(APPENDS) + elif isinstance(obj, dict): + write(MARK) + for k, v in obj.iteritems(): + save(k) + save(v) + write(SETITEMS) + getstate = getattr(obj, "__getstate__", None) if getstate: *************** *** 385,391 **** # XXX What about __slots__? if state is not None: ! self.save(state) ! self.write(BUILD) ! return # Methods below this point are dispatched through the dispatch table --- 415,420 ---- # XXX What about __slots__? if state is not None: ! save(state) ! write(BUILD) # Methods below this point are dispatched through the dispatch table *************** *** 1174,1177 **** --- 1203,1208 ---- >>> """ + # XXX This is still a quadratic algorithm. + # Should use hex() to get started. digits = [] while not -128 <= x < 128: *************** *** 1196,1199 **** --- 1227,1231 ---- 127L """ + # XXX This is quadratic too. x = 0L i = 0L From nnorwitz@users.sourceforge.net Tue Jan 28 19:40:41 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 28 Jan 2003 11:40:41 -0800 Subject: [Python-checkins] python/dist/src/Objects floatobject.c,2.110.6.2,2.110.6.3 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv16314a/Objects Modified Files: Tag: release22-maint floatobject.c Log Message: backport: Fix SF bug# 676155, RuntimeWarning with tp_compare Check return value of PyLong_AsDouble(), it can return an error. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.110.6.2 retrieving revision 2.110.6.3 diff -C2 -d -r2.110.6.2 -r2.110.6.3 *** floatobject.c 12 May 2002 17:20:38 -0000 2.110.6.2 --- floatobject.c 28 Jan 2003 19:40:35 -0000 2.110.6.3 *************** *** 626,630 **** } else if (PyLong_Check(*pw)) { ! *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw)); Py_INCREF(*pv); return 0; --- 626,633 ---- } else if (PyLong_Check(*pw)) { ! double x = PyLong_AsDouble(*pw); ! if (x == -1.0 && PyErr_Occurred()) ! return -1; ! *pw = PyFloat_FromDouble(x); Py_INCREF(*pv); return 0; From tim_one@users.sourceforge.net Tue Jan 28 20:37:50 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 12:37:50 -0800 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.146,1.147 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv8113/python/Objects Modified Files: longobject.c Log Message: Added new private API function _PyLong_NumBits. This will be used at the start for the C implemention of new pickle LONG1 and LONG4 opcodes (the linear-time way to pickle a long is to call _PyLong_AsByteArray, but the caller has no idea how big an array to allocate, and correct calculation is a bit subtle). Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.146 retrieving revision 1.147 diff -C2 -d -r1.146 -r1.147 *** longobject.c 30 Dec 2002 20:19:02 -0000 1.146 --- longobject.c 28 Jan 2003 20:37:45 -0000 1.147 *************** *** 261,264 **** --- 261,299 ---- } + size_t + _PyLong_NumBits(PyObject *vv) + { + PyLongObject *v = (PyLongObject *)vv; + size_t result = 1; /* for the sign bit */ + size_t ndigits = ABS(v->ob_size); + + assert(v != NULL); + assert(PyLong_Check(v)); + assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + if (ndigits > 0) { + size_t product; + digit msd = v->ob_digit[ndigits - 1]; + + product = (ndigits - 1) * SHIFT; + if (product / SHIFT != ndigits - 1) + goto Overflow; + result += product; + if (result < product) + goto Overflow; + do { + ++result; + if (result == 0) + goto Overflow; + msd >>= 1; + } while (msd); + } + return result; + + Overflow: + PyErr_SetString(PyExc_OverflowError, "long has too many bits " + "to express in a platform size_t"); + return (size_t)-1; + } + PyObject * _PyLong_FromByteArray(const unsigned char* bytes, size_t n, From tim_one@users.sourceforge.net Tue Jan 28 20:38:16 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 12:38:16 -0800 Subject: [Python-checkins] python/dist/src/Include longobject.h,2.26,2.27 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv8113/python/Include Modified Files: longobject.h Log Message: Added new private API function _PyLong_NumBits. This will be used at the start for the C implemention of new pickle LONG1 and LONG4 opcodes (the linear-time way to pickle a long is to call _PyLong_AsByteArray, but the caller has no idea how big an array to allocate, and correct calculation is a bit subtle). Index: longobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v retrieving revision 2.26 retrieving revision 2.27 diff -C2 -d -r2.26 -r2.27 *** longobject.h 12 Aug 2002 07:21:57 -0000 2.26 --- longobject.h 28 Jan 2003 20:37:41 -0000 2.27 *************** *** 45,48 **** --- 45,59 ---- #endif + /* _PyLong_NumBits. Return the number of bits needed to represent a long + in contiguous 2's-complement form, including 1 for the sign bit. For + example, this returns 1 for 0, and 2 for 1 and -1. Note that the + ceiling of this divided by 8 is the number of bytes needed by + _PyLong_AsByteArray to store the long in 256's-complement form. + v must not be NULL, and must be a normalized long. + (size_t)-1 is returned and OverflowError set if the true result doesn't + fit in a size_t. + */ + PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); + /* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in base 256, and return a Python long with the same numeric value. From tim_one@users.sourceforge.net Tue Jan 28 20:38:18 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 12:38:18 -0800 Subject: [Python-checkins] python/dist/src/Modules _testcapimodule.c,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv8113/python/Modules Modified Files: _testcapimodule.c Log Message: Added new private API function _PyLong_NumBits. This will be used at the start for the C implemention of new pickle LONG1 and LONG4 opcodes (the linear-time way to pickle a long is to call _PyLong_AsByteArray, but the caller has no idea how big an array to allocate, and correct calculation is a bit subtle). Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** _testcapimodule.c 23 Jul 2002 06:31:14 -0000 1.17 --- _testcapimodule.c 28 Jan 2003 20:37:43 -0000 1.18 *************** *** 37,41 **** { char buf[1024]; ! PyOS_snprintf(buf, sizeof(buf), "%.200s #define == %d but sizeof(%.200s) == %d", fatname, expected, typename, got); --- 37,41 ---- { char buf[1024]; ! PyOS_snprintf(buf, sizeof(buf), "%.200s #define == %d but sizeof(%.200s) == %d", fatname, expected, typename, got); *************** *** 327,331 **** return raiseTestError("test_u_code", "u# code returned wrong values for u'test'"); ! Py_DECREF(tuple); Py_INCREF(Py_None); --- 327,331 ---- return raiseTestError("test_u_code", "u# code returned wrong values for u'test'"); ! Py_DECREF(tuple); Py_INCREF(Py_None); *************** *** 335,338 **** --- 335,374 ---- #endif + /* Simple test of _PyLong_NumBits. */ + static PyObject * + test_long_numbits(PyObject *self) + { + struct pair { + long input; + size_t output; + } testcases[] = {{0, 1}, + {1L, 2}, + {-1L, 2}, + {2L, 3}, + {-2L, 3}, + {3L, 3}, + {-3L, 3}, + {4L, 4}, + {-4L, 4}, + {0x7fffL, 16}, /* one Python long digit */ + {-0x7fffL, 16}, + {0xfffffffL, 29}, + {-0xfffffffL, 29}}; + int i; + + for (i = 0; i < sizeof(testcases) / sizeof(struct pair); ++i) { + long input = testcases[i].input; + PyObject *plong = PyLong_FromLong(input); + size_t nbits = _PyLong_NumBits(plong); + + Py_DECREF(plong); + if (nbits != testcases[i].output) + return raiseTestError("test_long_numbits", + "wrong result"); + } + Py_INCREF(Py_None); + return Py_None; + } + static PyObject * raise_exception(PyObject *self, PyObject *args) *************** *** 367,370 **** --- 403,407 ---- {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS}, + {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, #ifdef HAVE_LONG_LONG {"test_longlong_api", (PyCFunction)test_longlong_api, METH_NOARGS}, From gvanrossum@users.sourceforge.net Tue Jan 28 20:39:53 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 12:39:53 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_compile.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv10396 Modified Files: test_compile.py Log Message: Comment out a test that was anticipating SF patch 661536 -- but that isn't checked in yet. :-( Index: test_compile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_compile.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_compile.py 28 Jan 2003 17:48:21 -0000 1.13 --- test_compile.py 28 Jan 2003 20:39:49 -0000 1.14 *************** *** 134,141 **** expect_same("000000000000009.", 9.) ! # Verify treatment of unary minus on negative numbers SF bug #660455 ! import warnings ! warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning) ! # XXX Of course the following test will have to be changed in Python 2.4 ! expect_same("0xffffffff", -1) ! expect_same("-0xffffffff", 1) --- 134,141 ---- expect_same("000000000000009.", 9.) ! ## # Verify treatment of unary minus on negative numbers SF bug #660455 ! ## import warnings ! ## warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning) ! ## # XXX Of course the following test will have to be changed in Python 2.4 ! ## expect_same("0xffffffff", -1) ! ## expect_same("-0xffffffff", 1) From jackjansen@users.sourceforge.net Tue Jan 28 21:39:31 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 28 Jan 2003 13:39:31 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_macfs.py,NONE,1.1 test_macostools.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv9905 Added Files: test_macfs.py test_macostools.py Log Message: Finally created the first two tests for MacPython modules: macfs and macostools. --- NEW FILE: test_macfs.py --- # Copyright (C) 2003 Python Software Foundation import unittest import macfs import os import tempfile from test import test_support class TestMacfs(unittest.TestCase): def setUp(self): fp = open(test_support.TESTFN, 'w') fp.write('hello world\n') fp.close() def tearDown(self): try: os.unlink(test_support.TESTFN) except: pass def test_fsspec(self): fss = macfs.FSSpec(test_support.TESTFN) self.assertEqual(os.path.abspath(test_support.TESTFN), fss.as_pathname()) def test_fsref(self): fsr = macfs.FSRef(test_support.TESTFN) self.assertEqual(os.path.abspath(test_support.TESTFN), fsr.as_pathname()) def test_coercion(self): fss = macfs.FSSpec(test_support.TESTFN) fsr = macfs.FSRef(test_support.TESTFN) fss2 = fsr.as_fsspec() fsr2 = fss.as_fsref() self.assertEqual(fss.as_pathname(), fss2.as_pathname()) self.assertEqual(fsr.as_pathname(), fsr2.as_pathname()) def test_dates(self): import time fss = macfs.FSSpec(test_support.TESTFN) now = int(time.time()) fss.SetDates(now, now-1, now-2) dates = fss.GetDates() self.assertEqual(dates, (now, now-1, now-2)) def test_ctor_type(self): fss = macfs.FSSpec(test_support.TESTFN) fss.SetCreatorType('Pyth', 'TEXT') filecr, filetp = fss.GetCreatorType() self.assertEqual((filecr, filetp), ('Pyth', 'TEXT')) def test_alias(self): fss = macfs.FSSpec(test_support.TESTFN) alias = fss.NewAlias() fss2, changed = alias.Resolve() self.assertEqual(changed, 0) self.assertEqual(fss.as_pathname(), fss2.as_pathname()) def test_fss_alias(self): fss = macfs.FSSpec(test_support.TESTFN) def test_main(): test_support.run_unittest(TestMacfs) if __name__ == '__main__': test_main() --- NEW FILE: test_macostools.py --- # Copyright (C) 2003 Python Software Foundation import unittest import macostools import MacOS import os import tempfile from test import test_support TESTFN2 = test_support.TESTFN + '2' class TestMacostools(unittest.TestCase): def setUp(self): fp = open(test_support.TESTFN, 'w') fp.write('hello world\n') fp.close() rfp = MacOS.openrf(test_support.TESTFN, '*wb') rfp.write('goodbye world\n') rfp.close() def tearDown(self): try: os.unlink(test_support.TESTFN) except: pass try: os.unlink(TESTFN2) except: pass def compareData(self): fp = open(test_support.TESTFN, 'r') data1 = fp.read() fp.close() fp = open(TESTFN2, 'r') data2 = fp.read() fp.close() if data1 != data2: return 'Data forks differ' rfp = MacOS.openrf(test_support.TESTFN, '*rb') data1 = rfp.read(1000) rfp.close() rfp = MacOS.openrf(TESTFN2, '*rb') data2 = rfp.read(1000) rfp.close() if data1 != data2: return 'Resource forks differ' return '' def test_touched(self): # This really only tests that nothing unforeseen happens. macostools.touched(test_support.TESTFN) def test_copy(self): try: os.unlink(TESTFN2) except: pass macostools.copy(test_support.TESTFN, TESTFN2) self.assertEqual(self.compareData(), '') def test_main(): test_support.run_unittest(TestMacostools) if __name__ == '__main__': test_main() From jackjansen@users.sourceforge.net Tue Jan 28 21:40:41 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 28 Jan 2003 13:40:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macfs.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv10763 Modified Files: macfs.py Log Message: Don't import Nav. It isn't needed, and importing it doesn't work in a non-windowing Python. Index: macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macfs.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** macfs.py 22 Jan 2003 14:04:18 -0000 1.6 --- macfs.py 28 Jan 2003 21:40:36 -0000 1.7 *************** *** 6,10 **** import Carbon.Res import Carbon.File - import Nav import warnings --- 6,9 ---- From jackjansen@users.sourceforge.net Tue Jan 28 21:45:47 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 28 Jan 2003 13:45:47 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSX Makefile,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSX In directory sc8-pr-cvs1:/tmp/cvs-serv13195 Modified Files: Makefile Log Message: Install "python$(VERSION)" into /usr/local as the symlink to the framework, and also create a symlink "python" pointing to "python$(VERSION)". Fixes #675745. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSX/Makefile,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** Makefile 30 Dec 2002 22:23:40 -0000 1.32 --- Makefile 28 Jan 2003 21:45:44 -0000 1.33 *************** *** 206,211 **** installunixtools: $(INSTALLED_PYTHON) $(INSTALLED_PYTHONW) $(INSTALL) -d $(bindir) ! $(INSTALL_SYMLINK) $(INSTALLED_PYTHON) $(bindir)/python echo "#!/bin/sh" > pythonw.sh echo "exec \"$(INSTALLED_PYTHONW)\" \"\$$@\"" >> pythonw.sh ! $(INSTALL) pythonw.sh $(bindir)/pythonw --- 206,213 ---- installunixtools: $(INSTALLED_PYTHON) $(INSTALLED_PYTHONW) $(INSTALL) -d $(bindir) ! $(INSTALL_SYMLINK) $(INSTALLED_PYTHON) $(bindir)/python$(VERSION) ! $(INSTALL_SYMLINK) python$(VERSION) $(bindir)/python echo "#!/bin/sh" > pythonw.sh echo "exec \"$(INSTALLED_PYTHONW)\" \"\$$@\"" >> pythonw.sh ! $(INSTALL) pythonw.sh $(bindir)/pythonw$(VERSION) ! $(INSTALL_SYMLINK) pythonw$(VERSION) $(bindir)/pythonw From fdrake@users.sourceforge.net Tue Jan 28 21:53:12 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 28 Jan 2003 13:53:12 -0800 Subject: [Python-checkins] python/dist/src/Doc Makefile.deps,1.96,1.97 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory sc8-pr-cvs1:/tmp/cvs-serv17887 Modified Files: Makefile.deps Log Message: Added missing dependency. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -d -r1.96 -r1.97 *** Makefile.deps 6 Jan 2003 16:51:32 -0000 1.96 --- Makefile.deps 28 Jan 2003 21:53:05 -0000 1.97 *************** *** 167,170 **** --- 167,171 ---- lib/libposixfile.tex \ lib/libsyslog.tex \ + lib/liblogging.tex \ lib/libpdb.tex \ lib/libprofile.tex \ From gvanrossum@users.sourceforge.net Tue Jan 28 22:01:19 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 14:01:19 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.116,1.117 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv22784 Modified Files: pickle.py Log Message: Instead of bad hacks trying to worm around the inherited object.__reduce__, do a getattr() on the class so we can explicitly test for it. The reduce()-calling code becomes a bit more regular as a result. Also add support slots: if an object has slots, the default state is (dict, slots) where dict is the __dict__ or None, and slots is a dict mapping slot names to slot values. We do a best-effort approach to find slot names, assuming the __slots__ fields of classes aren't modified after class definition time to misrepresent the actual list of slots defined by a class. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -d -r1.116 -r1.117 *** pickle.py 28 Jan 2003 19:48:16 -0000 1.116 --- pickle.py 28 Jan 2003 22:01:16 -0000 1.117 *************** *** 252,259 **** return GET + `i` + '\n' ! def save(self, obj, ! _builtin_type = (int, long, float, complex, str, unicode, ! tuple, list, dict), ! ): # Check for persistent id (defined by a subclass) pid = self.persistent_id(obj) --- 252,256 ---- return GET + `i` + '\n' ! def save(self, obj): # Check for persistent id (defined by a subclass) pid = self.persistent_id(obj) *************** *** 286,303 **** # Check copy_reg.dispatch_table reduce = dispatch_table.get(t) ! if reduce: ! rv = reduce(obj) ! else: ! # Check for __reduce__ method ! reduce = getattr(obj, "__reduce__", None) ! if not reduce: ! # Check for instance of subclass of common built-in types ! if self.proto >= 2 and isinstance(obj, _builtin_type): ! assert t not in _builtin_type # Proper subclass self.save_newobj(obj) return raise PicklingError("Can't pickle %r object: %r" % (t.__name__, obj)) ! rv = reduce() # Check for string returned by reduce(), meaning "save as global" --- 283,304 ---- # Check copy_reg.dispatch_table reduce = dispatch_table.get(t) ! if not reduce: ! # Check for a __reduce__ method. ! # Subtle: get the unbound method from the class, so that ! # protocol 2 can override the default __reduce__ that all ! # classes inherit from object. This has the added ! # advantage that the call always has the form reduce(obj) ! reduce = getattr(t, "__reduce__", None) ! if self.proto >= 2: ! # Protocol 2 can do better than the default __reduce__ ! if reduce is object.__reduce__: ! reduce = None ! if not reduce: self.save_newobj(obj) return + if not reduce: raise PicklingError("Can't pickle %r object: %r" % (t.__name__, obj)) ! rv = reduce(obj) # Check for string returned by reduce(), meaning "save as global" *************** *** 321,331 **** "exactly two or three elements" % reduce) - # XXX Temporary hack XXX - # Override the default __reduce__ for new-style class instances - if self.proto >= 2: - if func is _reconstructor: - self.save_newobj(obj) - return - # Save the reduce() output and finally memoize the object self.save_reduce(func, args, state) --- 322,325 ---- *************** *** 376,383 **** # Save a new-style class instance, using protocol 2. # XXX Much of this is still experimental. t = type(obj) getnewargs = getattr(obj, "__getnewargs__", None) if getnewargs: ! args = getnewargs() # This better not reference obj else: for cls in int, long, float, complex, str, unicode, tuple: --- 370,378 ---- # Save a new-style class instance, using protocol 2. # XXX Much of this is still experimental. + assert self.proto >= 2 # This only works for protocol 2 t = type(obj) getnewargs = getattr(obj, "__getnewargs__", None) if getnewargs: ! args = getnewargs() # This bette not reference obj else: for cls in int, long, float, complex, str, unicode, tuple: *************** *** 410,417 **** getstate = getattr(obj, "__getstate__", None) if getstate: ! state = getstate() ! else: state = getattr(obj, "__dict__", None) ! # XXX What about __slots__? if state is not None: save(state) --- 405,434 ---- getstate = getattr(obj, "__getstate__", None) if getstate: ! try: ! state = getstate() ! except TypeError, err: ! # XXX Catch generic exception caused by __slots__ ! if str(err) != ("a class that defines __slots__ " ! "without defining __getstate__ " ! "cannot be pickled"): ! print repr(str(err)) ! raise # Not that specific exception ! getstate = None ! if not getstate: state = getattr(obj, "__dict__", None) ! # If there are slots, the state becomes a tuple of two ! # items: the first item the regular __dict__ or None, and ! # the second a dict mapping slot names to slot values ! names = _slotnames(t) ! if names: ! slots = {} ! nil = [] ! for name in names: ! value = getattr(obj, name, nil) ! if value is not nil: ! slots[name] = value ! if slots: ! state = (state, slots) ! if state is not None: save(state) *************** *** 719,722 **** --- 736,757 ---- # Pickling helpers + def _slotnames(cls): + """Return a list of slot names for a given class. + + This needs to find slots defined by the class and its bases, so we + can't simply return the __slots__ attribute. We must walk down + the Method Resolution Order and concatenate the __slots__ of each + class found there. (This assumes classes don't modify their + __slots__ attribute to misrepresent their slots after the class is + defined.) + """ + if not hasattr(cls, "__slots__"): + return [] + names = [] + for c in cls.__mro__: + if "__slots__" in c.__dict__: + names += list(c.__dict__["__slots__"]) + return names + def _keep_alive(x, memo): """Keeps a reference to the object x in the memo. *************** *** 1153,1172 **** def load_build(self): stack = self.stack ! value = stack.pop() inst = stack[-1] ! try: ! setstate = inst.__setstate__ ! except AttributeError: try: ! inst.__dict__.update(value) except RuntimeError: ! # XXX In restricted execution, the instance's __dict__ is not ! # accessible. Use the old way of unpickling the instance ! # variables. This is a semantic different when unpickling in ! # restricted vs. unrestricted modes. ! for k, v in value.items(): setattr(inst, k, v) ! else: ! setstate(value) dispatch[BUILD] = load_build --- 1188,1214 ---- def load_build(self): stack = self.stack ! state = stack.pop() inst = stack[-1] ! setstate = getattr(inst, "__setstate__", None) ! if setstate: ! setstate(state) ! return ! slotstate = None ! if isinstance(state, tuple) and len(state) == 2: ! state, slotstate = state ! if state: try: ! inst.__dict__.update(state) except RuntimeError: ! # XXX In restricted execution, the instance's __dict__ ! # is not accessible. Use the old way of unpickling ! # the instance variables. This is a semantic ! # difference when unpickling in restricted ! # vs. unrestricted modes. ! for k, v in state.items(): setattr(inst, k, v) ! if slotstate: ! for k, v in slotstate.items(): ! setattr(inst, k, v) dispatch[BUILD] = load_build From gvanrossum@users.sourceforge.net Tue Jan 28 22:02:35 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 14:02:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv23734 Modified Files: pickletester.py Log Message: Add a test for a list subclass with a __dict__ as well as slots. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** pickletester.py 28 Jan 2003 19:48:18 -0000 1.26 --- pickletester.py 28 Jan 2003 22:02:31 -0000 1.27 *************** *** 325,328 **** --- 325,342 ---- ## pickletools.dis(s) + def test_newobj_list_slots(self): + x = SlotList([1, 2, 3]) + x.foo = 42 + x.bar = "hello" + s = self.dumps(x, 2) + y = self.loads(s) + self.assertEqual(list(x), list(y)) + self.assertEqual(x.__dict__, y.__dict__) + self.assertEqual(x.foo, y.foo) + self.assertEqual(x.bar, y.bar) + ## import pickletools + ## print + ## pickletools.dis(s) + class MyTuple(tuple): pass *************** *** 330,333 **** --- 344,350 ---- class MyList(list): pass + + class SlotList(MyList): + __slots__ = ["foo"] class AbstractPickleModuleTests(unittest.TestCase): From fdrake@users.sourceforge.net Tue Jan 28 22:02:39 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 28 Jan 2003 14:02:39 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib liblogging.tex,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv23762 Modified Files: liblogging.tex Log Message: Various minor markup adjustments. Index: liblogging.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liblogging.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** liblogging.tex 25 Jan 2003 21:46:53 -0000 1.5 --- liblogging.tex 28 Jan 2003 22:02:35 -0000 1.6 *************** *** 9,13 **** \sectionauthor{Vinay Sajip}{vinay_sajip@red-dove.com} ! \modulesynopsis{Logging module for Python based on PEP 282.} \indexii{Errors}{logging} --- 9,13 ---- \sectionauthor{Vinay Sajip}{vinay_sajip@red-dove.com} ! \modulesynopsis{Logging module for Python based on \pep{282}.} \indexii{Errors}{logging} *************** *** 91,95 **** \item \class{SysLogHandler} instances send error messages to a ! Unix syslog, possibly on a remote machine. \item \class{NTEventLogHandler} instances send error messages to a --- 91,95 ---- \item \class{SysLogHandler} instances send error messages to a ! \UNIX{} syslog daemon, possibly on a remote machine. \item \class{NTEventLogHandler} instances send error messages to a *************** *** 101,105 **** \item \class{HTTPHandler} instances send error messages to an ! HTTP server using either GET or POST semantics. \end{enumerate} --- 101,105 ---- \item \class{HTTPHandler} instances send error messages to an ! HTTP server using either \samp{GET} or \samp{POST} semantics. \end{enumerate} *************** *** 228,231 **** --- 228,239 ---- \end{funcdesc} + + \begin{seealso} + \seepep{282}{A Logging System} + {The proposal which described this feature for inclusion in + the Python standard library.} + \end{seealso} + + \subsection{Logger Objects} *************** *** 343,350 **** \subsection{Handler Objects} ! Handlers have the following attributes and methods. Note that a Handler is ! never instantiated directly; this class acts as a base for more useful ! subclasses. However, the \method{__init__()} in subclasses needs to call ! \method{Handler.__init__()}. \begin{methoddesc}{__init__}{level=\constant{ALL}} --- 351,358 ---- \subsection{Handler Objects} ! Handlers have the following attributes and methods. Note that ! \class{Handler} is never instantiated directly; this class acts as a ! base for more useful subclasses. However, the \method{__init__()} ! method in subclasses needs to call \method{Handler.__init__()}. \begin{methoddesc}{__init__}{level=\constant{ALL}} *************** *** 458,462 **** The \class{FileHandler} class sends logging output to a disk file. ! It delegates the output functionality from \class{StreamHandler}. \begin{classdesc}{FileHandler}{filename\optional{, mode}} --- 466,470 ---- The \class{FileHandler} class sends logging output to a disk file. ! It inherits the output functionality from \class{StreamHandler}. \begin{classdesc}{FileHandler}{filename\optional{, mode}} *************** *** 483,487 **** Returns a new instance of the \class{RotatingFileHandler} class. The specified file is opened and used as the stream for logging. If ! \var{mode} is not specified, \constant{"a"} is used. By default, the file grows indefinitely. You can use the \var{maxBytes} and \var{backupCount} values to allow the file to \dfn{rollover} at a --- 491,495 ---- Returns a new instance of the \class{RotatingFileHandler} class. The specified file is opened and used as the stream for logging. If ! \var{mode} is not specified, \code{'a'} is used. By default, the file grows indefinitely. You can use the \var{maxBytes} and \var{backupCount} values to allow the file to \dfn{rollover} at a *************** *** 583,594 **** The \class{SysLogHandler} class supports sending logging messages to a ! remote or local Unix syslog. \begin{classdesc}{SysLogHandler}{\optional{address\optional{, facility}}} Returns a new instance of the \class{SysLogHandler} class intended to ! communicate with a remote Unix machine whose address is given by ! \var{address} in the form of a (host, port) tuple. If \var{address} is not ! specified, ('localhost', 514) is used. The address is used to open a UDP ! socket. If \var{facility} is not specified, \constant{LOG_USER} is used. \end{classdesc} --- 591,603 ---- The \class{SysLogHandler} class supports sending logging messages to a ! remote or local \UNIX{} syslog. \begin{classdesc}{SysLogHandler}{\optional{address\optional{, facility}}} Returns a new instance of the \class{SysLogHandler} class intended to ! communicate with a remote \UNIX{} machine whose address is given by ! \var{address} in the form of a \code{(\var{host}, \var{port})} ! tuple. If \var{address} is not specified, \code{('localhost', 514)} is ! used. The address is used to open a UDP socket. If \var{facility} is ! not specified, \constant{LOG_USER} is used. \end{classdesc} *************** *** 758,767 **** The \class{HTTPHandler} class supports sending logging messages to a ! Web server, using either GET or POST semantics. \begin{classdesc}{HTTPHandler}{host, url\optional{, method}} Returns a new instance of the \class{HTTPHandler} class. The instance is initialized with a host address, url and HTTP method. ! If no \var{method} is specified, GET is used. \end{classdesc} --- 767,776 ---- The \class{HTTPHandler} class supports sending logging messages to a ! Web server, using either \samp{GET} or \samp{POST} semantics. \begin{classdesc}{HTTPHandler}{host, url\optional{, method}} Returns a new instance of the \class{HTTPHandler} class. The instance is initialized with a host address, url and HTTP method. ! If no \var{method} is specified, \samp{GET} is used. \end{classdesc} From fdrake@users.sourceforge.net Tue Jan 28 22:09:19 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 28 Jan 2003 14:09:19 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib liblogging.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv27721 Modified Files: liblogging.tex Log Message: More markup changes for consistency. Index: liblogging.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liblogging.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** liblogging.tex 28 Jan 2003 22:02:35 -0000 1.6 --- liblogging.tex 28 Jan 2003 22:09:16 -0000 1.7 *************** *** 30,37 **** convenience, you indicate the importance of a logged message by calling an appropriate method of \class{Logger}. The methods are ! \method{debug}, \method{info}, \method{warning}, \method{error} and ! \method{critical}, which mirrors the default levels. You are not ! constrained to use these levels - you can specify your own and use a ! more general \class{Logger} method, \method{log}, which takes an explicit level argument. --- 30,37 ---- convenience, you indicate the importance of a logged message by calling an appropriate method of \class{Logger}. The methods are ! \method{debug()}, \method{info()}, \method{warning()}, \method{error()} and ! \method{critical()}, which mirror the default levels. You are not ! constrained to use these levels: you can specify your own and use a ! more general \class{Logger} method, \method{log()}, which takes an explicit level argument. *************** *** 58,69 **** associated with it (via the \method{addHandler} method of \class{Logger}). In addition to any handlers directly associated with a logger, ! \emph{all handlers associated with all ancestors of the logger} are called ! upon to dispatch the message. Just as for loggers, handlers can have levels associated with them. A handler's level acts as a filter in the same way as a logger's level does. ! If a handler decides to actually dispatch an event, the \method{emit} method is used to send the message to its destination. Most user-defined subclasses ! of \class{Handler} will need to override this \method{emit}. In addition to the base \class{Handler} class, many useful subclasses --- 58,69 ---- associated with it (via the \method{addHandler} method of \class{Logger}). In addition to any handlers directly associated with a logger, ! \emph{all handlers associated with all ancestors of the logger} are ! called to dispatch the message. Just as for loggers, handlers can have levels associated with them. A handler's level acts as a filter in the same way as a logger's level does. ! If a handler decides to actually dispatch an event, the \method{emit()} method is used to send the message to its destination. Most user-defined subclasses ! of \class{Handler} will need to override this \method{emit()}. In addition to the base \class{Handler} class, many useful subclasses *************** *** 121,125 **** When filtering based on logger level and/or handler level is not enough, instances of \class{Filter} can be added to both \class{Logger} and ! \class{Handler} instances (through their \method{addFilter} method). Before deciding to process a message further, both loggers and handlers consult all their filters for permission. If any filter returns a false --- 121,125 ---- When filtering based on logger level and/or handler level is not enough, instances of \class{Filter} can be added to both \class{Logger} and ! \class{Handler} instances (through their \method{addFilter()} method). Before deciding to process a message further, both loggers and handlers consult all their filters for permission. If any filter returns a false *************** *** 148,152 **** \var{kwargs} which is inspected is \var{exc_info} which, if it does not evaluate as false, causes exception information (via a call to ! \method{sys.exc_info()}) to be added to the logging message. \end{funcdesc} --- 148,152 ---- \var{kwargs} which is inspected is \var{exc_info} which, if it does not evaluate as false, causes exception information (via a call to ! \function{sys.exc_info()}) to be added to the logging message. \end{funcdesc} *************** *** 275,279 **** \var{kwargs} which is inspected is \var{exc_info} which, if it does not evaluate as false, causes exception information (via a call to ! \method{sys.exc_info()}) to be added to the logging message. \end{methoddesc} --- 275,279 ---- \var{kwargs} which is inspected is \var{exc_info} which, if it does not evaluate as false, causes exception information (via a call to ! \function{sys.exc_info()}) to be added to the logging message. \end{methoddesc} *************** *** 842,846 **** in formatters to provide for any specific requirement, but the basic behavior is as follows: if \var{datefmt} (a string) is specified, ! it is used with \method{time.strftime()} to format the creation time of the record. Otherwise, the ISO8601 format is used. The resulting string is returned. --- 842,846 ---- in formatters to provide for any specific requirement, but the basic behavior is as follows: if \var{datefmt} (a string) is specified, ! it is used with \function{time.strftime()} to format the creation time of the record. Otherwise, the ISO8601 format is used. The resulting string is returned. *************** *** 849,854 **** \begin{methoddesc}{formatException}{exc_info} Formats the specified exception information (a standard exception tuple ! as returned by \method{sys.exc_info()}) as a string. This default ! implementation just uses \method{traceback.print_exception()}. The resulting string is returned. \end{methoddesc} --- 849,854 ---- \begin{methoddesc}{formatException}{exc_info} Formats the specified exception information (a standard exception tuple ! as returned by \function{sys.exc_info()}) as a string. This default ! implementation just uses \function{traceback.print_exception()}. The resulting string is returned. \end{methoddesc} From tim_one@users.sourceforge.net Tue Jan 28 22:26:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 14:26:34 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_cpickle.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv2928/Lib/test Modified Files: test_cpickle.py Log Message: Renamed "bin" arguments to "proto". Note that this test currently fails, for reasons unrelated to this patch. Index: test_cpickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cpickle.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_cpickle.py 23 Jul 2002 19:03:46 -0000 1.12 --- test_cpickle.py 28 Jan 2003 22:26:28 -0000 1.13 *************** *** 16,22 **** class cPicklePicklerTests(AbstractPickleTests): ! def dumps(self, arg, bin=0): f = StringIO() ! p = cPickle.Pickler(f, bin) p.dump(arg) f.seek(0) --- 16,22 ---- class cPicklePicklerTests(AbstractPickleTests): ! def dumps(self, arg, proto=0): f = StringIO() ! p = cPickle.Pickler(f, proto) p.dump(arg) f.seek(0) *************** *** 32,37 **** class cPickleListPicklerTests(AbstractPickleTests): ! def dumps(self, arg, bin=0): ! p = cPickle.Pickler(bin) p.dump(arg) return p.getvalue() --- 32,37 ---- class cPickleListPicklerTests(AbstractPickleTests): ! def dumps(self, arg, proto=0): ! p = cPickle.Pickler(proto) p.dump(arg) return p.getvalue() *************** *** 46,52 **** class cPickleFastPicklerTests(AbstractPickleTests): ! def dumps(self, arg, bin=0): f = StringIO() ! p = cPickle.Pickler(f, bin) p.fast = 1 p.dump(arg) --- 46,52 ---- class cPickleFastPicklerTests(AbstractPickleTests): ! def dumps(self, arg, proto=0): f = StringIO() ! p = cPickle.Pickler(f, proto) p.fast = 1 p.dump(arg) From gvanrossum@users.sourceforge.net Tue Jan 28 22:29:20 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 14:29:20 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.117,1.118 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv4374 Modified Files: pickle.py Log Message: Get rid of __safe_for_unpickling__ and safe_constructors. Also tidied up a few lines, got rid of apply(), added a comment. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.117 retrieving revision 1.118 diff -C2 -d -r1.117 -r1.118 *** pickle.py 28 Jan 2003 22:01:16 -0000 1.117 --- pickle.py 28 Jan 2003 22:29:13 -0000 1.118 *************** *** 28,32 **** from types import * ! from copy_reg import dispatch_table, safe_constructors, _reconstructor import marshal import sys --- 28,32 ---- from types import * ! from copy_reg import dispatch_table, _reconstructor import marshal import sys *************** *** 376,381 **** args = getnewargs() # This bette not reference obj else: ! for cls in int, long, float, complex, str, unicode, tuple: ! if isinstance(obj, cls): args = (cls(obj),) break --- 376,381 ---- args = getnewargs() # This bette not reference obj else: ! for cls in int, long, float, complex, str, UnicodeType, tuple: ! if cls and isinstance(obj, cls): args = (cls(obj),) break *************** *** 1031,1038 **** if not instantiated: try: ! if not hasattr(klass, '__safe_for_unpickling__'): ! raise UnpicklingError('%s is not safe for unpickling' % ! klass) ! value = apply(klass, args) except TypeError, err: raise TypeError, "in constructor for %s: %s" % ( --- 1031,1035 ---- if not instantiated: try: ! value = klass(*args) except TypeError, err: raise TypeError, "in constructor for %s: %s" % ( *************** *** 1060,1064 **** pass if not instantiated: ! value = apply(klass, args) self.append(value) dispatch[OBJ] = load_obj --- 1057,1061 ---- pass if not instantiated: ! value = klass(*args) self.append(value) dispatch[OBJ] = load_obj *************** *** 1079,1082 **** --- 1076,1080 ---- def find_class(self, module, name): + # Subclasses may override this __import__(module) mod = sys.modules[module] *************** *** 1086,1113 **** def load_reduce(self): stack = self.stack ! ! callable = stack[-2] ! arg_tup = stack[-1] ! del stack[-2:] ! ! if type(callable) is not ClassType: ! if not callable in safe_constructors: ! try: ! safe = callable.__safe_for_unpickling__ ! except AttributeError: ! safe = None ! ! if not safe: ! raise UnpicklingError, "%s is not safe for " \ ! "unpickling" % callable ! ! if arg_tup is None: # A hack for Jim Fulton's ExtensionClass, now deprecated warnings.warn("__basicnew__ special case is deprecated", DeprecationWarning) ! value = callable.__basicnew__() else: ! value = apply(callable, arg_tup) ! self.append(value) dispatch[REDUCE] = load_reduce --- 1084,1097 ---- def load_reduce(self): stack = self.stack ! args = stack.pop() ! func = stack[-1] ! if args is None: # A hack for Jim Fulton's ExtensionClass, now deprecated warnings.warn("__basicnew__ special case is deprecated", DeprecationWarning) ! value = func.__basicnew__() else: ! value = func(*args) ! stack[-1] = value dispatch[REDUCE] = load_reduce From gvanrossum@users.sourceforge.net Tue Jan 28 22:31:29 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 14:31:29 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.118,1.119 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5335 Modified Files: pickle.py Log Message: Add a comment about how some built-in types should grow a __getnewargs__ method. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.118 retrieving revision 1.119 diff -C2 -d -r1.118 -r1.119 *** pickle.py 28 Jan 2003 22:29:13 -0000 1.118 --- pickle.py 28 Jan 2003 22:31:25 -0000 1.119 *************** *** 369,373 **** def save_newobj(self, obj): # Save a new-style class instance, using protocol 2. ! # XXX Much of this is still experimental. assert self.proto >= 2 # This only works for protocol 2 t = type(obj) --- 369,373 ---- def save_newobj(self, obj): # Save a new-style class instance, using protocol 2. ! # XXX This is still experimental. assert self.proto >= 2 # This only works for protocol 2 t = type(obj) *************** *** 376,379 **** --- 376,381 ---- args = getnewargs() # This bette not reference obj else: + # XXX These types should each grow a __getnewargs__ + # implementation so this special-casing is unnecessary. for cls in int, long, float, complex, str, UnicodeType, tuple: if cls and isinstance(obj, cls): From tim_one@users.sourceforge.net Tue Jan 28 22:34:15 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 14:34:15 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.27,1.28 test_pickle.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv5801/Lib/test Modified Files: pickletester.py test_pickle.py Log Message: Temporary hacks to arrange that the pickle tests relying on protocol 2 only get run by test_pickle.py now (& not by test_cpickle.py). This should be undone when protocol 2 is implemented in cPickle too. test_cpickle should pass again. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** pickletester.py 28 Jan 2003 22:02:31 -0000 1.27 --- pickletester.py 28 Jan 2003 22:34:08 -0000 1.28 *************** *** 325,328 **** --- 325,334 ---- ## pickletools.dis(s) + # XXX Temporary hack, so long as the C implementation of pickle protocol + # XXX 2 isn't ready. When it is, move the methods in TempAbstractPickleTests + # XXX into AbstractPickleTests above, and get rid of TempAbstractPickleTests + # XXX along with the references to it in test_pickle.py. + class TempAbstractPickleTests(unittest.TestCase): + def test_newobj_list_slots(self): x = SlotList([1, 2, 3]) Index: test_pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pickle.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_pickle.py 28 Jan 2003 03:51:53 -0000 1.13 --- test_pickle.py 28 Jan 2003 22:34:11 -0000 1.14 *************** *** 2,10 **** import unittest from cStringIO import StringIO ! from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests, \ ! AbstractPersistentPicklerTests from test import test_support ! class PickleTests(AbstractPickleTests, AbstractPickleModuleTests): def setUp(self): --- 2,14 ---- import unittest from cStringIO import StringIO ! from test import test_support ! from test.pickletester import AbstractPickleTests ! from test.pickletester import TempAbstractPickleTests as XXXTemp ! from test.pickletester import AbstractPickleModuleTests ! from test.pickletester import AbstractPersistentPicklerTests ! ! class PickleTests(AbstractPickleTests, AbstractPickleModuleTests, XXXTemp): def setUp(self): From jackjansen@users.sourceforge.net Tue Jan 28 23:29:48 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 28 Jan 2003 15:29:48 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/file _Filemodule.c,1.15,1.16 filesupport.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/file In directory sc8-pr-cvs1:/tmp/cvs-serv28498 Modified Files: _Filemodule.c filesupport.py Log Message: Added a missing INCREF in pathname(). Index: _Filemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/_Filemodule.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** _Filemodule.c 26 Jan 2003 20:22:40 -0000 1.15 --- _Filemodule.c 28 Jan 2003 23:29:46 -0000 1.16 *************** *** 3027,3032 **** if (!PyArg_ParseTuple(_args, "O", &obj)) return NULL; ! if (PyString_Check(obj)) return obj; if (PyUnicode_Check(obj)) return PyUnicode_AsEncodedString(obj, "utf8", "strict"); --- 3027,3034 ---- if (!PyArg_ParseTuple(_args, "O", &obj)) return NULL; ! if (PyString_Check(obj)) { ! Py_INCREF(obj); return obj; + } if (PyUnicode_Check(obj)) return PyUnicode_AsEncodedString(obj, "utf8", "strict"); Index: filesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filesupport.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** filesupport.py 26 Jan 2003 20:22:41 -0000 1.14 --- filesupport.py 28 Jan 2003 23:29:46 -0000 1.15 *************** *** 875,880 **** if (!PyArg_ParseTuple(_args, "O", &obj)) return NULL; ! if (PyString_Check(obj)) return obj; if (PyUnicode_Check(obj)) return PyUnicode_AsEncodedString(obj, "utf8", "strict"); --- 875,882 ---- if (!PyArg_ParseTuple(_args, "O", &obj)) return NULL; ! if (PyString_Check(obj)) { ! Py_INCREF(obj); return obj; + } if (PyUnicode_Check(obj)) return PyUnicode_AsEncodedString(obj, "utf8", "strict"); From jackjansen@users.sourceforge.net Tue Jan 28 23:53:42 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 28 Jan 2003 15:53:42 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macostools.py,1.1,1.2 aepack.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv4263 Modified Files: macostools.py aepack.py Log Message: Converted to not use macfs whenever possible. Index: macostools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macostools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** macostools.py 30 Dec 2002 22:04:20 -0000 1.1 --- macostools.py 28 Jan 2003 23:53:40 -0000 1.2 *************** *** 5,23 **** """ - import macfs from Carbon import Res import os ! from MACFS import * import MacOS import time try: ! openrf = MacOS.openrf except AttributeError: ! # Backward compatability ! openrf = open Error = 'macostools.Error' ! BUFSIZ=0x80000 # Copy in 0.5Mb chunks # --- 5,26 ---- """ from Carbon import Res + from Carbon import File, Files import os ! import sys import MacOS import time try: ! openrf = MacOS.openrf except AttributeError: ! # Backward compatability ! openrf = open Error = 'macostools.Error' ! BUFSIZ=0x80000 # Copy in 0.5Mb chunks ! ! COPY_FLAGS = (Files.kIsStationary|Files.kNameLocked|Files.kHasBundle| ! Files.kIsInvisible|Files.kIsAlias) # *************** *** 26,137 **** # def mkalias(src, dst, relative=None): ! """Create a finder alias""" ! srcfss = macfs.FSSpec(src) ! # The next line will fail under unix-Python if the destination ! # doesn't exist yet. We should change this code to be fsref-based. ! dstfss = macfs.FSSpec(dst) ! if relative: ! relativefss = macfs.FSSpec(relative) ! # ik mag er geen None in stoppen :-( ! alias = srcfss.NewAlias(relativefss) ! else: ! alias = srcfss.NewAlias() ! ! if os.path.isdir(src): ! cr, tp = 'MACS', 'fdrp' ! else: ! cr, tp = srcfss.GetCreatorType() ! ! Res.FSpCreateResFile(dstfss, cr, tp, -1) ! h = Res.FSpOpenResFile(dstfss, 3) ! resource = Res.Resource(alias.data) ! resource.AddResource('alis', 0, '') ! Res.CloseResFile(h) ! ! dstfinfo = dstfss.GetFInfo() ! dstfinfo.Flags = dstfinfo.Flags|0x8000 # Alias flag ! dstfss.SetFInfo(dstfinfo) ! def mkdirs(dst): ! """Make directories leading to 'dst' if they don't exist yet""" ! if dst == '' or os.path.exists(dst): ! return ! head, tail = os.path.split(dst) ! if os.sep == ':' and not ':' in head: ! head = head + ':' ! mkdirs(head) ! os.mkdir(dst, 0777) ! def touched(dst): ! """Tell the finder a file has changed""" ! file_fss = macfs.FSSpec(dst) ! vRefNum, dirID, name = file_fss.as_tuple() ! dir_fss = macfs.FSSpec((vRefNum, dirID, '')) ! crdate, moddate, bkdate = dir_fss.GetDates() ! now = time.time() ! if now == moddate: ! now = now + 1 ! try: ! dir_fss.SetDates(crdate, now, bkdate) ! except macfs.error: ! pass ! def touched_ae(dst): ! """Tell the finder a file has changed""" ! import Finder ! f = Finder.Finder() ! file_fss = macfs.FSSpec(dst) ! vRefNum, dirID, name = file_fss.as_tuple() ! dir_fss = macfs.FSSpec((vRefNum, dirID, '')) ! f.update(dir_fss) ! def copy(src, dst, createpath=0, copydates=1, forcetype=None): ! """Copy a file, including finder info, resource fork, etc""" ! if hasattr(src, 'as_pathname'): ! src = src.as_pathname() ! if hasattr(dst, 'as_pathname'): ! dst = dst.as_pathname() ! if createpath: ! mkdirs(os.path.split(dst)[0]) ! ! ifp = open(src, 'rb') ! ofp = open(dst, 'wb') ! d = ifp.read(BUFSIZ) ! while d: ! ofp.write(d) ! d = ifp.read(BUFSIZ) ! ifp.close() ! ofp.close() ! ! ifp = openrf(src, '*rb') ! ofp = openrf(dst, '*wb') ! d = ifp.read(BUFSIZ) ! while d: ! ofp.write(d) ! d = ifp.read(BUFSIZ) ! ifp.close() ! ofp.close() ! ! srcfss = macfs.FSSpec(src) ! dstfss = macfs.FSSpec(dst) ! sf = srcfss.GetFInfo() ! df = dstfss.GetFInfo() ! df.Creator, df.Type = sf.Creator, sf.Type ! if forcetype != None: ! df.Type = forcetype ! df.Flags = (sf.Flags & (kIsStationary|kNameLocked|kHasBundle|kIsInvisible|kIsAlias)) ! dstfss.SetFInfo(df) ! if copydates: ! crdate, mddate, bkdate = srcfss.GetDates() ! dstfss.SetDates(crdate, mddate, bkdate) ! touched(dstfss) ! def copytree(src, dst, copydates=1): ! """Copy a complete file tree to a new destination""" ! if os.path.isdir(src): ! mkdirs(dst) ! files = os.listdir(src) ! for f in files: ! copytree(os.path.join(src, f), os.path.join(dst, f), copydates) ! else: ! copy(src, dst, 1, copydates) --- 29,140 ---- # def mkalias(src, dst, relative=None): ! """Create a finder alias""" ! srcfsr = File.FSRef(src) ! # The next line will fail under unix-Python if the destination ! # doesn't exist yet. We should change this code to be fsref-based. ! dstdir, dstname = os.path.split(dst) ! if not dstdir: dstdir = os.curdir ! dstdirfsr = File.FSRef(dstdir) ! if relative: ! relativefsr = File.FSRef(relative) ! # ik mag er geen None in stoppen :-( ! alias = File.FSNewAlias(relativefsr, srcfsr) ! else: ! alias = srcfsr.FSNewAliasMinimal() ! ! dstfsr, dstfss = Res.FSCreateResourceFile(dstdirfsr, unicode(dstname), ! File.FSGetResourceForkName()) ! h = Res.FSOpenResourceFile(dstfsr, File.FSGetResourceForkName(), 3) ! resource = Res.Resource(alias.data) ! resource.AddResource('alis', 0, '') ! Res.CloseResFile(h) ! ! dstfinfo = dstfss.FSpGetFInfo() ! dstfinfo.Flags = dstfinfo.Flags|0x8000 # Alias flag ! dstfss.FSpSetFInfo(dstfinfo) ! def mkdirs(dst): ! """Make directories leading to 'dst' if they don't exist yet""" ! if dst == '' or os.path.exists(dst): ! return ! head, tail = os.path.split(dst) ! if os.sep == ':' and not ':' in head: ! head = head + ':' ! mkdirs(head) ! os.mkdir(dst, 0777) ! def touched(dst): ! """Tell the finder a file has changed. No-op on MacOSX.""" ! if sys.platform != 'mac': return ! import macfs ! file_fss = macfs.FSSpec(dst) ! vRefNum, dirID, name = file_fss.as_tuple() ! dir_fss = macfs.FSSpec((vRefNum, dirID, '')) ! crdate, moddate, bkdate = dir_fss.GetDates() ! now = time.time() ! if now == moddate: ! now = now + 1 ! try: ! dir_fss.SetDates(crdate, now, bkdate) ! except macfs.error: ! pass ! def touched_ae(dst): ! """Tell the finder a file has changed""" ! pardir = os.path.split(dst)[0] ! if not pardir: ! pardir = os.curdir ! import Finder ! f = Finder.Finder() ! f.update(File.FSRef(pardir)) ! def copy(src, dst, createpath=0, copydates=1, forcetype=None): ! """Copy a file, including finder info, resource fork, etc""" ! src = File.pathname(src) ! dst = File.pathname(dst) ! if createpath: ! mkdirs(os.path.split(dst)[0]) ! ! ifp = open(src, 'rb') ! ofp = open(dst, 'wb') ! d = ifp.read(BUFSIZ) ! while d: ! ofp.write(d) ! d = ifp.read(BUFSIZ) ! ifp.close() ! ofp.close() ! ! ifp = openrf(src, '*rb') ! ofp = openrf(dst, '*wb') ! d = ifp.read(BUFSIZ) ! while d: ! ofp.write(d) ! d = ifp.read(BUFSIZ) ! ifp.close() ! ofp.close() ! ! srcfss = File.FSSpec(src) ! dstfss = File.FSSpec(dst) ! sf = srcfss.FSpGetFInfo() ! df = dstfss.FSpGetFInfo() ! df.Creator, df.Type = sf.Creator, sf.Type ! if forcetype != None: ! df.Type = forcetype ! df.Flags = (sf.Flags & COPY_FLAGS) ! dstfss.FSpSetFInfo(df) ! if copydates: ! srcfsr = File.FSRef(src) ! dstfsr = File.FSRef(dst) ! catinfo, _, _, _ = srcfsr.FSGetCatalogInfo(Files.kFSCatInfoAllDates) ! dstfsr.FSSetCatalogInfo(Files.kFSCatInfoAllDates, catinfo) ! touched(dstfss) ! def copytree(src, dst, copydates=1): ! """Copy a complete file tree to a new destination""" ! if os.path.isdir(src): ! mkdirs(dst) ! files = os.listdir(src) ! for f in files: ! copytree(os.path.join(src, f), os.path.join(dst, f), copydates) ! else: ! copy(src, dst, 1, copydates) Index: aepack.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/aepack.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** aepack.py 30 Dec 2002 22:04:20 -0000 1.1 --- aepack.py 28 Jan 2003 23:53:40 -0000 1.2 *************** *** 21,25 **** from Carbon.AppleEvents import * import MacOS ! import macfs import StringIO import aetypes --- 21,25 ---- from Carbon.AppleEvents import * import MacOS ! import Carbon.File import StringIO import aetypes *************** *** 60,65 **** # AEDescType = AE.AEDescType ! FSSType = macfs.FSSpecType ! AliasType = macfs.AliasType def packkey(ae, key, value): --- 60,66 ---- # AEDescType = AE.AEDescType ! FSSType = Carbon.File.FSSpecType ! FSRefType = Carbon.File.FSRefType ! AliasType = Carbon.File.AliasType def packkey(ae, key, value): *************** *** 84,111 **** return AE.AECreateDesc('null', '') ! t = type(x) ! if t == AEDescType: return x ! if t == FSSType: return AE.AECreateDesc('fss ', x.data) ! if t == AliasType: return AE.AECreateDesc('alis', x.data) ! if t == IntType: return AE.AECreateDesc('long', struct.pack('l', x)) ! if t == FloatType: return AE.AECreateDesc('doub', struct.pack('d', x)) ! if t == StringType: return AE.AECreateDesc('TEXT', x) ! if t == UnicodeType: data = t.encode('utf16') if data[:2] == '\xfe\xff': data = data[2:] return AE.AECreateDesc('utxt', data) ! if t == ListType: list = AE.AECreateList('', 0) for item in x: list.AEPutDesc(0, pack(item)) return list ! if t == DictionaryType: record = AE.AECreateList('', 1) for key, value in x.items(): --- 85,111 ---- return AE.AECreateDesc('null', '') ! if isinstance(x, AEDescType): return x ! if isinstance(x, FSSType): return AE.AECreateDesc('fss ', x.data) ! if isinstance(x, AliasType): return AE.AECreateDesc('alis', x.data) ! if isinstance(x, IntType): return AE.AECreateDesc('long', struct.pack('l', x)) ! if isinstance(x, FloatType): return AE.AECreateDesc('doub', struct.pack('d', x)) ! if isinstance(x, StringType): return AE.AECreateDesc('TEXT', x) ! if isinstance(x, UnicodeType): data = t.encode('utf16') if data[:2] == '\xfe\xff': data = data[2:] return AE.AECreateDesc('utxt', data) ! if isinstance(x, ListType): list = AE.AECreateList('', 0) for item in x: list.AEPutDesc(0, pack(item)) return list ! if isinstance(x, DictionaryType): record = AE.AECreateList('', 1) for key, value in x.items(): *************** *** 113,117 **** #record.AEPutParamDesc(key, pack(value)) return record ! if t == InstanceType and hasattr(x, '__aepack__'): return x.__aepack__() if hasattr(x, 'which'): --- 113,117 ---- #record.AEPutParamDesc(key, pack(value)) return record ! if hasattr(x, '__aepack__'): return x.__aepack__() if hasattr(x, 'which'): *************** *** 145,149 **** return mkaetext(unpack(record, formodulename)) if t == typeAlias: ! return macfs.RawAlias(desc.data) # typeAppleEvent returned as unknown if t == typeBoolean: --- 145,149 ---- return mkaetext(unpack(record, formodulename)) if t == typeAlias: ! return Carbon.File.Alias(rawdata=desc.data) # typeAppleEvent returned as unknown if t == typeBoolean: *************** *** 166,170 **** return struct.unpack('d', data)[0] if t == typeFSS: ! return macfs.RawFSSpec(desc.data) if t == typeInsertionLoc: record = desc.AECoerceDesc('reco') --- 166,170 ---- return struct.unpack('d', data)[0] if t == typeFSS: ! return Carbon.File.FSSpec(rawdata=desc.data) if t == typeInsertionLoc: record = desc.AECoerceDesc('reco') *************** *** 354,359 **** ['a', 'list', 'of', 'strings'], {'key1': 'value1', 'key2':'value2'}, ! macfs.FSSpec(':'), ! macfs.FSSpec(':').NewAliasMinimal(), aetypes.Enum('enum'), aetypes.Type('type'), --- 354,359 ---- ['a', 'list', 'of', 'strings'], {'key1': 'value1', 'key2':'value2'}, ! Carbon.File.FSSpec(os.curdir), ! Carbon.File.FSSpec(os.curdir).NewAliasMinimal(), aetypes.Enum('enum'), aetypes.Type('type'), From jackjansen@users.sourceforge.net Tue Jan 28 23:54:07 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 28 Jan 2003 15:54:07 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_macostools.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv4493 Modified Files: test_macostools.py Log Message: Test aliases too. Index: test_macostools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_macostools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_macostools.py 28 Jan 2003 21:39:28 -0000 1.1 --- test_macostools.py 28 Jan 2003 23:54:05 -0000 1.2 *************** *** 3,9 **** import unittest import macostools import MacOS import os ! import tempfile from test import test_support --- 3,10 ---- import unittest import macostools + import macfs import MacOS import os ! import sys from test import test_support *************** *** 60,63 **** --- 61,82 ---- macostools.copy(test_support.TESTFN, TESTFN2) self.assertEqual(self.compareData(), '') + + def test_mkalias(self): + try: + os.unlink(TESTFN2) + except: + pass + macostools.mkalias(test_support.TESTFN, TESTFN2) + fss, _, _ = macfs.ResolveAliasFile(TESTFN2) + self.assertEqual(fss.as_pathname(), os.path.abspath(test_support.TESTFN)) + + def test_mkalias_relative(self): + try: + os.unlink(TESTFN2) + except: + pass + macostools.mkalias(test_support.TESTFN, TESTFN2, sys.prefix) + fss, _, _ = macfs.ResolveAliasFile(TESTFN2) + self.assertEqual(fss.as_pathname(), os.path.abspath(test_support.TESTFN)) From tim_one@users.sourceforge.net Wed Jan 29 00:35:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 16:35:34 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.118,1.119 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv21246/Lib/test Modified Files: regrtest.py Log Message: Expect test_macostools and test_macfs to get skipped whenever sys.platform != mac. Likewise expect test_win{reg,sound} to get skipped on non-win32 platforms. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.118 retrieving revision 1.119 diff -C2 -d -r1.118 -r1.119 *** regrtest.py 27 Jan 2003 16:45:03 -0000 1.118 --- regrtest.py 29 Jan 2003 00:35:32 -0000 1.119 *************** *** 591,596 **** test_sunaudiodev test_unicode_file - test_winreg - test_winsound """, 'mac': --- 591,594 ---- *************** *** 636,641 **** test_timing test_unicode_file - test_winreg - test_winsound """, 'unixware7': --- 634,637 ---- *************** *** 660,665 **** test_sundry test_unicode_file - test_winreg - test_winsound """, 'openunix8': --- 656,659 ---- *************** *** 684,689 **** test_sundry test_unicode_file - test_winreg - test_winsound """, 'sco_sv3': --- 678,681 ---- *************** *** 717,722 **** test_threading test_unicode_file - test_winreg - test_winsound """, 'riscos': --- 709,712 ---- *************** *** 758,763 **** test_timing test_unicode_file - test_winreg - test_winsound """, 'darwin': --- 748,751 ---- *************** *** 786,791 **** test_sunaudiodev test_unicode_file - test_winreg - test_winsound """, 'sunos5': --- 774,777 ---- *************** *** 806,811 **** test_openpty test_socketserver - test_winreg - test_winsound test_zipfile test_zlib --- 792,795 ---- *************** *** 835,840 **** test_sunaudiodev test_unicode_file - test_winreg - test_winsound test_zipfile test_zlib --- 819,822 ---- *************** *** 864,869 **** test_sunaudiodev test_unicode_file - test_winreg - test_winsound """, 'cygwin': --- 846,849 ---- *************** *** 886,891 **** test_sunaudiodev test_unicode_file - test_winreg - test_winsound """, 'os2emx': --- 866,869 ---- *************** *** 915,920 **** test_sunaudiodev test_unicode_file - test_winreg - test_winsound """, } --- 893,896 ---- *************** *** 940,943 **** --- 916,927 ---- self.expected.add('test_socket_ssl') + if sys.platform != "mac": + self.expected.add("test_macostools") + self.expected.add("test_macfs") + + if sys.platform != "win32": + self.expected.add("test_winreg") + self.expected.add("test_winsound") + self.valid = True From tim_one@users.sourceforge.net Wed Jan 29 00:38:46 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 16:38:46 -0800 Subject: [Python-checkins] python/dist/src/PCbuild readme.txt,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory sc8-pr-cvs1:/tmp/cvs-serv22335/PCbuild Modified Files: readme.txt Log Message: Updated info about test_bsddb3 failures. Index: readme.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/readme.txt,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** readme.txt 24 Jan 2003 15:31:31 -0000 1.39 --- readme.txt 29 Jan 2003 00:38:42 -0000 1.40 *************** *** 223,226 **** --- 223,230 ---- XXX DBLockDeadlockError: (-30996, 'DB_LOCK_DEADLOCK: Locker killed XXX to resolve a deadlock') + XXX + XXX I'm told that DBLockDeadlockError is expected at times. It + XXX doesn't cause a test to fail when it happens (exceptions in + XXX threads are invisible to unittest). From tim_one@users.sourceforge.net Wed Jan 29 00:56:19 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 16:56:19 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.119,1.120 pickletools.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28373/Lib Modified Files: pickle.py pickletools.py Log Message: pickle: Comment repair. pickletools: Import decode_long from pickle instead of duplicating it. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.119 retrieving revision 1.120 diff -C2 -d -r1.119 -r1.120 *** pickle.py 28 Jan 2003 22:31:25 -0000 1.119 --- pickle.py 29 Jan 2003 00:56:17 -0000 1.120 *************** *** 38,42 **** "Unpickler", "dump", "dumps", "load", "loads"] ! # These are purely informational; no code usues these format_version = "2.0" # File format version we write compatible_formats = ["1.0", # Original protocol 0 --- 38,42 ---- "Unpickler", "dump", "dumps", "load", "loads"] ! # These are purely informational; no code uses these. format_version = "2.0" # File format version we write compatible_formats = ["1.0", # Original protocol 0 *************** *** 48,52 **** # Why use struct.pack() for pickling but marshal.loads() for ! # unpickling? struct.pack() is 40% faster than marshal.loads(), but # marshal.loads() is twice as fast as struct.unpack()! mloads = marshal.loads --- 48,52 ---- # Why use struct.pack() for pickling but marshal.loads() for ! # unpickling? struct.pack() is 40% faster than marshal.dumps(), but # marshal.loads() is twice as fast as struct.unpack()! mloads = marshal.loads *************** *** 74,77 **** --- 74,79 ---- pass + # An instance of _Stop is raised by Unpickler.load_stop() in response to + # the STOP opcode, passing the object that is the result of unpickling. class _Stop(Exception): def __init__(self, value): *************** *** 139,143 **** FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py ! # Protocol 2 (not yet implemented). PROTO = '\x80' # identify pickle protocol --- 141,145 ---- FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py ! # Protocol 2 (XXX not yet implemented). PROTO = '\x80' # identify pickle protocol *************** *** 773,776 **** --- 775,781 ---- + # A cache for whichmodule(), mapping a function object to the name of + # the module in which the function was found. + classmap = {} # called classmap for backwards compatibility *************** *** 781,785 **** Cache in classmap. Return a module name. ! If the function cannot be found, return __main__. """ if func in classmap: --- 786,790 ---- Cache in classmap. Return a module name. ! If the function cannot be found, return "__main__". """ if func in classmap: Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** pickletools.py 28 Jan 2003 16:01:25 -0000 1.17 --- pickletools.py 29 Jan 2003 00:56:17 -0000 1.18 *************** *** 604,630 **** # Protocol 2 formats ! def decode_long(data): ! r"""Decode a long from a two's complement little-endian binary string. ! >>> decode_long("\xff\x00") ! 255L ! >>> decode_long("\xff\x7f") ! 32767L ! >>> decode_long("\x00\xff") ! -256L ! >>> decode_long("\x00\x80") ! -32768L ! >>> decode_long("\x80") ! -128L ! >>> decode_long("\x7f") ! 127L ! """ ! x = 0L ! i = 0L ! for c in data: ! x |= long(ord(c)) << i ! i += 8L ! if data and ord(c) >= 0x80: ! x -= 1L << i ! return x def read_long1(f): --- 604,608 ---- # Protocol 2 formats ! from pickle import decode_long def read_long1(f): *************** *** 1794,1797 **** --- 1772,1776 ---- assure_pickle_consistency() + del assure_pickle_consistency ############################################################################## From rhettinger@users.sourceforge.net Wed Jan 29 01:52:06 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 28 Jan 2003 17:52:06 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.13,1.14 test_itertools.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv14741 Modified Files: libitertools.tex test_itertools.py Log Message: More and improved examples Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** libitertools.tex 28 Jan 2003 02:02:25 -0000 1.13 --- libitertools.tex 29 Jan 2003 01:52:04 -0000 1.14 *************** *** 265,291 **** >>> import operator ! >>> bases = [2, 3, 5, 7] ! >>> powers = [2, 3, 4] ! >>> for power in powers: ! ... print list(imap(operator.pow, bases, repeat(power))) ... ! [4, 9, 25, 49] ! [8, 27, 125, 343] ! [16, 81, 625, 2401] \end{verbatim} As a further example of how itertools can be combined, here ! are a few re-definitions of existing tools: \begin{verbatim} ! >>> def enumerate(s): ! ... return izip(count(), s) ! >>> def tabulate(f): ! ... return imap(f, count()) ! >>> def iteritems(d): ! ... return izip(d.iterkeys(), d.itervalues()) ! >>> def nth(s, n): ! ... return islice(n, n+1).next() \end{verbatim} --- 265,305 ---- >>> import operator ! >>> for cube in imap(operator.pow, xrange(1,4), repeat(3)): ! ... print cube ... ! 1 ! 8 ! 27 ! ! >>> reportfile = ['EuroPython', 'Roster', '', 'alex', '', 'laura', ! '', 'martin', '', 'walter', '', 'samuele'] ! >>> for name in islice(reportfile, 3, len(reportfile), 2): ! ... print name.title() ! ... ! Alex ! Laura ! Martin ! Walter ! Samuele \end{verbatim} As a further example of how itertools can be combined, here ! are a few ways to define higher level tools: \begin{verbatim} ! >>> def enumerate(iterable): ! ... return izip(count(), iterable) ! ! >>> def tabulate(function): ! ... "Return function(0), function(1), ..." ! ... return imap(function, count()) ! ! >>> def iteritems(mapping): ! ... return izip(mapping.iterkeys(), mapping.itervalues()) ! ! >>> def nth(iterable, n): ! ... "Returns the nth item" ! ... return islice(iterable, n, n+1).next() \end{verbatim} Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_itertools.py 28 Jan 2003 02:02:26 -0000 1.9 --- test_itertools.py 29 Jan 2003 01:52:04 -0000 1.10 *************** *** 100,122 **** >>> import operator ! >>> bases = [2, 3, 5, 7] ! >>> powers = [2, 3, 4] ! >>> for power in powers: ! ... print list(imap(operator.pow, bases, repeat(power))) ... ! [4, 9, 25, 49] ! [8, 27, 125, 343] ! [16, 81, 625, 2401] ! >>> def enumerate(s): ! ... return izip(count(), s) ! >>> def tabulate(f): ! ... return imap(f, count()) ! >>> def iteritems(d): ! ... return izip(d.iterkeys(), d.itervalues()) ! >>> def nth(s, n): ! ... return islice(n, n+1).next() """ --- 100,134 ---- >>> import operator ! >>> import operator ! >>> for cube in imap(operator.pow, xrange(1,4), repeat(3)): ! ... print cube ... ! 1 ! 8 ! 27 ! ! >>> reportfile = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] ! >>> for name in islice(reportfile, 3, len(reportfile), 2): ! ... print name.title() ! ... ! Alex ! Laura ! Martin ! Walter ! Samuele + >>> def enumerate(iterable): + ... return izip(count(), iterable) ! >>> def tabulate(function): ! ... "Return function(0), function(1), ..." ! ... return imap(function, count()) ! ! >>> def iteritems(mapping): ! ... return izip(mapping.iterkeys(), mapping.itervalues()) + >>> def nth(iterable, n): + ... "Returns the nth item" + ... return islice(iterable, n, n+1).next() """ From tim_one@users.sourceforge.net Wed Jan 29 03:49:45 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 19:49:45 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.138,1.139 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv16331 Modified Files: setup.py Log Message: Whitespace normalization. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.138 retrieving revision 1.139 diff -C2 -d -r1.138 -r1.139 *** setup.py 26 Jan 2003 11:27:16 -0000 1.138 --- setup.py 29 Jan 2003 03:49:42 -0000 1.139 *************** *** 75,79 **** else: assert False, "Internal error: Path not found in std_dirs or paths" ! def module_enabled(extlist, modname): """Returns whether the module 'modname' is present in the list --- 75,79 ---- else: assert False, "Internal error: Path not found in std_dirs or paths" ! def module_enabled(extlist, modname): """Returns whether the module 'modname' is present in the list *************** *** 160,164 **** remove_modules.append( line[0] ) input.close() ! for ext in self.extensions[:]: if ext.name in remove_modules: --- 160,164 ---- remove_modules.append( line[0] ) input.close() ! for ext in self.extensions[:]: if ext.name in remove_modules: *************** *** 324,328 **** libraries=math_libs) ) # random number generator implemented in C ! exts.append( Extension("_random", ["_randommodule.c"]) ) # operator.add() and similar goodies exts.append( Extension('operator', ['operator.c']) ) --- 324,328 ---- libraries=math_libs) ) # random number generator implemented in C ! exts.append( Extension("_random", ["_randommodule.c"]) ) # operator.add() and similar goodies exts.append( Extension('operator', ['operator.c']) ) *************** *** 348,354 **** if platform not in ['mac']: # pwd(3) ! exts.append( Extension('pwd', ['pwdmodule.c']) ) ! # grp(3) ! exts.append( Extension('grp', ['grpmodule.c']) ) # select(2); not on ancient System V exts.append( Extension('select', ['selectmodule.c']) ) --- 348,354 ---- if platform not in ['mac']: # pwd(3) ! exts.append( Extension('pwd', ['pwdmodule.c']) ) ! # grp(3) ! exts.append( Extension('grp', ['grpmodule.c']) ) # select(2); not on ancient System V exts.append( Extension('select', ['selectmodule.c']) ) *************** *** 381,386 **** exts.append( Extension('rotor', ['rotormodule.c']) ) if platform not in ['mac']: ! # syslog daemon interface ! exts.append( Extension('syslog', ['syslogmodule.c']) ) # George Neville-Neil's timing module: --- 381,386 ---- exts.append( Extension('rotor', ['rotormodule.c']) ) if platform not in ['mac']: ! # syslog daemon interface ! exts.append( Extension('syslog', ['syslogmodule.c']) ) # George Neville-Neil's timing module: *************** *** 420,429 **** if platform not in ['mac']: # crypt module. ! ! if self.compiler.find_library_file(lib_dirs, 'crypt'): ! libs = ['crypt'] ! else: ! libs = [] ! exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) ) # socket(2) --- 420,429 ---- if platform not in ['mac']: # crypt module. ! ! if self.compiler.find_library_file(lib_dirs, 'crypt'): ! libs = ['crypt'] ! else: ! libs = [] ! exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) ) # socket(2) *************** *** 502,506 **** db_search_order.sort() db_search_order.reverse() ! class found(Exception): pass try: --- 502,506 ---- db_search_order.sort() db_search_order.reverse() ! class found(Exception): pass try: *************** *** 603,607 **** exts.append( Extension('termios', ['termios.c']) ) # Jeremy Hylton's rlimit interface ! if platform not in ['atheos']: exts.append( Extension('resource', ['resource.c']) ) --- 603,607 ---- exts.append( Extension('termios', ['termios.c']) ) # Jeremy Hylton's rlimit interface ! if platform not in ['atheos']: exts.append( Extension('resource', ['resource.c']) ) *************** *** 626,630 **** else: iconv_libraries = [] # in libc ! exts.append( Extension('_iconv_codec', ['_iconv_codec.c'], --- 626,630 ---- else: iconv_libraries = [] # in libc ! exts.append( Extension('_iconv_codec', ['_iconv_codec.c'], *************** *** 727,731 **** ], include_dirs = [expatinc] ! )) # Dynamic loading module --- 727,731 ---- ], include_dirs = [expatinc] ! )) # Dynamic loading module *************** *** 822,826 **** # same folder as your python source tree. Or modify the # next few lines:-) ! waste_incs = find_file("WASTE.h", [], ['../'*n + 'waste/C_C++ Headers' for n in (0,1,2,3,4)]) waste_libs = find_library_file(self.compiler, "WASTE", [], --- 822,826 ---- # same folder as your python source tree. Or modify the # next few lines:-) ! waste_incs = find_file("WASTE.h", [], ['../'*n + 'waste/C_C++ Headers' for n in (0,1,2,3,4)]) waste_libs = find_library_file(self.compiler, "WASTE", [], *************** *** 830,834 **** exts.append( Extension('waste', ['waste/wastemodule.c'] + [ ! os.path.join(srcdir, d) for d in 'Mac/Wastemods/WEObjectHandlers.c', 'Mac/Wastemods/WETabHooks.c', --- 830,834 ---- exts.append( Extension('waste', ['waste/wastemodule.c'] + [ ! os.path.join(srcdir, d) for d in 'Mac/Wastemods/WEObjectHandlers.c', 'Mac/Wastemods/WETabHooks.c', *************** *** 853,858 **** from os.path import join, exists framework_dirs = [ ! '/System/Library/Frameworks/', ! '/Library/Frameworks', join(os.getenv('HOME'), '/Library/Frameworks') ] --- 853,858 ---- from os.path import join, exists framework_dirs = [ ! '/System/Library/Frameworks/', ! '/Library/Frameworks', join(os.getenv('HOME'), '/Library/Frameworks') ] *************** *** 862,868 **** # XXX distutils should support -F! for F in framework_dirs: ! # both Tcl.framework and Tk.framework should be present for fw in 'Tcl', 'Tk': ! if not exists(join(F, fw + '.framework')): break else: --- 862,868 ---- # XXX distutils should support -F! for F in framework_dirs: ! # both Tcl.framework and Tk.framework should be present for fw in 'Tcl', 'Tk': ! if not exists(join(F, fw + '.framework')): break else: *************** *** 874,889 **** # will now resume. return 0 ! # For 8.4a2, we must add -I options that point inside the Tcl and Tk # frameworks. In later release we should hopefully be able to pass ! # the -F option to gcc, which specifies a framework lookup path. # include_dirs = [ ! join(F, fw + '.framework', H) for fw in 'Tcl', 'Tk' for H in 'Headers', 'Versions/Current/PrivateHeaders' ] ! # For 8.4a2, the X11 headers are not included. Rather than include a # complicated search, this is a hard-coded path. It could bail out # if X11 libs are not found... --- 874,889 ---- # will now resume. return 0 ! # For 8.4a2, we must add -I options that point inside the Tcl and Tk # frameworks. In later release we should hopefully be able to pass ! # the -F option to gcc, which specifies a framework lookup path. # include_dirs = [ ! join(F, fw + '.framework', H) for fw in 'Tcl', 'Tk' for H in 'Headers', 'Versions/Current/PrivateHeaders' ] ! # For 8.4a2, the X11 headers are not included. Rather than include a # complicated search, this is a hard-coded path. It could bail out # if X11 libs are not found... *************** *** 901,905 **** return 1 ! def detect_tkinter(self, inc_dirs, lib_dirs): # The _tkinter module. --- 901,905 ---- return 1 ! def detect_tkinter(self, inc_dirs, lib_dirs): # The _tkinter module. *************** *** 911,915 **** if platform == 'darwin' and \ self.detect_tkinter_darwin(inc_dirs, lib_dirs): ! return # Set platform specific library prefix, if any --- 911,915 ---- if platform == 'darwin' and \ self.detect_tkinter_darwin(inc_dirs, lib_dirs): ! return # Set platform specific library prefix, if any From tim_one@users.sourceforge.net Wed Jan 29 03:49:46 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Tue, 28 Jan 2003 19:49:46 -0800 Subject: [Python-checkins] python/dist/src/Lib SimpleXMLRPCServer.py,1.3,1.4 _strptime.py,1.11,1.12 dummy_thread.py,1.1,1.2 macpath.py,1.44,1.45 modulefinder.py,1.2,1.3 os.py,1.65,1.66 pickletools.py,1.18,1.19 pty.py,1.13,1.14 py_compile.py,1.24,1.25 tarfile.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv16331/Lib Modified Files: SimpleXMLRPCServer.py _strptime.py dummy_thread.py macpath.py modulefinder.py os.py pickletools.py pty.py py_compile.py tarfile.py Log Message: Whitespace normalization. Index: SimpleXMLRPCServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SimpleXMLRPCServer.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** SimpleXMLRPCServer.py 15 Jan 2003 11:37:23 -0000 1.3 --- SimpleXMLRPCServer.py 29 Jan 2003 03:49:42 -0000 1.4 *************** *** 33,37 **** def pow(self, x, y): return pow(x, y) def add(self, x, y) : return x + y ! server = SimpleXMLRPCServer(("localhost", 8000)) server.register_introspection_functions() --- 33,37 ---- def pow(self, x, y): return pow(x, y) def add(self, x, y) : return x + y ! server = SimpleXMLRPCServer(("localhost", 8000)) server.register_introspection_functions() *************** *** 138,142 **** item must be hashable and the order of the items in the resulting list is not defined. ! """ u = {} for x in lst: --- 138,142 ---- item must be hashable and the order of the items in the resulting list is not defined. ! """ u = {} for x in lst: *************** *** 152,156 **** reason to instantiate this class directly. """ ! def __init__(self): self.funcs = {} --- 152,156 ---- reason to instantiate this class directly. """ ! def __init__(self): self.funcs = {} *************** *** 196,200 **** see http://xmlrpc.usefulinc.com/doc/reserved.html """ ! self.funcs.update({'system.listMethods' : self.system_listMethods, 'system.methodSignature' : self.system_methodSignature, --- 196,200 ---- see http://xmlrpc.usefulinc.com/doc/reserved.html """ ! self.funcs.update({'system.listMethods' : self.system_listMethods, 'system.methodSignature' : self.system_methodSignature, *************** *** 206,224 **** see http://www.xmlrpc.com/discuss/msgReader$1208""" ! self.funcs.update({'system.multicall' : self.system_multicall}) ! def _marshaled_dispatch(self, data, dispatch_method = None): """Dispatches an XML-RPC method from marshalled (XML) data. ! XML-RPC methods are dispatched from the marshalled (XML) data using the _dispatch method and the result is returned as marshalled data. For backwards compatibility, a dispatch ! function can be provided as an argument (see comment in SimpleXMLRPCRequestHandler.do_POST) but overriding the existing method through subclassing is the prefered means of changing method dispatch behavior. """ ! params, method = xmlrpclib.loads(data) --- 206,224 ---- see http://www.xmlrpc.com/discuss/msgReader$1208""" ! self.funcs.update({'system.multicall' : self.system_multicall}) ! def _marshaled_dispatch(self, data, dispatch_method = None): """Dispatches an XML-RPC method from marshalled (XML) data. ! XML-RPC methods are dispatched from the marshalled (XML) data using the _dispatch method and the result is returned as marshalled data. For backwards compatibility, a dispatch ! function can be provided as an argument (see comment in SimpleXMLRPCRequestHandler.do_POST) but overriding the existing method through subclassing is the prefered means of changing method dispatch behavior. """ ! params, method = xmlrpclib.loads(data) *************** *** 227,231 **** if dispatch_method is not None: response = dispatch_method(method, params) ! else: response = self._dispatch(method, params) # wrap response in a singleton tuple --- 227,231 ---- if dispatch_method is not None: response = dispatch_method(method, params) ! else: response = self._dispatch(method, params) # wrap response in a singleton tuple *************** *** 246,250 **** Returns a list of the methods supported by the server.""" ! methods = self.funcs.keys() if self.instance is not None: --- 246,250 ---- Returns a list of the methods supported by the server.""" ! methods = self.funcs.keys() if self.instance is not None: *************** *** 264,268 **** methods.sort() return methods ! def system_methodSignature(self, method_name): """system.methodSignature('add') => [double, int, int] --- 264,268 ---- methods.sort() return methods ! def system_methodSignature(self, method_name): """system.methodSignature('add') => [double, int, int] *************** *** 275,279 **** # See http://xmlrpc.usefulinc.com/doc/sysmethodsig.html ! return 'signatures not supported' --- 275,279 ---- # See http://xmlrpc.usefulinc.com/doc/sysmethodsig.html ! return 'signatures not supported' *************** *** 282,286 **** Returns a string containing documentation for the specified method.""" ! method = None if self.funcs.has_key(method_name): --- 282,286 ---- Returns a string containing documentation for the specified method.""" ! method = None if self.funcs.has_key(method_name): *************** *** 315,321 **** request. ! See http://www.xmlrpc.com/discuss/msgReader$1208 """ ! results = [] for call in call_list: --- 315,321 ---- request. ! See http://www.xmlrpc.com/discuss/msgReader$1208 """ ! results = [] for call in call_list: *************** *** 338,342 **** ) return results ! def _dispatch(self, method, params): """Dispatches the XML-RPC method. --- 338,342 ---- ) return results ! def _dispatch(self, method, params): """Dispatches the XML-RPC method. *************** *** 383,387 **** else: raise Exception('method "%s" is not supported' % method) ! class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): """Simple XML-RPC request handler class. --- 383,387 ---- else: raise Exception('method "%s" is not supported' % method) ! class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): """Simple XML-RPC request handler class. *************** *** 397,401 **** which are forwarded to the server's _dispatch method for handling. """ ! try: # get arguments --- 397,401 ---- which are forwarded to the server's _dispatch method for handling. """ ! try: # get arguments *************** *** 424,428 **** self.wfile.flush() self.connection.shutdown(1) ! def log_request(self, code='-', size='-'): """Selectively log an accepted request.""" --- 424,428 ---- self.wfile.flush() self.connection.shutdown(1) ! def log_request(self, code='-', size='-'): """Selectively log an accepted request.""" *************** *** 431,435 **** BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size) ! class SimpleXMLRPCServer(SocketServer.TCPServer, SimpleXMLRPCDispatcher): """Simple XML-RPC server. --- 431,435 ---- BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size) ! class SimpleXMLRPCServer(SocketServer.TCPServer, SimpleXMLRPCDispatcher): """Simple XML-RPC server. *************** *** 445,455 **** logRequests=1): self.logRequests = logRequests ! SimpleXMLRPCDispatcher.__init__(self) SocketServer.TCPServer.__init__(self, addr, requestHandler) ! class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): """Simple handler for XML-RPC data passed through CGI.""" ! def __init__(self): SimpleXMLRPCDispatcher.__init__(self) --- 445,455 ---- logRequests=1): self.logRequests = logRequests ! SimpleXMLRPCDispatcher.__init__(self) SocketServer.TCPServer.__init__(self, addr, requestHandler) ! class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): """Simple handler for XML-RPC data passed through CGI.""" ! def __init__(self): SimpleXMLRPCDispatcher.__init__(self) *************** *** 457,463 **** def handle_xmlrpc(self, request_text): """Handle a single XML-RPC request""" ! response = self._marshaled_dispatch(request_text) ! print 'Content-Type: text/xml' print 'Content-Length: %d' % len(response) --- 457,463 ---- def handle_xmlrpc(self, request_text): """Handle a single XML-RPC request""" ! response = self._marshaled_dispatch(request_text) ! print 'Content-Type: text/xml' print 'Content-Length: %d' % len(response) *************** *** 475,483 **** message, explain = \ BaseHTTPServer.BaseHTTPRequestHandler.responses[code] ! response = BaseHTTPServer.DEFAULT_ERROR_MESSAGE % \ { ! 'code' : code, ! 'message' : message, 'explain' : explain } --- 475,483 ---- message, explain = \ BaseHTTPServer.BaseHTTPRequestHandler.responses[code] ! response = BaseHTTPServer.DEFAULT_ERROR_MESSAGE % \ { ! 'code' : code, ! 'message' : message, 'explain' : explain } *************** *** 487,499 **** print print response ! def handle_request(self, request_text = None): """Handle a single XML-RPC request passed through a CGI post method. ! If no XML data is given then it is read from stdin. The resulting XML-RPC response is printed to stdout along with the correct HTTP headers. """ ! if request_text is None and \ os.environ.get('REQUEST_METHOD', None) == 'GET': --- 487,499 ---- print print response ! def handle_request(self, request_text = None): """Handle a single XML-RPC request passed through a CGI post method. ! If no XML data is given then it is read from stdin. The resulting XML-RPC response is printed to stdout along with the correct HTTP headers. """ ! if request_text is None and \ os.environ.get('REQUEST_METHOD', None) == 'GET': *************** *** 502,509 **** # POST data is normally available through stdin if request_text is None: ! request_text = sys.stdin.read() self.handle_xmlrpc(request_text) ! if __name__ == '__main__': server = SimpleXMLRPCServer(("localhost", 8000)) --- 502,509 ---- # POST data is normally available through stdin if request_text is None: ! request_text = sys.stdin.read() self.handle_xmlrpc(request_text) ! if __name__ == '__main__': server = SimpleXMLRPCServer(("localhost", 8000)) Index: _strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/_strptime.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** _strptime.py 19 Jan 2003 04:40:44 -0000 1.11 --- _strptime.py 29 Jan 2003 03:49:43 -0000 1.12 *************** *** 500,509 **** #``datetime`` and the methods it provides. if julian == -1: ! julian = julianday(year, month, day) else: # Assuming that if they bothered to include Julian day it will #be accurate ! year, month, day = gregorian(julian, year) if weekday == -1: ! weekday = dayofweek(year, month, day) return time.struct_time((year, month, day, hour, minute, second, --- 500,509 ---- #``datetime`` and the methods it provides. if julian == -1: ! julian = julianday(year, month, day) else: # Assuming that if they bothered to include Julian day it will #be accurate ! year, month, day = gregorian(julian, year) if weekday == -1: ! weekday = dayofweek(year, month, day) return time.struct_time((year, month, day, hour, minute, second, Index: dummy_thread.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dummy_thread.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** dummy_thread.py 30 Dec 2002 22:30:22 -0000 1.1 --- dummy_thread.py 29 Jan 2003 03:49:43 -0000 1.2 *************** *** 5,9 **** Suggested usage is:: ! try: import thread --- 5,9 ---- Suggested usage is:: ! try: import thread *************** *** 68,72 **** class LockType(object): """Class implementing dummy implementation of thread.LockType. ! Compatibility is maintained by maintaining self.locked_status which is a boolean that stores the state of the lock. Pickling of --- 68,72 ---- class LockType(object): """Class implementing dummy implementation of thread.LockType. ! Compatibility is maintained by maintaining self.locked_status which is a boolean that stores the state of the lock. Pickling of *************** *** 79,83 **** def __init__(self): self.locked_status = False ! def acquire(self, waitflag=None): """Dummy implementation of acquire(). --- 79,83 ---- def __init__(self): self.locked_status = False ! def acquire(self, waitflag=None): """Dummy implementation of acquire(). *************** *** 93,97 **** if waitflag is None: self.locked_status = True ! return None elif not waitflag: if not self.locked_status: --- 93,97 ---- if waitflag is None: self.locked_status = True ! return None elif not waitflag: if not self.locked_status: *************** *** 102,106 **** else: self.locked_status = True ! return True def release(self): --- 102,106 ---- else: self.locked_status = True ! return True def release(self): Index: macpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/macpath.py,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** macpath.py 15 Jan 2003 22:45:48 -0000 1.44 --- macpath.py 29 Jan 2003 03:49:43 -0000 1.45 *************** *** 86,93 **** def ismount(s): ! if not isabs(s): ! return False ! components = split(s) ! return len(components) == 2 and components[1] == '' def isdir(s): --- 86,93 ---- def ismount(s): ! if not isabs(s): ! return False ! components = split(s) ! return len(components) == 2 and components[1] == '' def isdir(s): Index: modulefinder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/modulefinder.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** modulefinder.py 31 Dec 2002 16:33:00 -0000 1.2 --- modulefinder.py 29 Jan 2003 03:49:43 -0000 1.3 *************** *** 515,521 **** consts[i] = self.replace_paths_in_code(consts[i]) ! return new.code(co.co_argcount, co.co_nlocals, co.co_stacksize, ! co.co_flags, co.co_code, tuple(consts), co.co_names, ! co.co_varnames, new_filename, co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars, co.co_cellvars) --- 515,521 ---- consts[i] = self.replace_paths_in_code(consts[i]) ! return new.code(co.co_argcount, co.co_nlocals, co.co_stacksize, ! co.co_flags, co.co_code, tuple(consts), co.co_names, ! co.co_varnames, new_filename, co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars, co.co_cellvars) Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** os.py 8 Jan 2003 21:20:57 -0000 1.65 --- os.py 29 Jan 2003 03:49:43 -0000 1.66 *************** *** 416,422 **** def getenv(key, default=None): ! """Get an environment variable, return None if it doesn't exist. ! The optional second argument can specify an alternate default.""" ! return environ.get(key, default) __all__.append("getenv") --- 416,422 ---- def getenv(key, default=None): ! """Get an environment variable, return None if it doesn't exist. ! The optional second argument can specify an alternate default.""" ! return environ.get(key, default) __all__.append("getenv") Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** pickletools.py 29 Jan 2003 00:56:17 -0000 1.18 --- pickletools.py 29 Jan 2003 03:49:43 -0000 1.19 *************** *** 1860,1867 **** markmsg = None if markstack and markobject in opcode.stack_before: ! assert markobject not in opcode.stack_after ! markpos = markstack.pop() ! if markpos is not None: ! markmsg = "(MARK at %d)" % markpos if arg is not None or markmsg: --- 1860,1867 ---- markmsg = None if markstack and markobject in opcode.stack_before: ! assert markobject not in opcode.stack_after ! markpos = markstack.pop() ! if markpos is not None: ! markmsg = "(MARK at %d)" % markpos if arg is not None or markmsg: Index: pty.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pty.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pty.py 1 Jan 2003 09:51:11 -0000 1.13 --- pty.py 29 Jan 2003 03:49:43 -0000 1.14 *************** *** 93,98 **** return result try: ! ioctl(result, I_PUSH, "ptem") ! ioctl(result, I_PUSH, "ldterm") except IOError: pass --- 93,98 ---- return result try: ! ioctl(result, I_PUSH, "ptem") ! ioctl(result, I_PUSH, "ldterm") except IOError: pass Index: py_compile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/py_compile.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** py_compile.py 15 Jan 2003 11:51:06 -0000 1.24 --- py_compile.py 29 Jan 2003 03:49:43 -0000 1.25 *************** *** 25,46 **** where ! exc_type: exception type to be used in error message type name can be accesses as class variable 'exc_type_name' ! exc_value: exception value to be used in error message can be accesses as class variable 'exc_value' ! file: name of file being compiled to be used in error message can be accesses as class variable 'file' ! msg: string message to be written as error message If no value is given, a default exception message will be given, consistent with 'standard' py_compile output. message (or default) can be accesses as class variable 'msg' ! """ ! def __init__(self, exc_type, exc_value, file, msg=''): exc_type_name = exc_type.__name__ --- 25,46 ---- where ! exc_type: exception type to be used in error message type name can be accesses as class variable 'exc_type_name' ! exc_value: exception value to be used in error message can be accesses as class variable 'exc_value' ! file: name of file being compiled to be used in error message can be accesses as class variable 'file' ! msg: string message to be written as error message If no value is given, a default exception message will be given, consistent with 'standard' py_compile output. message (or default) can be accesses as class variable 'msg' ! """ ! def __init__(self, exc_type, exc_value, file, msg=''): exc_type_name = exc_type.__name__ *************** *** 50,54 **** else: errmsg = "Sorry: %s: %s" % (exc_type_name,exc_value) ! Exception.__init__(self,msg or errmsg,exc_type_name,exc_value,file) --- 50,54 ---- else: errmsg = "Sorry: %s: %s" % (exc_type_name,exc_value) ! Exception.__init__(self,msg or errmsg,exc_type_name,exc_value,file) *************** *** 95,99 **** exception occurs and this flag is set to True, a PyCompileError exception will be raised. ! Note that it isn't necessary to byte-compile Python modules for execution efficiency -- Python itself byte-compiles a module when --- 95,99 ---- exception occurs and this flag is set to True, a PyCompileError exception will be raised. ! Note that it isn't necessary to byte-compile Python modules for execution efficiency -- Python itself byte-compiles a module when *************** *** 160,164 **** except PyCompileError,err: sys.stderr.write(err.msg) ! if __name__ == "__main__": main() --- 160,164 ---- except PyCompileError,err: sys.stderr.write(err.msg) ! if __name__ == "__main__": main() Index: tarfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tarfile.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** tarfile.py 5 Jan 2003 23:19:43 -0000 1.1 --- tarfile.py 29 Jan 2003 03:49:43 -0000 1.2 *************** *** 1250,1254 **** prefix = tarinfo.name[:LENGTH_PREFIX + 1] while prefix and prefix[-1] != "/": ! prefix = prefix[:-1] name = tarinfo.name[len(prefix):] --- 1250,1254 ---- prefix = tarinfo.name[:LENGTH_PREFIX + 1] while prefix and prefix[-1] != "/": ! prefix = prefix[:-1] name = tarinfo.name[len(prefix):] From goodger@users.sourceforge.net Wed Jan 29 03:56:49 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 28 Jan 2003 19:56:49 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv18574 Modified Files: pep-0304.txt Log Message: fixed headers Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pep-0304.txt 27 Jan 2003 22:33:41 -0000 1.4 --- pep-0304.txt 29 Jan 2003 03:56:47 -0000 1.5 *************** *** 4,9 **** Last-Modified: $Date$ Author: Skip Montanaro ! Status: Active ! Type: Draft Content-Type: text/x-rst Created: 22-Jan-2003 --- 4,9 ---- Last-Modified: $Date$ Author: Skip Montanaro ! Status: Draft ! Type: Standards Track Content-Type: text/x-rst Created: 22-Jan-2003 From goodger@users.sourceforge.net Wed Jan 29 04:20:22 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 28 Jan 2003 20:20:22 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,NONE,1.1 pep-0000.txt,1.224,1.225 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv25170 Modified Files: pep-0000.txt Added Files: pep-0305.txt Log Message: Added PEP 305, CSV file API --- NEW FILE: pep-0305.txt --- PEP: 305 Title: CSV file API Version: $Revision: 1.1 $ Last-Modified: $Date: 2003/01/29 04:20:19 $ Author: Skip Montanaro , Kevin Altis , Cliff Wells Status: Draft Type: Informational Content-Type: text/x-rst Created: 26-Jan-2003 Post-History: Abstract ======== The Comma Separated Values (CSV) file format is the most common import and export format for spreadsheets and databases. Although many CSV files are simple to parse, the format is not formally defined by a stable specification and is subtle enough that parsing lines of a CSV file with something like ``line.split(",")`` is bound to fail. This PEP defines an API for reading and writing CSV files which should make it possible for programmers to select a CSV module which meets their requirements. Existing Modules ================ Three widely available modules enable programmers to read and write CSV files: - Object Craft's CSV module [1]_ - Cliff Wells's Python-DSV module [2]_ - Laurence Tratt's ASV module [3]_ Each has a different API, making it somewhat difficult for programmers to switch between them. More of a problem may be that they interpret some of the CSV corner cases differently, so even after surmounting the differences in the module APIs, the programmer has to also deal with semantic differences between the packages. Rationale ========= By defining common APIs for reading and writing CSV files, we make it easier for programmers to choose an appropriate module to suit their needs, and make it easier to switch between modules if their needs change. This PEP also forms a set of requirements for creation of a module which will hopefully be incorporated into the Python distribution. Module Interface ================ The module supports two basic APIs, one for reading and one for writing. The reading interface is:: reader(fileobj [, dialect='excel2000'] [, quotechar='"'] [, delimiter=','] [, skipinitialspace=False]) A reader object is an iterable which takes a file-like object opened for reading as the sole required parameter. It also accepts four optional parameters (discussed below). Readers are typically used as follows:: csvreader = csv.reader(file("some.csv")) for row in csvreader: process(row) The writing interface is similar:: writer(fileobj [, dialect='excel2000'] [, quotechar='"'] [, delimiter=','] [, skipinitialspace=False]) A writer object is a wrapper around a file-like object opened for writing. It accepts the same four optional parameters as the reader constructor. Writers are typically used as follows:: csvwriter = csv.writer(file("some.csv", "w")) for row in someiterable: csvwriter.write(row) Optional Parameters ------------------- Both the reader and writer constructors take four optional keyword parameters: - dialect is an easy way of specifying a complete set of format constraints for a reader or writer. Most people will know what application generated a CSV file or what application will process the CSV file they are generating, but not the precise settings necessary. The only dialect defined initially is "excel2000". The dialect parameter is interpreted in a case-insensitive manner. - quotechar specifies a one-character string to use as the quoting character. It defaults to '"'. - delimiter specifies a one-character string to use as the field separator. It defaults to ','. - skipinitialspace specifies how to interpret whitespace which immediately follows a delimiter. It defaults to False, which means that whitespace immediate following a delimiter is part of the following field. When processing a dialect setting and one or more of the other optional parameters, the dialect parameter is processed first, then the others are processed. This makes it easy to choose a dialect, then override one or more of the settings. For example, if a CSV file was generated by Excel 2000 using single quotes as the quote character and TAB as the delimiter, you could create a reader like:: csvreader = csv.reader(file("some.csv"), dialect="excel2000", quotechar="'", delimiter='\t') Other details of how Excel generates CSV files would be handled automatically. Testing ======= TBD. Issues ====== - Should a parameter control how consecutive delimiters are interpreted? Our thought is "no". Consecutive delimiters should always denote an empty field. - What about Unicode? Is it sufficient to pass a file object gotten from codecs.open()? For example:: csvreader = csv.reader(codecs.open("some.csv", "r", "cp1252")) csvwriter = csv.writer(codecs.open("some.csv", "w", "utf-8")) In the first example, text would be assumed to be encoded as cp1252. Should the system be aggressive in converting to Unicode or should Unicode strings only be returned if necessary? In the second example, the file will take care of automatically encoding Unicode strings as utf-8 before writing to disk. - What about alternate escape conventions? When Excel exports a file, it appears only the field delimiter needs to be escaped. It accomplishes this by quoting the entire field, then doubling any quote characters which appear in the field. It also quotes a field if the first character is a quote character. It would seem we need to support two modes: escape-by-quoting and escape-by-prefix. In addition, for the second mode, we'd have to specify the escape character (presumably defaulting to a backslash character). - Should there be a "fully quoted" mode for writing? What about "fully quoted except for numeric values"? - What about end-of-line? If I generate a CSV file on a Unix system, will Excel properly recognize the LF-only line terminators? - What about conversion to other file formats? Is the list-of-lists output from the csvreader sufficient to feed into other writers? - What about an option to generate list-of-dict output from the reader and accept list-of-dicts by the writer? This makes manipulating individual rows easier since each one is independent, but you lose field order when writing and have to tell the writer object the order the fields should appear in the file. - Are quote character and delimiters limited to single characters? I had a client not that long ago who wrote their own flat file format with a delimiter of ":::". - How should rows of different lengths be handled? The options seem to be: * raise an exception when a row is encountered whose length differs from the previous row * silently return short rows * allow the caller to specify the desired row length and what to do when rows of a different length are encountered: ignore, truncate, pad, raise exception, etc. References ========== .. [1] csv module, Object Craft (http://www.object-craft.com.au/projects/csv) .. [2] Python-DSV module, Wells (http://sourceforge.net/projects/python-dsv/) .. [3] ASV module, Tratt (http://tratt.net/laurie/python/asv/) There are many references to other CSV-related projects on the Web. A few are included here. 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.224 retrieving revision 1.225 diff -C2 -d -r1.224 -r1.225 *** pep-0000.txt 23 Jan 2003 17:25:59 -0000 1.224 --- pep-0000.txt 29 Jan 2003 04:20:19 -0000 1.225 *************** *** 106,110 **** S 302 New Import Hooks JvR S 303 Extend divmod() for Multiple Divisors Bellman ! S 304 Controlling generation of bytecode files Montanaro Finished PEPs (done, implemented in CVS) --- 106,111 ---- S 302 New Import Hooks JvR S 303 Extend divmod() for Multiple Divisors Bellman ! S 304 Controlling Generation of Bytecode Files Montanaro ! I 305 CSV File API Montanaro, Altis, Wells Finished PEPs (done, implemented in CVS) *************** *** 300,304 **** S 302 New Import Hooks JvR S 303 Extend divmod() for Multiple Divisors Bellman ! S 304 Controlling generation of bytecode files Montanaro SR 666 Reject Foolish Indentation Creighton --- 301,306 ---- S 302 New Import Hooks JvR S 303 Extend divmod() for Multiple Divisors Bellman ! S 304 Controlling Generation of Bytecode Files Montanaro ! I 305 CSV File API Montanaro, Altis, Wells SR 666 Reject Foolish Indentation Creighton *************** *** 321,324 **** --- 323,327 ---- Ahlstrom, James C. jim@interet.com Althoff, Jim james_althoff@i2.com + Altis, Kevin altis@semi-retired.com Ascher, David davida@activestate.com Barrett, Paul barrett@stsci.edu *************** *** 373,376 **** --- 376,380 ---- Tirosh, Oren oren at hishome.net Warsaw, Barry barry@zope.com + Wells, Cliff LogiplexSoftware@earthlink.net Wilson, Greg gvwilson@ddj.com Wouters, Thomas thomas@xs4all.net From goodger@users.sourceforge.net Wed Jan 29 04:20:47 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 28 Jan 2003 20:20:47 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv25273 Modified Files: pep-0304.txt Log Message: capitalized title Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0304.txt 29 Jan 2003 03:56:47 -0000 1.5 --- pep-0304.txt 29 Jan 2003 04:20:45 -0000 1.6 *************** *** 1,4 **** PEP: 304 ! Title: Controlling generation of bytecode files Version: $Revision$ Last-Modified: $Date$ --- 1,4 ---- PEP: 304 ! Title: Controlling Generation of Bytecode Files Version: $Revision$ Last-Modified: $Date$ From goodger@users.sourceforge.net Wed Jan 29 04:23:28 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Tue, 28 Jan 2003 20:23:28 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv25890 Modified Files: pep-0305.txt Log Message: capitalized title Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep-0305.txt 29 Jan 2003 04:20:19 -0000 1.1 --- pep-0305.txt 29 Jan 2003 04:23:26 -0000 1.2 *************** *** 1,4 **** PEP: 305 ! Title: CSV file API Version: $Revision$ Last-Modified: $Date$ --- 1,4 ---- PEP: 305 ! Title: CSV File API Version: $Revision$ Last-Modified: $Date$ From fdrake@users.sourceforge.net Wed Jan 29 05:10:29 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 28 Jan 2003 21:10:29 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib email.tex,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv5688 Modified Files: email.tex Log Message: Move a footnote to the end of the sentence, so the note mark won't interfere with the flow of the sentence. Index: email.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/email.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** email.tex 1 Oct 2002 15:29:08 -0000 1.16 --- email.tex 29 Jan 2003 05:10:27 -0000 1.17 *************** *** 324,330 **** \verbatiminput{email-mime.py} ! Here's an example\footnote{Thanks to Matthew Dixon Cowles for the ! original inspiration and examples.} of how to send the entire contents ! of a directory as an email message: \verbatiminput{email-dir.py} --- 324,331 ---- \verbatiminput{email-mime.py} ! Here's an example of how to send the entire contents of a directory as ! an email message: ! \footnote{Thanks to Matthew Dixon Cowles for the original inspiration ! and examples.} \verbatiminput{email-dir.py} From fdrake@users.sourceforge.net Wed Jan 29 05:14:46 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Tue, 28 Jan 2003 21:14:46 -0800 Subject: [Python-checkins] python/dist/src/Doc/html style.css,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/html In directory sc8-pr-cvs1:/tmp/cvs-serv6893 Modified Files: style.css Log Message: Make the footer at the end of a \verbatiminput stand out a little more, to make it easier to tell apart from the verbatim content. Index: style.css =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/html/style.css,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** style.css 27 Jan 2003 16:31:16 -0000 1.24 --- style.css 29 Jan 2003 05:14:44 -0000 1.25 *************** *** 90,93 **** --- 90,97 ---- font-size: 90%; } .verbatim { margin-left: 2em; } + .verbatim .footer { padding: 0.05in; + font-size: 85%; + background-color: #99ccff; + margin-right: 0.5in; } .grammar { background-color: #99ccff; From gvanrossum@users.sourceforge.net Wed Jan 29 06:12:48 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 22:12:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv24126 Modified Files: pickletester.py Log Message: Test all three EXT opcodes, and move these tests into TempAbstractPickleTests, because they don't work with cPickle yet. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** pickletester.py 28 Jan 2003 22:34:08 -0000 1.28 --- pickletester.py 29 Jan 2003 06:12:46 -0000 1.29 *************** *** 345,348 **** --- 345,409 ---- ## pickletools.dis(s) + def test_global_ext1(self): + import copy_reg + copy_reg.add_extension(__name__, "MyList", 0xf0) + try: + x = MyList([1, 2, 3]) + x.foo = 42 + x.bar = "hello" + + # Dump using protocol 1 for comparison + s1 = self.dumps(x, 1) + y = self.loads(s1) + self.assertEqual(list(x), list(y)) + self.assertEqual(x.__dict__, y.__dict__) + self.assert_(s1.find(__name__) >= 0) + self.assert_(s1.find("MyList") >= 0) + ## import pickletools + ## print + ## pickletools.dis(s1) + + # Dump using protocol 2 for test + s2 = self.dumps(x, 2) + self.assertEqual(s2.find(__name__), -1) + self.assertEqual(s2.find("MyList"), -1) + y = self.loads(s2) + self.assertEqual(list(x), list(y)) + self.assertEqual(x.__dict__, y.__dict__) + ## import pickletools + ## print + ## pickletools.dis(s2) + + finally: + copy_reg.remove_extension(__name__, "MyList", 0xf0) + + def test_global_ext2(self): + import copy_reg + copy_reg.add_extension(__name__, "MyList", 0xfff0) + try: + x = MyList() + s2 = self.dumps(x, 2) + self.assertEqual(s2.find(__name__), -1) + self.assertEqual(s2.find("MyList"), -1) + y = self.loads(s2) + self.assertEqual(list(x), list(y)) + self.assertEqual(x.__dict__, y.__dict__) + finally: + copy_reg.remove_extension(__name__, "MyList", 0xfff0) + + def test_global_ext4(self): + import copy_reg + copy_reg.add_extension(__name__, "MyList", 0xfffff0) + try: + x = MyList() + s2 = self.dumps(x, 2) + self.assertEqual(s2.find(__name__), -1) + self.assertEqual(s2.find("MyList"), -1) + y = self.loads(s2) + self.assertEqual(list(x), list(y)) + self.assertEqual(x.__dict__, y.__dict__) + finally: + copy_reg.remove_extension(__name__, "MyList", 0xfffff0) + class MyTuple(tuple): pass From gvanrossum@users.sourceforge.net Wed Jan 29 06:14:14 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 22:14:14 -0800 Subject: [Python-checkins] python/dist/src/Lib copy_reg.py,1.10,1.11 pickle.py,1.120,1.121 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv24309a Modified Files: copy_reg.py pickle.py Log Message: Support for extension codes. (By accident I checked in the tests first.) Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** copy_reg.py 27 Dec 2001 16:27:28 -0000 1.10 --- copy_reg.py 29 Jan 2003 06:14:11 -0000 1.11 *************** *** 71,72 **** --- 71,131 ---- else: return _reconstructor, args + + # A registry of extension codes. This is an ad-hoc compression + # mechanism. Whenever a global reference to , is about + # to be pickled, the (, ) tuple is looked up here to see + # if it is a registered extension code for it. Extension codes are + # universal, so that the meaning of a pickle does not depend on + # context. (There are also some codes reserved for local use that + # don't have this restriction.) Codes are positive ints; 0 is + # reserved. + + extension_registry = {} # key -> code + inverted_registry = {} # code -> key + extension_cache = {} # code -> object + + def add_extension(module, name, code): + """Register an extension code.""" + code = int(code) + if not 1 <= code < 0x7fffffff: + raise ValueError, "code out of range" + key = (module, name) + if (extension_registry.get(key) == code and + inverted_registry.get(code) == key): + return # Redundant registrations are benign + if key in extension_registry: + raise ValueError("key %s is already registered with code %s" % + (key, extension_registry[key])) + if code in inverted_registry: + raise ValueError("code %s is already in use for key %s" % + (code, inverted_registry[code])) + extension_registry[key] = code + inverted_registry[code] = key + + def remove_extension(module, name, code): + """Unregister an extension code. For testing only.""" + key = (module, name) + if (extension_registry.get(key) != code or + inverted_registry.get(code) != key): + raise ValueError("key %s is not registered with code %s" % + (key, code)) + del extension_registry[key] + del inverted_registry[code] + if code in extension_cache: + del extension_cache[code] + + def clear_extension_cache(): + extension_cache.clear() + + # Standard extension code assignments + + # Reserved ranges + + # First Last Count Purpose + # 1 127 127 Reserved for Python standard library + # 128 191 64 Reserved for Zope 3 + # 192 239 48 Reserved for 3rd parties + # 240 255 16 Reserved for private use (will never be assigned) + # 256 Inf Inf Reserved for future assignment + + # Extension codes are assigned by the Python Software Foundation. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.120 retrieving revision 1.121 diff -C2 -d -r1.120 -r1.121 *** pickle.py 29 Jan 2003 00:56:17 -0000 1.120 --- pickle.py 29 Jan 2003 06:14:11 -0000 1.121 *************** *** 29,32 **** --- 29,33 ---- from types import * from copy_reg import dispatch_table, _reconstructor + from copy_reg import extension_registry, inverted_registry, extension_cache import marshal import sys *************** *** 396,409 **** if isinstance(obj, list): ! write(MARK) ! for x in obj: ! save(x) ! write(APPENDS) elif isinstance(obj, dict): ! write(MARK) ! for k, v in obj.iteritems(): save(k) save(v) ! write(SETITEMS) getstate = getattr(obj, "__getstate__", None) --- 397,422 ---- if isinstance(obj, list): ! n = len(obj) ! if n > 1: ! write(MARK) ! for x in obj: ! save(x) ! write(APPENDS) ! elif n == 1: ! save(obj[0]) ! write(APPEND) elif isinstance(obj, dict): ! n = len(obj) ! if n > 1: ! write(MARK) ! for k, v in obj.iteritems(): ! save(k) ! save(v) ! write(SETITEMS) ! elif n == 1: ! k, v = obj.items()[0] save(k) save(v) ! write(SETITEM) getstate = getattr(obj, "__getstate__", None) *************** *** 421,424 **** --- 434,439 ---- if not getstate: state = getattr(obj, "__dict__", None) + if not state: + state = None # If there are slots, the state becomes a tuple of two # items: the first item the regular __dict__ or None, and *************** *** 704,708 **** dispatch[InstanceType] = save_inst ! def save_global(self, obj, name = None): write = self.write memo = self.memo --- 719,723 ---- dispatch[InstanceType] = save_inst ! def save_global(self, obj, name=None, pack=struct.pack): write = self.write memo = self.memo *************** *** 730,733 **** --- 745,760 ---- (obj, module, name)) + if self.proto >= 2: + code = extension_registry.get((module, name)) + if code: + assert code > 0 + if code <= 0xff: + write(EXT1 + chr(code)) + elif code <= 0xffff: + write(EXT2 + chr(code&0xff) + chr(code>>8)) + else: + write(EXT4 + pack(" Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25375 Modified Files: pickle.py Log Message: Declare Protocol 2 as implemented. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.121 retrieving revision 1.122 diff -C2 -d -r1.121 -r1.122 *** pickle.py 29 Jan 2003 06:14:11 -0000 1.121 --- pickle.py 29 Jan 2003 06:16:12 -0000 1.122 *************** *** 142,146 **** FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py ! # Protocol 2 (XXX not yet implemented). PROTO = '\x80' # identify pickle protocol --- 142,146 ---- FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py ! # Protocol 2 PROTO = '\x80' # identify pickle protocol From gvanrossum@users.sourceforge.net Wed Jan 29 06:24:33 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 28 Jan 2003 22:24:33 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv27768 Modified Files: pickletools.py Log Message: Document the demise of all pretenses of safety, and the difference between cPickle and pickle.py regarding __safe_for_unpickling__ before Python 2.3. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** pickletools.py 29 Jan 2003 03:49:43 -0000 1.19 --- pickletools.py 29 Jan 2003 06:24:30 -0000 1.20 *************** *** 126,129 **** --- 126,140 ---- the registry contents are predefined (there's nothing akin to the memo's PUT). + + Another, independent change with Python 2.3 is the abandonment of any + pretense that it might be safe to pickles received from untrusted + parties -- no sufficient security analysis has been done to guarantee + this and there isn't a use case to warrants the expense of such an + analysis. + + To this end, all tests for __safe_for_unpickling__ or for + copy_reg.safe_constructors are removed from the unpickling code. + References to these variables in the descriptions below are to be seen + as describing unpickling in Python 2.2 and before. """ *************** *** 1592,1597 **** attribute. Unlike as for the __safe_for_unpickling__ check in REDUCE, it doesn't matter whether this attribute has a true or false value, it ! only matters whether it exists (XXX this smells like a bug). If ! __safe_for_unpickling__ dosn't exist, UnpicklingError is raised. Else (the class object does have a __safe_for_unpickling__ attr), --- 1603,1609 ---- attribute. Unlike as for the __safe_for_unpickling__ check in REDUCE, it doesn't matter whether this attribute has a true or false value, it ! only matters whether it exists (XXX this is a bug; cPickle ! requires the attribute to be true). If __safe_for_unpickling__ ! doesn't exist, UnpicklingError is raised. Else (the class object does have a __safe_for_unpickling__ attr), *************** *** 1625,1630 **** As for INST, the remainder of the stack above the markobject is gathered into an argument tuple, and then the logic seems identical, ! except that no __safe_for_unpickling__ check is done (XXX this smells ! like a bug). See INST for the gory details. """), --- 1637,1643 ---- As for INST, the remainder of the stack above the markobject is gathered into an argument tuple, and then the logic seems identical, ! except that no __safe_for_unpickling__ check is done (XXX this is ! a bug; cPickle does test __safe_for_unpickling__). See INST for ! the gory details. """), From jackjansen@users.sourceforge.net Wed Jan 29 09:56:59 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 29 Jan 2003 01:56:59 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macfs.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv26918 Modified Files: macfs.py Log Message: test_macfs found an error on the first day of its existence: round trips for date values to FSSpec.{Get,Set}Dates didn't work in MacPython-OS9. Fixed. Index: macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macfs.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** macfs.py 28 Jan 2003 21:40:36 -0000 1.7 --- macfs.py 29 Jan 2003 09:56:56 -0000 1.8 *************** *** 36,40 **** return (0, int(t), 0) else: ! def _utc2time(utc): return utc[1] def _time2utc(t): if t > 0x7fffffff: --- 36,44 ---- return (0, int(t), 0) else: ! def _utc2time(utc): ! t = utc[1] ! if t < 0: ! t = t + 0x100000000L ! return t def _time2utc(t): if t > 0x7fffffff: From jackjansen@users.sourceforge.net Wed Jan 29 10:39:21 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 29 Jan 2003 02:39:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac aetypes.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv9226 Modified Files: aetypes.py Log Message: Some objects could have uninitialized attributes. Fixed. Index: aetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/aetypes.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** aetypes.py 30 Dec 2002 22:04:20 -0000 1.1 --- aetypes.py 29 Jan 2003 10:39:19 -0000 1.2 *************** *** 522,525 **** --- 522,527 ---- def __init__(self, which, fr = None): SelectableItem.__init__(self, self.want, which, fr) + self._propdict = {} + self._elemdict = {} def __repr__(self): From jackjansen@users.sourceforge.net Wed Jan 29 10:41:02 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 29 Jan 2003 02:41:02 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_aepack.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv9666 Added Files: test_aepack.py Log Message: Moved aepack test code to the test suite. --- NEW FILE: test_aepack.py --- # Copyright (C) 2003 Python Software Foundation import unittest import aepack import aetypes import os from test import test_support class TestAepack(unittest.TestCase): OBJECTS = [ aetypes.Enum('enum'), aetypes.Type('type'), aetypes.Keyword('kwrd'), aetypes.Range(1, 10), aetypes.Comparison(1, '< ', 10), aetypes.Logical('not ', 1), aetypes.IntlText(0, 0, 'international text'), aetypes.IntlWritingCode(0,0), aetypes.QDPoint(50,100), aetypes.QDRectangle(50,100,150,200), aetypes.RGBColor(0x7000, 0x6000, 0x5000), aetypes.Unknown('xxxx', 'unknown type data'), aetypes.Character(1), aetypes.Character(2, aetypes.Line(2)), ] def test_roundtrip_string(self): o = 'a string' packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o, unpacked) def test_roundtrip_int(self): o = 12 packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o, unpacked) def test_roundtrip_float(self): o = 12.1 packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o, unpacked) def test_roundtrip_None(self): o = None packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o, unpacked) def test_roundtrip_aeobjects(self): for o in self.OBJECTS: packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(repr(o), repr(unpacked)) def test_roundtrip_FSSpec(self): try: import Carbon.File except: return o = Carbon.File.FSSpec(os.curdir) packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o.as_pathname(), unpacked.as_pathname()) def test_roundtrip_Alias(self): try: import Carbon.File except: return o = Carbon.File.FSSpec(os.curdir).NewAliasMinimal() packed = aepack.pack(o) unpacked = aepack.unpack(packed) self.assertEqual(o.FSResolveAlias(None)[0].as_pathname(), unpacked.FSResolveAlias(None)[0].as_pathname()) def test_main(): test_support.run_unittest(TestAepack) if __name__ == '__main__': test_main() From jackjansen@users.sourceforge.net Wed Jan 29 10:41:20 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 29 Jan 2003 02:41:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac aepack.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv9771 Modified Files: aepack.py Log Message: Moved aepack test code to the test suite. Index: aepack.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/aepack.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** aepack.py 28 Jan 2003 23:53:40 -0000 1.2 --- aepack.py 29 Jan 2003 10:41:18 -0000 1.3 *************** *** 344,385 **** newobj.__class__ = classtype return newobj - - def _test(): - """Test program. Pack and unpack various things""" - objs = [ - 'a string', - 12, - 12.0, - None, - ['a', 'list', 'of', 'strings'], - {'key1': 'value1', 'key2':'value2'}, - Carbon.File.FSSpec(os.curdir), - Carbon.File.FSSpec(os.curdir).NewAliasMinimal(), - aetypes.Enum('enum'), - aetypes.Type('type'), - aetypes.Keyword('kwrd'), - aetypes.Range(1, 10), - aetypes.Comparison(1, '< ', 10), - aetypes.Logical('not ', 1), - # Cannot do StyledText - # Cannot do AEText - aetypes.IntlText(0, 0, 'international text'), - aetypes.IntlWritingCode(0,0), - aetypes.QDPoint(50,100), - aetypes.QDRectangle(50,100,150,200), - aetypes.RGBColor(0x7000, 0x6000, 0x5000), - aetypes.Unknown('xxxx', 'unknown type data'), - aetypes.Character(1), - aetypes.Character(2, aetypes.Line(2)), - ] - for o in objs: - print 'BEFORE', o, `o` - packed = pack(o) - unpacked = unpack(packed) - print 'AFTER ', unpacked, `unpacked` - import sys - sys.exit(1) - - if __name__ == '__main__': - _test() - --- 344,345 ---- From davecole@users.sourceforge.net Wed Jan 29 11:21:37 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Wed, 29 Jan 2003 03:21:37 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.1,1.2 setup.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv20979 Modified Files: _csv.c setup.py Log Message: Reformatted the Object Craft csv module to conform to what looks like the Python C coding standard. Made use of PyDoc_STRVAR and other macros which seem to be in other 2.3 code I looked at. This seems like a good place for us to start building our code which conforms to the PEP we are going to have RSN. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _csv.c 28 Jan 2003 02:07:46 -0000 1.1 --- _csv.c 29 Jan 2003 11:21:34 -0000 1.2 *************** *** 1 **** ! /* placeholder */ --- 1,784 ---- ! #include "Python.h" ! #include "structmember.h" ! ! static PyObject *error_obj; /* CSV exception */ ! ! typedef enum { ! START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD, ! IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD ! } ParserState; ! ! typedef struct { ! PyObject_HEAD ! ! int ms_double_quote; /* is " represented by ""? */ ! char field_sep; /* field separator */ ! char quote_char; /* quote character */ ! char escape_char; /* escape character */ ! ! ParserState state; /* current CSV parse state */ ! PyObject *fields; /* field list for current record */ ! ! int auto_clear; /* should fields be cleared on next ! parse() after exception? */ ! int strict; /* raise exception on bad CSV */ ! ! int had_parse_error; /* did we have a parse error? */ ! ! char *field; /* build current field in here */ ! int field_size; /* size of allocated buffer */ ! int field_len; /* length of current field */ ! ! char *rec; /* buffer for parser.join */ ! int rec_size; /* size of allocated record */ ! int rec_len; /* length of record */ ! int num_fields; /* number of fields in record */ ! } ParserObj; ! ! staticforward PyTypeObject Parser_Type; ! ! static PyObject * ! raise_exception(char *fmt, ...) ! { ! va_list ap; ! char msg[512]; ! PyObject *pymsg; ! ! va_start(ap, fmt); ! #ifdef _WIN32 ! _vsnprintf(msg, sizeof(msg), fmt, ap); ! #else ! vsnprintf(msg, sizeof(msg), fmt, ap); ! #endif ! va_end(ap); ! pymsg = PyString_FromString(msg); ! PyErr_SetObject(error_obj, pymsg); ! Py_XDECREF(pymsg); ! ! return NULL; ! } ! ! static void ! parse_save_field(ParserObj *self) ! { ! PyObject *field; ! ! field = PyString_FromStringAndSize(self->field, self->field_len); ! if (field != NULL) { ! PyList_Append(self->fields, field); ! Py_XDECREF(field); ! } ! self->field_len = 0; ! } ! ! static int ! parse_grow_buff(ParserObj *self) ! { ! if (self->field_size == 0) { ! self->field_size = 4096; ! self->field = PyMem_Malloc(self->field_size); ! } else { ! self->field_size *= 2; ! self->field = PyMem_Realloc(self->field, self->field_size); ! } ! if (self->field == NULL) { ! PyErr_NoMemory(); ! return 0; ! } ! return 1; ! } ! ! static void ! parse_add_char(ParserObj *self, char c) ! { ! if (self->field_len == self->field_size && !parse_grow_buff(self)) ! return; ! self->field[self->field_len++] = c; ! } ! ! static void ! parse_prepend_char(ParserObj *self, char c) ! { ! if (self->field_len == self->field_size && !parse_grow_buff(self)) ! return; ! memmove(self->field + 1, self->field, self->field_len); ! self->field[0] = c; ! self->field_len++; ! } ! ! static void ! parse_process_char(ParserObj *self, char c) ! { ! switch (self->state) { ! case START_RECORD: ! /* start of record */ ! if (c == '\0') ! /* empty line - return [] */ ! break; ! /* normal character - handle as START_FIELD */ ! self->state = START_FIELD; ! /* fallthru */ ! case START_FIELD: ! /* expecting field */ ! if (c == '\0') { ! /* save empty field - return [fields] */ ! parse_save_field(self); ! self->state = START_RECORD; ! } else if (c == self->quote_char) { ! /* start quoted field */ ! self->state = IN_QUOTED_FIELD; ! } else if (c == self->escape_char) { ! /* possible escaped character */ ! self->state = ESCAPED_CHAR; ! } else if (c == self->field_sep) { ! /* save empty field */ ! parse_save_field(self); ! } else { ! /* begin new unquoted field */ ! parse_add_char(self, c); ! self->state = IN_FIELD; ! } ! break; ! ! case ESCAPED_CHAR: ! if (c != self->escape_char && c != self->field_sep && ! c != self->quote_char) ! parse_add_char(self, self->escape_char); ! parse_add_char(self, c); ! self->state = IN_FIELD; ! break; ! ! case IN_FIELD: ! /* in unquoted field */ ! if (c == '\0') { ! /* end of line - return [fields] */ ! parse_save_field(self); ! self->state = START_RECORD; ! } else if (c == self->escape_char) { ! /* possible escaped character */ ! self->state = ESCAPED_CHAR; ! } else if (c == self->field_sep) { ! /* save field - wait for new field */ ! parse_save_field(self); ! self->state = START_FIELD; ! } else { ! /* normal character - save in field */ ! parse_add_char(self, c); ! } ! break; ! ! case IN_QUOTED_FIELD: ! /* in quoted field */ ! if (c == '\0') { ! /* end of line - save '\n' in field */ ! parse_add_char(self, '\n'); ! } else if (c == self->escape_char) { ! /* Possible escape character */ ! self->state = ESCAPE_IN_QUOTED_FIELD; ! } else if (c == self->quote_char) { ! if (self->ms_double_quote) { ! /* microsoft style double quotes; " represented by "" */ ! self->state = QUOTE_IN_QUOTED_FIELD; ! } else { ! /* end of quote part of field */ ! self->state = IN_FIELD; ! } ! } else { ! /* normal character - save in field */ ! parse_add_char(self, c); ! } ! break; ! ! case ESCAPE_IN_QUOTED_FIELD: ! if (c != self->escape_char && c != self->field_sep && ! c != self->quote_char) ! parse_add_char(self, self->escape_char); ! parse_add_char(self, c); ! self->state = IN_QUOTED_FIELD; ! break; ! ! case QUOTE_IN_QUOTED_FIELD: ! /* microsoft double quotes - seen a quote in an quoted field */ ! if (self->quote_char && c == self->quote_char) { ! /* save "" as " */ ! parse_add_char(self, c); ! self->state = IN_QUOTED_FIELD; ! } else if (c == self->field_sep) { ! /* save field - wait for new field */ ! parse_save_field(self); ! self->state = START_FIELD; ! } else if (c == '\0') { ! /* end of line - return [fields] */ ! parse_save_field(self); ! self->state = START_RECORD; ! } else if (!self->strict) { ! parse_add_char(self, c); ! self->state = IN_FIELD; ! } else { ! /* illegal */ ! self->had_parse_error = 1; ! raise_exception("%c expected after %c", ! self->field_sep, self->quote_char); ! } ! break; ! ! } ! } ! ! static void ! clear_fields_and_status(ParserObj *self) ! { ! if (self->fields) { ! Py_XDECREF(self->fields); ! } ! self->fields = PyList_New(0); ! self->field_len = 0; ! self->state = START_RECORD; ! ! self->had_parse_error = 0; ! } ! ! /* ---------------------------------------------------------------- */ ! ! PyDoc_STRVAR(Parser_parse_doc, ! "parse(s) -> list of strings\n" ! "\n" ! "CSV parse the single line in the string s and return a\n" ! "list of string fields. If the CSV record contains multi-line\n" ! "fields, the function will return None until all lines of the\n" ! "record have been parsed."); ! ! static PyObject * ! Parser_parse(ParserObj *self, PyObject *args) ! { ! char *line; ! ! if (!PyArg_ParseTuple(args, "s", &line)) ! return NULL; ! ! if (self->auto_clear && self->had_parse_error) ! clear_fields_and_status(self); ! ! /* Process line of text - send '\0' to processing code to ! represent end of line. End of line which is not at end of ! string is an error. */ ! while (*line) { ! char c; ! ! c = *line++; ! if (c == '\r') { ! c = *line++; ! if (c == '\0') ! /* macintosh end of line */ ! break; ! if (c == '\n') { ! c = *line++; ! if (c == '\0') ! /* DOS end of line */ ! break; ! } ! self->had_parse_error = 1; ! return raise_exception("Newline inside string"); ! } ! if (c == '\n') { ! c = *line++; ! if (c == '\0') ! /* unix end of line */ ! break; ! self->had_parse_error = 1; ! return raise_exception("Newline inside string"); ! } ! parse_process_char(self, c); ! if (PyErr_Occurred()) ! return NULL; ! } ! parse_process_char(self, '\0'); ! ! if (self->state == START_RECORD) { ! PyObject *fields = self->fields; ! self->fields = PyList_New(0); ! return fields; ! } ! ! Py_INCREF(Py_None); ! return Py_None; ! } ! ! /* ---------------------------------------------------------------- */ ! ! PyDoc_STRVAR(Parser_clear_doc, ! "clear() -> None\n" ! "\n" ! "Discard partially parsed record. This must be called to reset\n" ! "parser state after an exception."); ! ! static PyObject * ! Parser_clear(ParserObj *self, PyObject *args) ! { ! if (!PyArg_ParseTuple(args, "")) ! return NULL; ! ! clear_fields_and_status(self); ! ! Py_INCREF(Py_None); ! return Py_None; ! } ! ! /* ---------------------------------------------------------------- */ ! static void ! join_reset(ParserObj *self) ! { ! self->rec_len = 0; ! self->num_fields = 0; ! } ! ! #define MEM_INCR 32768 ! ! /* Calculate new record length or append field to record. Return new ! * record length. ! */ ! static int ! join_append_data(ParserObj *self, char *field, int quote_empty, ! int *quoted, int copy_phase) ! { ! int i, rec_len; ! ! rec_len = self->rec_len; ! ! /* If this is not the first field we need a field separator. ! */ ! if (self->num_fields > 0) { ! if (copy_phase) ! self->rec[rec_len] = self->field_sep; ! rec_len++; ! } ! /* We only know about quoted in the copy phase. ! */ ! if (copy_phase && *quoted) { ! self->rec[rec_len] = self->quote_char; ! rec_len++; ! } ! for (i = 0;; i++) { ! char c = field[i]; ! ! if (c == '\0') ! break; ! /* If in MS double quote mode we escape quote chars with a ! * quote. ! */ ! if (c == self->quote_char && self->ms_double_quote) { ! if (copy_phase) ! self->rec[rec_len] = self->quote_char; ! *quoted = 1; ! rec_len++; ! } ! /* Some special characters need to be escaped. If we have a ! * quote character switch to quoted field instead of escaping ! * individual characters. ! */ ! if (!*quoted ! && (c == self->field_sep || c == self->escape_char ! || c == '\n' || c == '\r')) { ! if (self->quote_char) ! *quoted = 1; ! else if (self->escape_char) { ! if (copy_phase) ! self->rec[rec_len] = self->escape_char; ! rec_len++; ! } ! } ! /* Copy field character into record buffer. ! */ ! if (copy_phase) ! self->rec[rec_len] = c; ! rec_len++; ! } ! ! /* If field is empty check if it needs to be quoted. ! */ ! if (i == 0 && quote_empty && self->quote_char) ! *quoted = 1; ! ! /* Handle final quote character on field. ! */ ! if (*quoted) { ! if (copy_phase) ! self->rec[rec_len] = self->quote_char; ! else ! /* Didn't know about leading quote until we found it ! * necessary in field data - compensate for it now. ! */ ! rec_len++; ! rec_len++; ! } ! ! return rec_len; ! } ! ! static int ! join_append(ParserObj *self, char *field, int quote_empty) ! { ! int rec_len, quoted; ! ! quoted = 0; ! rec_len = join_append_data(self, field, quote_empty, "ed, 0); ! ! /* grow record buffer if necessary */ ! if (rec_len > self->rec_size) { ! if (self->rec_size == 0) { ! self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR; ! self->rec = PyMem_Malloc(self->rec_size); ! } else { ! char *old_rec = self->rec; ! ! self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR; ! self->rec = PyMem_Realloc(self->rec, self->rec_size); ! if (self->rec == NULL) ! free(old_rec); ! } ! if (self->rec == NULL) { ! PyErr_NoMemory(); ! return 0; ! } ! } ! ! self->rec_len = join_append_data(self, field, quote_empty, "ed, 1); ! self->num_fields++; ! ! return 1; ! } ! ! static PyObject * ! join_string(ParserObj *self) ! { ! return PyString_FromStringAndSize(self->rec, self->rec_len); ! } ! ! PyDoc_STRVAR(Parser_join_doc, ! "join(sequence) -> string\n" ! "\n" ! "Construct a CSV record from a sequence of fields. Non-string\n" ! "elements will be converted to string."); ! ! static PyObject * ! Parser_join(ParserObj *self, PyObject *args) ! { ! PyObject *seq; ! int len, i; ! ! if (!PyArg_ParseTuple(args, "O", &seq)) ! return NULL; ! if (!PySequence_Check(seq)) ! return raise_exception("sequence expected"); ! ! len = PySequence_Length(seq); ! if (len < 0) ! return NULL; ! ! join_reset(self); ! for (i = 0; i < len; i++) { ! PyObject *field; ! int append_ok; ! ! field = PySequence_GetItem(seq, i); ! if (field == NULL) ! return NULL; ! ! if (PyString_Check(field)) { ! append_ok = join_append(self, PyString_AsString(field), len == 1); ! Py_DECREF(field); ! } else if (field == Py_None) { ! append_ok = join_append(self, "", len == 1); ! Py_DECREF(field); ! } else { ! PyObject *str; ! ! str = PyObject_Str(field); ! Py_DECREF(field); ! if (str == NULL) ! return NULL; ! ! append_ok = join_append(self, PyString_AsString(str), len == 1); ! Py_DECREF(str); ! } ! if (!append_ok) ! return NULL; ! } ! ! return join_string(self); ! } ! ! static struct PyMethodDef Parser_methods[] = { ! { "parse", (PyCFunction)Parser_parse, METH_VARARGS, ! Parser_parse_doc }, ! { "clear", (PyCFunction)Parser_clear, METH_VARARGS, ! Parser_clear_doc }, ! { "join", (PyCFunction)Parser_join, METH_VARARGS, ! Parser_join_doc }, ! { NULL, NULL } ! }; ! ! static void ! Parser_dealloc(ParserObj *self) ! { ! if (self->field) ! free(self->field); ! if (self->fields) { ! Py_XDECREF(self->fields); ! } ! if (self->rec) ! free(self->rec); ! ! PyMem_DEL(self); ! } ! ! #define OFF(x) offsetof(ParserObj, x) ! ! static struct memberlist Parser_memberlist[] = { ! { "ms_double_quote", T_INT, OFF(ms_double_quote) }, ! { "fields", T_OBJECT, OFF(fields) }, ! { "field_sep", T_CHAR, OFF(field_sep) }, ! { "quote_char", T_CHAR, OFF(quote_char) }, ! { "escape_char", T_CHAR, OFF(escape_char) }, ! { "auto_clear", T_INT, OFF(auto_clear) }, ! { "strict", T_INT, OFF(strict) }, ! { "had_parse_error", T_INT, OFF(had_parse_error), RO }, ! ! { NULL } /* Sentinel */ ! }; ! ! static PyObject * ! Parser_getattr(ParserObj *self, char *name) ! { ! PyObject *rv; ! ! rv = PyMember_Get((char *)self, Parser_memberlist, name); ! if (rv) ! return rv; ! PyErr_Clear(); ! return Py_FindMethod(Parser_methods, (PyObject *)self, name); ! } ! ! static int ! _set_char_attr(char *attr, PyObject *v) ! { ! /* Special case for constructor - NULL == use default. ! */ ! if (v == NULL) ! return 0; ! ! if (v == Py_None) { ! *attr = 0; ! return 0; ! } else if (PyInt_Check(v) && PyInt_AsLong(v) == 0) { ! *attr = 0; ! return 0; ! } else if (PyString_Check(v) && PyString_Size(v) == 1) { ! *attr = PyString_AsString(v)[0]; ! return 0; ! } else { ! PyErr_BadArgument(); ! return -1; ! } ! } ! ! static int ! Parser_setattr(ParserObj *self, char *name, PyObject *v) ! { ! if (v == NULL) { ! PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute"); ! return -1; ! } ! if (strcmp(name, "field_sep") == 0) ! return _set_char_attr(&self->field_sep, v); ! else if (strcmp(name, "quote_char") == 0) ! return _set_char_attr(&self->quote_char, v); ! else if (strcmp(name, "escape_char") == 0) ! return _set_char_attr(&self->escape_char, v); ! else ! return PyMember_Set((char *)self, Parser_memberlist, name, v); ! } ! ! static PyObject * ! csv_parser(PyObject *module, PyObject *args, PyObject *keyword_args); ! ! PyDoc_STRVAR(Parser_Type_doc, "CSV parser"); ! ! static PyTypeObject Parser_Type = { ! PyObject_HEAD_INIT(0) ! 0, /*ob_size*/ ! "_csv.parser", /*tp_name*/ ! sizeof(ParserObj), /*tp_basicsize*/ ! 0, /*tp_itemsize*/ ! /* methods */ ! (destructor)Parser_dealloc, /*tp_dealloc*/ ! (printfunc)0, /*tp_print*/ ! (getattrfunc)Parser_getattr, /*tp_getattr*/ ! (setattrfunc)Parser_setattr, /*tp_setattr*/ ! (cmpfunc)0, /*tp_compare*/ ! (reprfunc)0, /*tp_repr*/ ! 0, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ ! (hashfunc)0, /*tp_hash*/ ! (ternaryfunc)0, /*tp_call*/ ! (reprfunc)0, /*tp_str*/ ! ! 0L, 0L, 0L, 0L, ! Parser_Type_doc ! }; ! ! PyDoc_STRVAR(csv_parser_doc, ! "parser(ms_double_quote = 1, field_sep = ',',\n" ! " auto_clear = 1, strict = 0,\n" ! " quote_char = '\"', escape_char = None) -> Parser\n" ! "\n" ! "Constructs a CSV parser object. \n" ! "\n" ! " ms_double_quote\n" ! " When True, quotes in a fields must be doubled up.\n" ! "\n" ! " field_sep\n" ! " Defines the character that will be used to separate\n" ! " fields in the CSV record.\n" ! "\n" ! " auto_clear\n" ! " When True, calling parse() will automatically call\n" ! " the clear() method if the previous call to parse() raised an\n" ! " exception during parsing.\n" ! "\n" ! " strict\n" ! " When True, the parser will raise an exception on\n" ! " malformed fields rather than attempting to guess the right\n" ! " behavior.\n" ! "\n" ! " quote_char\n" ! " Defines the character used to quote fields that\n" ! " contain the field separator or newlines. If set to None\n" ! " special characters will be escaped using the escape_char.\n" ! "\n" ! " escape_char\n" ! " Defines the character used to escape special\n" ! " characters. Only used if quote_char is None.\n"); ! ! static PyObject * ! csv_parser(PyObject *module, PyObject *args, PyObject *keyword_args) ! { ! static char *keywords[] = { ! "ms_double_quote", "field_sep", "auto_clear", "strict", ! "quote_char", "escape_char", NULL ! }; ! PyObject *quote_char, *escape_char; ! ParserObj *self = PyObject_NEW(ParserObj, &Parser_Type); ! ! if (self == NULL) ! return NULL; ! ! self->state = START_RECORD; ! self->fields = PyList_New(0); ! self->ms_double_quote = 1; ! self->auto_clear = 1; ! self->strict = 0; ! self->field_sep = ','; ! quote_char = escape_char = NULL; ! self->quote_char = '"'; ! self->escape_char = '\0'; ! ! self->had_parse_error = 0; ! ! self->field = NULL; ! self->field_size = 0; ! self->field_len = 0; ! ! self->rec = NULL; ! self->rec_size = 0; ! self->rec_len = 0; ! self->num_fields = 0; ! ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|iciiOO", ! keywords, ! &self->ms_double_quote, ! &self->field_sep, ! &self->auto_clear, &self->strict, ! "e_char, &escape_char) ! && !_set_char_attr(&self->quote_char, quote_char) ! && !_set_char_attr(&self->escape_char, escape_char)) ! return (PyObject*)self; ! ! Py_DECREF(self); ! return NULL; ! } ! ! static struct PyMethodDef csv_methods[] = { ! { "parser", (PyCFunction)csv_parser, METH_VARARGS | METH_KEYWORDS, ! csv_parser_doc }, ! { NULL, NULL } ! }; ! ! PyDoc_STRVAR(csv_module_doc, ! "This module provides class for performing CSV parsing and writing.\n" ! "\n" ! "The CSV parser object (returned by the parser() function) supports the\n" ! "following methods:\n" ! " clear()\n" ! " Discards all fields parsed so far. If auto_clear is set to\n" ! " zero. You should call this after a parser exception.\n" ! "\n" ! " parse(string) -> list of strings\n" ! " Extracts fields from the (partial) CSV record in string.\n" ! " Trailing end of line characters are ignored, so you do not\n" ! " need to strip the string before passing it to the parser. If\n" ! " you pass more than a single line of text, a _csv.Error\n" ! " exception will be raised.\n" ! "\n" ! " join(sequence) -> string\n" ! " Construct a CSV record from a sequence of fields. Non-string\n" ! " elements will be converted to string.\n" ! "\n" ! "Typical usage:\n" ! "\n" ! " import _csv\n" ! " p = _csv.parser()\n" ! " fp = open('afile.csv', 'U')\n" ! " for line in fp:\n" ! " fields = p.parse(line)\n" ! " if not fields:\n" ! " # multi-line record\n" ! " continue\n" ! " # process the fields\n"); ! ! PyMODINIT_FUNC ! init_csv(void) ! { ! PyObject *mod; ! PyObject *dict; ! PyObject *rev; ! ! if (PyType_Ready(&Parser_Type) < 0) ! return; ! ! /* Create the module and add the functions */ ! mod = Py_InitModule3("_csv", csv_methods, csv_module_doc); ! if (mod == NULL) ! return; ! ! /* Add version to the module. */ ! dict = PyModule_GetDict(mod); ! if (dict == NULL) ! return; ! rev = PyString_FromString("1.0"); ! if (rev == NULL) ! return; ! if (PyDict_SetItemString(dict, "__version__", rev) < 0) ! return; ! ! /* Add the CSV exception object to the module. */ ! error_obj = PyErr_NewException("_csv.Error", NULL, NULL); ! if (error_obj == NULL) ! return; ! ! PyDict_SetItemString(dict, "Error", error_obj); ! ! Py_XDECREF(rev); ! Py_XDECREF(error_obj); ! } Index: setup.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/setup.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** setup.py 28 Jan 2003 02:07:46 -0000 1.1 --- setup.py 29 Jan 2003 11:21:34 -0000 1.2 *************** *** 1 **** ! # placeholder --- 1,12 ---- ! import distutils ! from distutils.core import setup, Extension ! ! setup(name = "_csv", ! description = "Fast CSV Parser", ! ext_modules = [ ! Extension('_csv', ! ['_csv.c'], ! ) ! ], ! ) ! From davecole@users.sourceforge.net Wed Jan 29 11:44:58 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Wed, 29 Jan 2003 03:44:58 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv setup.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv31532 Modified Files: setup.py Log Message: We also need to install the Python module - d'oh. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/setup.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** setup.py 29 Jan 2003 11:21:34 -0000 1.2 --- setup.py 29 Jan 2003 11:44:55 -0000 1.3 *************** *** 4,7 **** --- 4,8 ---- setup(name = "_csv", description = "Fast CSV Parser", + py_modules = ['csv'], ext_modules = [ Extension('_csv', From montanaro@users.sourceforge.net Wed Jan 29 13:37:02 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 29 Jan 2003 05:37:02 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv12189 Modified Files: pep-0305.txt Log Message: Belatedly added Dave and Andrew as authors. Changed Type to Standards Track. Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pep-0305.txt 29 Jan 2003 04:23:26 -0000 1.2 --- pep-0305.txt 29 Jan 2003 13:36:59 -0000 1.3 *************** *** 5,11 **** Author: Skip Montanaro , Kevin Altis , ! Cliff Wells Status: Draft ! Type: Informational Content-Type: text/x-rst Created: 26-Jan-2003 --- 5,13 ---- Author: Skip Montanaro , Kevin Altis , ! Cliff Wells , ! Dave Cole , ! Andrew McNamara Status: Draft ! Type: Standards Track Content-Type: text/x-rst Created: 26-Jan-2003 From just@letterror.com Wed Jan 29 13:59:31 2003 From: just@letterror.com (Just van Rossum) Date: Wed, 29 Jan 2003 14:59:31 +0100 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.118,1.119 In-Reply-To: Message-ID: tim_one@users.sourceforge.net wrote: > Expect test_macostools and test_macfs to get skipped whenever > sys.platform != mac. [ ... ] [ ... ] > + if sys.platform != "mac": > + self.expected.add("test_macostools") > + self.expected.add("test_macfs") [ ... ] Jack, I think this should include sys.platform != "darwin", right? Just From montanaro@users.sourceforge.net Wed Jan 29 14:09:48 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 29 Jan 2003 06:09:48 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv27509 Modified Files: pep-0305.txt Log Message: started reorganizing the information about low-level formatting parameters. Define dialects in their own subsection. Define low-level parameters in a separate subsection. Define set_dialect() and get_dialect() module-level functions. More to be done, but I have to get to work... ;-) Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pep-0305.txt 29 Jan 2003 13:36:59 -0000 1.3 --- pep-0305.txt 29 Jan 2003 14:09:45 -0000 1.4 *************** *** 62,76 **** The module supports two basic APIs, one for reading and one for ! writing. The reading interface is:: ! reader(fileobj [, dialect='excel2000'] ! [, quotechar='"'] ! [, delimiter=','] ! [, skipinitialspace=False]) A reader object is an iterable which takes a file-like object opened ! for reading as the sole required parameter. It also accepts four ! optional parameters (discussed below). Readers are typically used as ! follows:: csvreader = csv.reader(file("some.csv")) --- 62,74 ---- The module supports two basic APIs, one for reading and one for ! writing. The basic reading interface is:: ! reader(fileobj [, dialect='excel2000']) A reader object is an iterable which takes a file-like object opened ! for reading as the sole required parameter. The optional dialect ! parameter is discussed below. It also accepts several keyword ! parameters which define specific format settings (see the section ! "Formatting Parameters"). Readers are typically used as follows:: csvreader = csv.reader(file("some.csv")) *************** *** 80,91 **** The writing interface is similar:: ! writer(fileobj [, dialect='excel2000'] ! [, quotechar='"'] ! [, delimiter=','] ! [, skipinitialspace=False]) A writer object is a wrapper around a file-like object opened for ! writing. It accepts the same four optional parameters as the reader ! constructor. Writers are typically used as follows:: csvwriter = csv.writer(file("some.csv", "w")) --- 78,91 ---- The writing interface is similar:: ! writer(fileobj [, dialect='excel2000'], [, fieldnames=list]) A writer object is a wrapper around a file-like object opened for ! writing. It accepts the same keyword parameters as the reader ! constructor. In addition, it accepts an optional fieldnames ! argument. This is a list which defines the order of fields in the ! output file. It allows the write() method to accept mapping objects ! as well as sequence objects. ! ! Writers are typically used as follows:: csvwriter = csv.writer(file("some.csv", "w")) *************** *** 93,109 **** csvwriter.write(row) ! Optional Parameters ! ------------------- - Both the reader and writer constructors take four optional keyword - parameters: ! - dialect is an easy way of specifying a complete set of format ! constraints for a reader or writer. Most people will know what ! application generated a CSV file or what application will process ! the CSV file they are generating, but not the precise settings ! necessary. The only dialect defined initially is "excel2000". The ! dialect parameter is interpreted in a case-insensitive manner. - quotechar specifies a one-character string to use as the quoting --- 93,132 ---- csvwriter.write(row) + To generate a set of field names as the first row of the CSV file, the + programmer must explicitly write it, e.g.:: ! csvwriter = csv.writer(file("some.csv", "w"), fieldnames=names) ! csvwriter.write(names) ! for row in someiterable: ! csvwriter.write(row) ! Dialects ! -------- ! ! Readers and writers support a dialect argument which is just a ! convenient (string) handle on a group of lower level parameters. ! Dialects will generally be named after applications or organizations ! which define specific sets of format constraints. The initial dialect ! is "excel2000", which describes the format constraints of Excel 2000's ! CSV format. Another possible dialect (used here only as an example) ! might be "gnumeric". ! ! Two functions are defined in the API to set and retrieve dialects:: ! ! set_dialect(dialect, pdict) ! pdict = get_dialect(dialect) ! ! The pdict parameter is a dictionary whose keys are the names the ! formatting parameters defined in the next section. ! ! ! Formatting Parameters ! --------------------- ! ! Both the reader and writer constructors take several specific ! formatting parameters, specified as keyword parameters. The ! parameters are also the keys for the input and output mapping objects ! for the set_dialect() and get_dialect() module functions. - quotechar specifies a one-character string to use as the quoting *************** *** 117,120 **** --- 140,148 ---- that whitespace immediate following a delimiter is part of the following field. + + - lineterminator specifies the character sequence which should + terminate rows. + + ... XXX More to come XXX ... When processing a dialect setting and one or more of the other From andrewmcnamara@users.sourceforge.net Wed Jan 29 14:18:22 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Wed, 29 Jan 2003 06:18:22 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv README,1.1,1.2 csv.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv32266 Modified Files: README csv.py Log Message: Simplistic python module to implement some of the proposed PEP on top of the existing C _csv module. Index: README =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/README,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** README 28 Jan 2003 02:07:46 -0000 1.1 --- README 29 Jan 2003 14:18:20 -0000 1.2 *************** *** 1,5 **** This little corner of the sandbox aims to create a module to read and write CSV files. Involved parties are currently Kevin Altis, Dave Cole, Skip ! Montanaro and Cliff Wells. Stay tuned... --- 1,5 ---- This little corner of the sandbox aims to create a module to read and write CSV files. Involved parties are currently Kevin Altis, Dave Cole, Skip ! Montanaro, Cliff Wells and Andrew McNamara. Stay tuned... Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** csv.py 28 Jan 2003 02:07:46 -0000 1.1 --- csv.py 29 Jan 2003 14:18:20 -0000 1.2 *************** *** 1 **** ! # placeholder --- 1,71 ---- ! import _csv ! ! class excel2000: ! pass ! ! class excel2000_tab: ! field_sep='\t' ! ! dialects = { ! 'excel': excel2000, ! 'excel2000': excel2000, ! 'excel-tab': excel2000_tab, ! 'excel2000-tab': excel2000_tab, ! } ! ! class Error(Exception): ! pass ! ! class OCcvs: ! def __init__(self, dialect, **options): ! try: ! dialect_obj = dialects[dialect] ! except KeyError: ! raise Error('Unknown dialect') ! parser_options = {} ! for attr in dir(dialect_obj): ! if attr[0] == '_': ! continue ! parser_options[attr] = getattr(dialect_obj, attr) ! parser_options.update(options) ! try: ! self.parser = _csv.parser(**parser_options) ! except _csv.Error, e: ! raise Error(e) ! ! class reader(OCcvs): ! def __init__(self, fileobj, dialect = 'excel2000', **options): ! self.fileobj = fileobj ! OCcvs.__init__(self, dialect, **options) ! ! def __iter__(self): ! return self ! ! def next(self): ! while 1: ! fields = self.parser.parse(self.fileobj.next()) ! if fields: ! return fields ! ! class writer(OCcvs): ! def __init__(self, fileobj, dialect='excel2000', **options): ! self.fileobj = fileobj ! OCcvs.__init__(self, dialect, **options) ! ! def write(self, fields): ! self.fileobj.write(self.parser.join(fields) + '\n') ! ! def writelines(self, lines): ! for fields in lines: ! self.write(fields) ! ! def close(self): ! self.fileobj.close() ! del self.fileobj ! ! def __del__(self): ! if hasattr(self, 'fileobj'): ! try: ! self.close() ! except: ! pass From mwh@users.sourceforge.net Wed Jan 29 14:20:25 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Wed, 29 Jan 2003 06:20:25 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_parser.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv675/Lib/test Modified Files: test_parser.py Log Message: Teach the parsermodule about floor division. Fixes [ 676521 ] parser module validation failure bugfix candidate. Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_parser.py 22 Aug 2002 19:43:51 -0000 1.13 --- test_parser.py 29 Jan 2003 14:20:23 -0000 1.14 *************** *** 52,55 **** --- 52,59 ---- self.check_expr("foo(a, b, c, **kw)") self.check_expr("foo + bar") + self.check_expr("foo - bar") + self.check_expr("foo * bar") + self.check_expr("foo / bar") + self.check_expr("foo // bar") self.check_expr("lambda: 0") self.check_expr("lambda x: 0") *************** *** 86,89 **** --- 90,94 ---- self.check_suite("a *= b") self.check_suite("a /= b") + self.check_suite("a //= b") self.check_suite("a %= b") self.check_suite("a &= b") From mwh@users.sourceforge.net Wed Jan 29 14:20:25 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Wed, 29 Jan 2003 06:20:25 -0800 Subject: [Python-checkins] python/dist/src/Modules parsermodule.c,2.74,2.75 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv675/Modules Modified Files: parsermodule.c Log Message: Teach the parsermodule about floor division. Fixes [ 676521 ] parser module validation failure bugfix candidate. Index: parsermodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v retrieving revision 2.74 retrieving revision 2.75 diff -C2 -d -r2.74 -r2.75 *** parsermodule.c 31 Dec 2002 18:17:43 -0000 2.74 --- parsermodule.c 29 Jan 2003 14:20:22 -0000 2.75 *************** *** 1441,1444 **** --- 1441,1445 ---- || strcmp(s, "*=") == 0 || strcmp(s, "/=") == 0 + || strcmp(s, "//=") == 0 || strcmp(s, "%=") == 0 || strcmp(s, "&=") == 0 *************** *** 2096,2099 **** --- 2097,2101 ---- res = (((TYPE(CHILD(tree, pos)) == STAR) || (TYPE(CHILD(tree, pos)) == SLASH) + || (TYPE(CHILD(tree, pos)) == DOUBLESLASH) || (TYPE(CHILD(tree, pos)) == PERCENT)) && validate_factor(CHILD(tree, pos + 1))); From goodger@users.sourceforge.net Wed Jan 29 15:08:02 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Wed, 29 Jan 2003 07:08:02 -0800 Subject: [Python-checkins] python/nondist/peps pep-0000.txt,1.225,1.226 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv24312 Modified Files: pep-0000.txt Log Message: added PEP 306; 305 authors Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.225 retrieving revision 1.226 diff -C2 -d -r1.225 -r1.226 *** pep-0000.txt 29 Jan 2003 04:20:19 -0000 1.225 --- pep-0000.txt 29 Jan 2003 15:07:58 -0000 1.226 *************** *** 107,111 **** S 303 Extend divmod() for Multiple Divisors Bellman S 304 Controlling Generation of Bytecode Files Montanaro ! I 305 CSV File API Montanaro, Altis, Wells Finished PEPs (done, implemented in CVS) --- 107,112 ---- S 303 Extend divmod() for Multiple Divisors Bellman S 304 Controlling Generation of Bytecode Files Montanaro ! I 305 CSV File API Montanaro, et al ! I 306 How to Change Python's Grammar Hudson Finished PEPs (done, implemented in CVS) *************** *** 302,306 **** S 303 Extend divmod() for Multiple Divisors Bellman S 304 Controlling Generation of Bytecode Files Montanaro ! I 305 CSV File API Montanaro, Altis, Wells SR 666 Reject Foolish Indentation Creighton --- 303,308 ---- S 303 Extend divmod() for Multiple Divisors Bellman S 304 Controlling Generation of Bytecode Files Montanaro ! I 305 CSV File API Montanaro, et al ! I 306 How to Change Python's Grammar Hudson SR 666 Reject Foolish Indentation Creighton *************** *** 328,331 **** --- 330,334 ---- Baxter, Anthony anthony@interlink.com.au Bellman, Thomas bellman+pep-divmod@lysator.liu.se + Cole, Dave djc@object-craft.com.au Craig, Christopher python-pep@ccraig.org Creighton, Laura lac@strakt.com *************** *** 357,360 **** --- 360,364 ---- Martelli, Alex aleax@aleax.it McMillan, Gordon gmcm@hypernet.com + McNamara, Andrew andrewm@object-craft.com.au Mick, Trent trentm@activestate.com Montanaro, Skip skip@pobox.com From goodger@users.sourceforge.net Wed Jan 29 15:07:20 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Wed, 29 Jan 2003 07:07:20 -0800 Subject: [Python-checkins] python/nondist/peps pep-0306.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv23948 Added Files: pep-0306.txt Log Message: How to Change Python's Grammar --- NEW FILE: pep-0306.txt --- PEP: 306 Title: How to Change Python's Grammar Version: $Revision: 1.1 $ Last-Modified: $Date: 2003/01/29 15:07:17 $ Author: Michael Hudson Status: Draft Type: Informational Content-Type: text/plain Created: 29-Jan-2003 Post-History: Abstract There's more to changing Python's grammar than editing Grammar/Grammar and Python/compile.c. This PEP aims to be a checklist of places that must also be fixed. It is probably incomplete. If you see omissions, just add them if you can -- you are not going to offend the author's sense of ownership. Otherwise submit a bug or patch and assign it to mwh. This PEP is not intended to be an instruction manual on Python grammar hacking. Rationale People are getting this wrong all the time; it took well over a year before someone noticed[1] that adding the floor division operator (//) broke the parser module. Checklist __ Grammar/Grammar: OK, you'd probably worked this one out :) __ Python/compile.c: you'll most likely need to edit both the actual compiler and the symtable builder (which is to say both the com_foo and the sym_foo functions). __ You may need to regenerate Lib/symbol.py and/or Lib/token.py. __ The parser module. Add some of your new syntax to test_parser, bang on parsermodule.c until it passes. __ The compiler package. A good test is to compile the standard library and test suite with the compiler package and then check it runs. You did add some of your new syntax to the test suite, didn't you? There's a script in Tools/compiler that does this. References [1] SF Bug #676521, parser module validation failure http://www.python.org/sf/676521 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: From montanaro@users.sourceforge.net Wed Jan 29 15:41:39 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 29 Jan 2003 07:41:39 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv7051 Modified Files: pickletools.py Log Message: minor grammar tweaks Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** pickletools.py 29 Jan 2003 06:24:30 -0000 1.20 --- pickletools.py 29 Jan 2003 15:41:33 -0000 1.21 *************** *** 1,3 **** ! """"Executable documentation" for the pickle module. Extensive comments about the pickle protocols and pickle-machine opcodes --- 1,3 ---- ! '''"Executable documentation" for the pickle module. Extensive comments about the pickle protocols and pickle-machine opcodes *************** *** 9,13 **** dis(pickle, out=None, indentlevel=4) Print a symbolic disassembly of a pickle. ! """ # Other ideas: --- 9,13 ---- dis(pickle, out=None, indentlevel=4) Print a symbolic disassembly of a pickle. ! ''' # Other ideas: *************** *** 127,134 **** PUT). ! Another, independent change with Python 2.3 is the abandonment of any ! pretense that it might be safe to pickles received from untrusted parties -- no sufficient security analysis has been done to guarantee ! this and there isn't a use case to warrants the expense of such an analysis. --- 127,134 ---- PUT). ! Another independent change with Python 2.3 is the abandonment of any ! pretense that it might be safe to load pickles received from untrusted parties -- no sufficient security analysis has been done to guarantee ! this and there isn't a use case that warrants the expense of such an analysis. From jackjansen@users.sourceforge.net Wed Jan 29 16:24:26 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 29 Jan 2003 08:24:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.119,1.120 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv1379 Modified Files: regrtest.py Log Message: - The mac-specific tests should also be run on darwin. - Added test_aepack to the mac/darwin specific tests. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.119 retrieving revision 1.120 diff -C2 -d -r1.119 -r1.120 *** regrtest.py 29 Jan 2003 00:35:32 -0000 1.119 --- regrtest.py 29 Jan 2003 16:24:16 -0000 1.120 *************** *** 916,922 **** self.expected.add('test_socket_ssl') ! if sys.platform != "mac": self.expected.add("test_macostools") self.expected.add("test_macfs") if sys.platform != "win32": --- 916,923 ---- self.expected.add('test_socket_ssl') ! if not sys.platform in ("mac", "darwin"): self.expected.add("test_macostools") self.expected.add("test_macfs") + self.expected.add("test_aepack") if sys.platform != "win32": From gvanrossum@users.sourceforge.net Wed Jan 29 16:58:35 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 08:58:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils/command build_scripts.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory sc8-pr-cvs1:/tmp/cvs-serv32120 Modified Files: build_scripts.py Log Message: Only log a message and chmod() when the mode isn't already what we want it to be. Log both the old and new mode. Index: build_scripts.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/build_scripts.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** build_scripts.py 24 Jan 2003 14:56:52 -0000 1.19 --- build_scripts.py 29 Jan 2003 16:58:31 -0000 1.20 *************** *** 115,121 **** log.info("changing mode of %s", file) else: ! mode = ((os.stat(file)[ST_MODE]) | 0555) & 07777 ! log.info("changing mode of %s to %o", file, mode) ! os.chmod(file, mode) # copy_scripts () --- 115,124 ---- log.info("changing mode of %s", file) else: ! oldmode = os.stat(file)[ST_MODE] & 07777 ! newmode = (oldmode | 0555) & 07777 ! if newmode != oldmode: ! log.info("changing mode of %s from %o to %o", ! file, oldmode, newmode) ! os.chmod(file, newmode) # copy_scripts () From walter@livinglogic.de Wed Jan 29 17:01:48 2003 From: walter@livinglogic.de (=?ISO-8859-15?Q?Walter_D=F6rwald?=) Date: Wed, 29 Jan 2003 18:01:48 +0100 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 In-Reply-To: References: Message-ID: <3E3808FC.9070508@livinglogic.de> loewis@users.sourceforge.net wrote: > Update of /cvsroot/python/python/dist/src/Modules > In directory sc8-pr-cvs1:/tmp/cvs-serv2026/Modules > > Added Files: > _iconv_codec.c > Log Message: > Patch #670715: Universal Unicode Codec for POSIX iconv. > [...] > if (newpos < 0) > newpos = inputlen - newpos; > [...] > if (newpos < 0) > newpos = inplen_total - newpos; As newpos is negative, I'd say this should be newpos = inputlen + newpos; newpos = inplen_total + newpos; Bye, Walter Dörwald From gvanrossum@users.sourceforge.net Wed Jan 29 17:58:46 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 09:58:46 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.122,1.123 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv6662/Lib Modified Files: pickle.py Log Message: Implement appropriate __getnewargs__ for all immutable subclassable builtin types. The special handling for these can now be removed from save_newobj(). Add some testing for this. Also add support for setting the 'fast' flag on the Python Pickler class, which suppresses use of the memo. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.122 retrieving revision 1.123 diff -C2 -d -r1.122 -r1.123 *** pickle.py 29 Jan 2003 06:16:12 -0000 1.122 --- pickle.py 29 Jan 2003 17:58:43 -0000 1.123 *************** *** 192,195 **** --- 192,196 ---- self.proto = int(proto) self.bin = proto >= 1 + self.fast = 0 def clear_memo(self): *************** *** 231,234 **** --- 232,237 ---- # scheme allows the Unpickler memo to be implemented as a plain (but # growable) array, indexed by memo key. + if self.fast: + return memo_len = len(self.memo) self.write(self.put(memo_len)) *************** *** 379,390 **** args = getnewargs() # This bette not reference obj else: ! # XXX These types should each grow a __getnewargs__ ! # implementation so this special-casing is unnecessary. ! for cls in int, long, float, complex, str, UnicodeType, tuple: ! if cls and isinstance(obj, cls): ! args = (cls(obj),) ! break ! else: ! args = () save = self.save --- 382,386 ---- args = getnewargs() # This bette not reference obj else: ! args = () save = self.save From gvanrossum@users.sourceforge.net Wed Jan 29 17:58:46 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 09:58:46 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.29,1.30 test_pickle.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv6662/Lib/test Modified Files: pickletester.py test_pickle.py Log Message: Implement appropriate __getnewargs__ for all immutable subclassable builtin types. The special handling for these can now be removed from save_newobj(). Add some testing for this. Also add support for setting the 'fast' flag on the Python Pickler class, which suppresses use of the memo. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** pickletester.py 29 Jan 2003 06:12:46 -0000 1.29 --- pickletester.py 29 Jan 2003 17:58:44 -0000 1.30 *************** *** 325,328 **** --- 325,343 ---- ## pickletools.dis(s) + def test_newobj_generic(self): + for proto in [0, 1, 2]: + for C in myclasses: + B = C.__base__ + x = C(C.sample) + x.foo = 42 + s = self.dumps(x, proto) + ## import pickletools + ## print + ## pickletools.dis(s) + y = self.loads(s) + detail = (proto, C, B, x, y, type(y)) + self.assertEqual(B(x), B(y), detail) + self.assertEqual(x.__dict__, y.__dict__, detail) + # XXX Temporary hack, so long as the C implementation of pickle protocol # XXX 2 isn't ready. When it is, move the methods in TempAbstractPickleTests *************** *** 406,414 **** copy_reg.remove_extension(__name__, "MyList", 0xfffff0) class MyTuple(tuple): ! pass class MyList(list): ! pass class SlotList(MyList): --- 421,456 ---- copy_reg.remove_extension(__name__, "MyList", 0xfffff0) + class MyInt(int): + sample = 1 + + class MyLong(long): + sample = 1L + + class MyFloat(float): + sample = 1.0 + + class MyComplex(complex): + sample = 1.0 + 0.0j + + class MyStr(str): + sample = "hello" + + class MyUnicode(unicode): + sample = u"hello \u1234" + class MyTuple(tuple): ! sample = (1, 2, 3) class MyList(list): ! sample = [1, 2, 3] ! ! class MyDict(dict): ! sample = {"a": 1, "b": 2} ! ! myclasses = [MyInt, MyLong, MyFloat, ! # MyComplex, # XXX complex somehow doesn't work here :-( ! MyStr, MyUnicode, ! MyTuple, MyList, MyDict] ! class SlotList(MyList): Index: test_pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pickle.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** test_pickle.py 28 Jan 2003 22:34:11 -0000 1.14 --- test_pickle.py 29 Jan 2003 17:58:44 -0000 1.15 *************** *** 12,18 **** class PickleTests(AbstractPickleTests, AbstractPickleModuleTests, XXXTemp): ! def setUp(self): ! self.dumps = pickle.dumps ! self.loads = pickle.loads module = pickle --- 12,22 ---- class PickleTests(AbstractPickleTests, AbstractPickleModuleTests, XXXTemp): ! def dumps(self, arg, proto=0, fast=0): ! # Ignore fast ! return pickle.dumps(arg, proto) ! ! def loads(self, buf): ! # Ignore fast ! return pickle.loads(buf) module = pickle *************** *** 23,29 **** error = KeyError ! def dumps(self, arg, proto=0): f = StringIO() p = pickle.Pickler(f, proto) p.dump(arg) f.seek(0) --- 27,35 ---- error = KeyError ! def dumps(self, arg, proto=0, fast=0): f = StringIO() p = pickle.Pickler(f, proto) + if fast: + p.fast = fast p.dump(arg) f.seek(0) *************** *** 37,41 **** class PersPicklerTests(AbstractPersistentPicklerTests): ! def dumps(self, arg, proto=0): class PersPickler(pickle.Pickler): def persistent_id(subself, obj): --- 43,47 ---- class PersPicklerTests(AbstractPersistentPicklerTests): ! def dumps(self, arg, proto=0, fast=0): class PersPickler(pickle.Pickler): def persistent_id(subself, obj): *************** *** 43,46 **** --- 49,54 ---- f = StringIO() p = PersPickler(f, proto) + if fast: + p.fast = fast p.dump(arg) f.seek(0) From gvanrossum@users.sourceforge.net Wed Jan 29 17:58:48 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 09:58:48 -0800 Subject: [Python-checkins] python/dist/src/Objects complexobject.c,2.64,2.65 floatobject.c,2.119,2.120 intobject.c,2.99,2.100 longobject.c,1.147,1.148 stringobject.c,2.204,2.205 tupleobject.c,2.75,2.76 unicodeobject.c,2.178,2.179 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv6662/Objects Modified Files: complexobject.c floatobject.c intobject.c longobject.c stringobject.c tupleobject.c unicodeobject.c Log Message: Implement appropriate __getnewargs__ for all immutable subclassable builtin types. The special handling for these can now be removed from save_newobj(). Add some testing for this. Also add support for setting the 'fast' flag on the Python Pickler class, which suppresses use of the memo. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.64 retrieving revision 2.65 diff -C2 -d -r2.64 -r2.65 *** complexobject.c 29 Aug 2002 14:22:50 -0000 2.64 --- complexobject.c 29 Jan 2003 17:58:44 -0000 2.65 *************** *** 640,645 **** --- 640,652 ---- } + static PyObject * + complex_getnewargs(PyComplexObject *v) + { + return Py_BuildValue("(D)", v->cval); + } + static PyMethodDef complex_methods[] = { {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS}, + {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.119 retrieving revision 2.120 diff -C2 -d -r2.119 -r2.120 *** floatobject.c 28 Jan 2003 19:21:24 -0000 2.119 --- floatobject.c 29 Jan 2003 17:58:45 -0000 2.120 *************** *** 727,730 **** --- 727,741 ---- } + static PyObject * + float_getnewargs(PyFloatObject *v) + { + return Py_BuildValue("(d)", v->ob_fval); + } + + static PyMethodDef float_methods[] = { + {"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS}, + {NULL, NULL} /* sentinel */ + }; + PyDoc_STRVAR(float_doc, "float(x) -> floating point number\n\ *************** *** 804,808 **** 0, /* tp_iter */ 0, /* tp_iternext */ ! 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ --- 815,819 ---- 0, /* tp_iter */ 0, /* tp_iternext */ ! float_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.99 retrieving revision 2.100 diff -C2 -d -r2.99 -r2.100 *** intobject.c 19 Jan 2003 15:40:09 -0000 2.99 --- intobject.c 29 Jan 2003 17:58:45 -0000 2.100 *************** *** 851,854 **** --- 851,865 ---- } + static PyObject * + int_getnewargs(PyIntObject *v) + { + return Py_BuildValue("(l)", v->ob_ival); + } + + static PyMethodDef int_methods[] = { + {"__getnewargs__", (PyCFunction)int_getnewargs, METH_NOARGS}, + {NULL, NULL} /* sentinel */ + }; + PyDoc_STRVAR(int_doc, "int(x[, base]) -> integer\n\ *************** *** 932,936 **** 0, /* tp_iter */ 0, /* tp_iternext */ ! 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ --- 943,947 ---- 0, /* tp_iter */ 0, /* tp_iternext */ ! int_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.147 retrieving revision 1.148 diff -C2 -d -r1.147 -r1.148 *** longobject.c 28 Jan 2003 20:37:45 -0000 1.147 --- longobject.c 29 Jan 2003 17:58:45 -0000 1.148 *************** *** 2647,2650 **** --- 2647,2661 ---- } + static PyObject * + long_getnewargs(PyLongObject *v) + { + return Py_BuildValue("(N)", _PyLong_Copy(v)); + } + + static PyMethodDef long_methods[] = { + {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS}, + {NULL, NULL} /* sentinel */ + }; + PyDoc_STRVAR(long_doc, "long(x[, base]) -> integer\n\ *************** *** 2727,2731 **** 0, /* tp_iter */ 0, /* tp_iternext */ ! 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ --- 2738,2742 ---- 0, /* tp_iter */ 0, /* tp_iternext */ ! long_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.204 retrieving revision 2.205 diff -C2 -d -r2.204 -r2.205 *** stringobject.c 15 Jan 2003 05:32:57 -0000 2.204 --- stringobject.c 29 Jan 2003 17:58:45 -0000 2.205 *************** *** 3046,3049 **** --- 3046,3055 ---- #undef SPLIT_APPEND + static PyObject * + string_getnewargs(PyStringObject *v) + { + return Py_BuildValue("(s#)", v->ob_sval, v->ob_size); + } + static PyMethodDef *************** *** 3092,3095 **** --- 3098,3102 ---- {"splitlines", (PyCFunction)string_splitlines, METH_VARARGS, splitlines__doc__}, + {"__getnewargs__", (PyCFunction)string_getnewargs, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.75 retrieving revision 2.76 diff -C2 -d -r2.75 -r2.76 *** tupleobject.c 11 Oct 2002 21:05:56 -0000 2.75 --- tupleobject.c 29 Jan 2003 17:58:45 -0000 2.76 *************** *** 588,591 **** --- 588,603 ---- } + static PyObject * + tuple_getnewargs(PyTupleObject *v) + { + return Py_BuildValue("(N)", tupleslice(v, 0, v->ob_size)); + + } + + static PyMethodDef tuple_methods[] = { + {"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS}, + {NULL, NULL} /* sentinel */ + }; + static PyMappingMethods tuple_as_mapping = { (inquiry)tuplelength, *************** *** 626,630 **** tuple_iter, /* tp_iter */ 0, /* tp_iternext */ ! 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ --- 638,642 ---- tuple_iter, /* tp_iter */ 0, /* tp_iternext */ ! tuple_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.178 retrieving revision 2.179 diff -C2 -d -r2.178 -r2.179 *** unicodeobject.c 8 Jan 2003 22:01:33 -0000 2.178 --- unicodeobject.c 29 Jan 2003 17:58:45 -0000 2.179 *************** *** 5742,5745 **** --- 5742,5753 ---- + + static PyObject * + unicode_getnewargs(PyUnicodeObject *v) + { + return Py_BuildValue("(u#)", v->str, v->length); + } + + static PyMethodDef unicode_methods[] = { *************** *** 5792,5795 **** --- 5800,5804 ---- #endif + {"__getnewargs__", (PyCFunction)unicode_getnewargs, METH_NOARGS}, {NULL, NULL} }; From montanaro@users.sourceforge.net Wed Jan 29 18:31:47 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 29 Jan 2003 10:31:47 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv .cvsignore,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv23438 Added Files: .cvsignore Log Message: cvs ignore file --- NEW FILE: .cvsignore --- build From montanaro@users.sourceforge.net Wed Jan 29 18:49:50 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 29 Jan 2003 10:49:50 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv816 Modified Files: pep-0304.txt Log Message: Feedback from Terry Reedy. Make the sys module attribute simply "bytecodebase". Give concrete examples of the augmented directory in the examples. Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0304.txt 29 Jan 2003 04:20:45 -0000 1.6 --- pep-0304.txt 29 Jan 2003 18:49:47 -0000 1.7 *************** *** 31,50 **** - If not present Python bytecode is generated in exactly the same way ! as is currently done. sys.pythonbytecodebase is set to the root directory (either / on Unix or the root directory of the startup drive -- typically ``C:\`` -- on Windows). - If present and it refers to an existing directory, ! sys.pythonbytecodebase is set to that directory and bytecode files are written into a directory structure rooted at that location. ! - If present but empty, sys.pythonbytecodebase is set to None and generation of bytecode files is suppressed altogether. - If present and it does not refer to an existing directory, a warning ! is displayed, sys.pythonbytecodebase is set to None and generation of bytecode files is suppressed altogether. ! After startup, all runtime references are to sys.pythonbytecodebase, not the PYTHONBYTECODEBASE environment variable. sys.path is not modified. --- 31,50 ---- - If not present Python bytecode is generated in exactly the same way ! as is currently done. sys.bytecodebase is set to the root directory (either / on Unix or the root directory of the startup drive -- typically ``C:\`` -- on Windows). - If present and it refers to an existing directory, ! sys.bytecodebase is set to that directory and bytecode files are written into a directory structure rooted at that location. ! - If present but empty, sys.bytecodebase is set to None and generation of bytecode files is suppressed altogether. - If present and it does not refer to an existing directory, a warning ! is displayed, sys.bytecodebase is set to None and generation of bytecode files is suppressed altogether. ! After startup, all runtime references are to sys.bytecodebase, not the PYTHONBYTECODEBASE environment variable. sys.path is not modified. *************** *** 55,59 **** - "bytecode base" refers to the current setting of ! sys.pythonbytecodebase. - "augmented directory" refers to the directory formed from the --- 55,59 ---- - "bytecode base" refers to the current setting of ! sys.bytecodebase. - "augmented directory" refers to the directory formed from the *************** *** 92,96 **** base. In a Unix environment this would be:: ! pcb = os.path.abspath(sys.pythonbytecodebase) if sourcefile[0] == os.sep: sourcefile = sourcefile[1:] augdir = os.path.join(pcb, os.path.dirname(sourcefile)) --- 92,96 ---- base. In a Unix environment this would be:: ! pcb = os.path.abspath(sys.bytecodebase) if sourcefile[0] == os.sep: sourcefile = sourcefile[1:] augdir = os.path.join(pcb, os.path.dirname(sourcefile)) *************** *** 101,105 **** augmented directory is thus derived as :: ! pcb = os.path.abspath(sys.pythonbytecodebase) drive, base = os.path.splitdrive(os.path.dirname(sourcefile)) drive = drive[:-1] --- 101,105 ---- augmented directory is thus derived as :: ! pcb = os.path.abspath(sys.bytecodebase) drive, base = os.path.splitdrive(os.path.dirname(sourcefile)) drive = drive[:-1] *************** *** 119,125 **** open(probe, "w") os.unlink(probe) ! sys.pythonbytecodebase = pcb except IOError: ! sys.pythonbytecodebase = None This allows the user to specify the bytecode base as a relative path, --- 119,125 ---- open(probe, "w") os.unlink(probe) ! sys.bytecodebase = pcb except IOError: ! sys.bytecodebase = None This allows the user to specify the bytecode base as a relative path, *************** *** 128,132 **** execution.) ! There is nothing special about sys.pythonbytecodebase. The user may change it at runtime if she so chooses, but normally it will not be modified. --- 128,132 ---- execution.) ! There is nothing special about sys.bytecodebase. The user may change it at runtime if she so chooses, but normally it will not be modified. *************** *** 181,185 **** if PYTHONBYTECODEBASE refers to a directory which is writable by anyone other than root. If so, it could raise an exception or ! warning and set sys.pythonbytecodebase to None. Or, see the next item. --- 181,185 ---- if PYTHONBYTECODEBASE refers to a directory which is writable by anyone other than root. If so, it could raise an exception or ! warning and set sys.bytecodebase to None. Or, see the next item. *************** *** 208,213 **** - The bytecode base is /tmp. /usr/lib/python2.3/urllib.pyc exists, but is out-of-date. When urllib is imported, the generated bytecode ! file is written to urllib.pyc in the augmented directory. ! Intermediate directories will be created as needed. - The bytecode base is None. No urllib.pyc file is found. When --- 208,214 ---- - The bytecode base is /tmp. /usr/lib/python2.3/urllib.pyc exists, but is out-of-date. When urllib is imported, the generated bytecode ! file is written to urllib.pyc in the augmented directory which has ! the value /tmp/usr/lib/python2.3. Intermediate directories will be ! created as needed. - The bytecode base is None. No urllib.pyc file is found. When *************** *** 216,231 **** - The bytecode base is /tmp. No urllib.pyc file is found. When urllib is imported, the generated bytecode file is written to the ! augmented directory, creating intermediate directories as needed. - At startup, PYTHONBYTECODEBASE is /tmp/foobar, which does not exist. ! A warning is emitted, sys.pythonbytecodebase is set to None and no bytecode files are written during program execution unless ! sys.pythonbytecodebase is later changed to refer to a valid, writable directory. - At startup, PYTHONBYTECODEBASE is set to /, which exists, but is not writable by the current user. A warning is emitted, ! sys.pythonbytecodebase is set to None and no bytecode files are ! written during program execution unless sys.pythonbytecodebase is later changed to refer to a valid, writable directory. Note that even though the augmented directory constructed for a particular --- 217,233 ---- - The bytecode base is /tmp. No urllib.pyc file is found. When urllib is imported, the generated bytecode file is written to the ! augmented directory which has the value /tmp/usr/lib/python2.3. ! Intermediate directories will be created as needed. - At startup, PYTHONBYTECODEBASE is /tmp/foobar, which does not exist. ! A warning is emitted, sys.bytecodebase is set to None and no bytecode files are written during program execution unless ! sys.bytecodebase is later changed to refer to a valid, writable directory. - At startup, PYTHONBYTECODEBASE is set to /, which exists, but is not writable by the current user. A warning is emitted, ! sys.bytecodebase is set to None and no bytecode files are ! written during program execution unless sys.bytecodebase is later changed to refer to a valid, writable directory. Note that even though the augmented directory constructed for a particular *************** *** 234,240 **** - At startup PYTHONBYTECODEBASE is set to the empty string. ! sys.pythonbytecodebase is set to None. No warning is generated, ! however. If no urllib.pyc file is found when urllib is imported, no ! bytecode file is written. In the Windows examples which follow, the urllib source code resides --- 236,242 ---- - At startup PYTHONBYTECODEBASE is set to the empty string. ! sys.bytecodebase is set to None. No warning is generated, however. ! If no urllib.pyc file is found when urllib is imported, no bytecode ! file is written. In the Windows examples which follow, the urllib source code resides *************** *** 249,266 **** - The bytecode base is set to ``C:\TEMP``. ``C:\PYTHON22\urllib.pyc`` exists, but is out-of-date. When urllib is imported, a new bytecode ! file is written to the augmented directory. Intermediate ! directories will be created as needed. - At startup PYTHONBYTECODEBASE is set to ``TEMP`` and the current working directory at application startup is ``H:\NET``. The potential bytecode base is thus ``H:\NET\TEMP``. If this directory ! exists and is writable by the current user, sys.pythonbytecodebase ! will be set to that value. If not, a warning will be emitted and ! sys.pythonbytecodebase will be set to None. - The bytecode base is ``C:\TEMP``. No urllib.pyc file is found. When urllib is imported, the generated bytecode file is written to ! the augmented directory, creating intermediate directories as ! needed. --- 251,269 ---- - The bytecode base is set to ``C:\TEMP``. ``C:\PYTHON22\urllib.pyc`` exists, but is out-of-date. When urllib is imported, a new bytecode ! file is written to the augmented directory which has the value ! ``C:\TEMP\C\PYTHON22``. Intermediate directories will be created as ! needed. - At startup PYTHONBYTECODEBASE is set to ``TEMP`` and the current working directory at application startup is ``H:\NET``. The potential bytecode base is thus ``H:\NET\TEMP``. If this directory ! exists and is writable by the current user, sys.bytecodebase will be ! set to that value. If not, a warning will be emitted and ! sys.bytecodebase will be set to None. - The bytecode base is ``C:\TEMP``. No urllib.pyc file is found. When urllib is imported, the generated bytecode file is written to ! the augmented directory which has the value ``C:\TEMP\C\PYTHON22``. ! Intermediate directories will be created as needed. From rhettinger@users.sourceforge.net Wed Jan 29 19:08:10 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 29 Jan 2003 11:08:10 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.14,1.15 test_itertools.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv13478 Modified Files: libitertools.tex test_itertools.py Log Message: Expand documentation to indicate when each tools would be used. Used spelled-out variable names instead of abbreviations (for clarity). Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** libitertools.tex 29 Jan 2003 01:52:04 -0000 1.14 --- libitertools.tex 29 Jan 2003 19:08:07 -0000 1.15 *************** *** 44,48 **** \item Whether cast in pure python form or C code, tools that use iterators ! are more memory efficient than their list based counterparts. Adopting the principles of just-in-time manufacturing, they create data when and where needed instead of consuming memory with the --- 44,48 ---- \item Whether cast in pure python form or C code, tools that use iterators ! are more memory efficient (and faster) than their list based counterparts. Adopting the principles of just-in-time manufacturing, they create data when and where needed instead of consuming memory with the *************** *** 70,74 **** \begin{funcdesc}{count}{\optional{n}} Make an iterator that returns consecutive integers starting with \var{n}. ! Used in zip and loop constructions to consecutively number a sequence. Equivalent to: --- 70,75 ---- \begin{funcdesc}{count}{\optional{n}} Make an iterator that returns consecutive integers starting with \var{n}. ! Often used as a argument to \function{imap()} to generate consecutive ! data points. Also, used in \function{izip()} to add sequence numbers. Equivalent to: *************** *** 100,122 **** \end{funcdesc} ! \begin{funcdesc}{ifilter}{func, iterable \optional{, invert}} Make an iterator that filters elements from iterable returning only ! those for which the function evaluates to \code{True}. If \var{invert} ! is \code{True}, then reverse the process and pass through only those ! elements for which the function evaluates to \code{False}. ! If function is \code{None}, return the items that are true (unless ! \var{invert} is set). ! ! Equivalent to: \begin{verbatim} ! def ifilter(func, iterable, invert=False): iterable = iter(iterable) while True: x = iterable.next() ! if func is None: b = bool(x) else: ! b = bool(func(x)) if not invert and b or invert and not b: yield x --- 101,121 ---- \end{funcdesc} ! \begin{funcdesc}{ifilter}{predicate, iterable \optional{, invert}} Make an iterator that filters elements from iterable returning only ! those for which the predicate function evaluates to \code{True}. If ! \var{invert} is \code{True}, then reverse the process and pass through ! only those elements for which the function evaluates to \code{False}. ! If \var{predicate} is \code{None}, return the items that are true ! (or false if \var{invert} has been set). Equivalent to: \begin{verbatim} ! def ifilter(predicate, iterable, invert=False): iterable = iter(iterable) while True: x = iterable.next() ! if predicate is None: b = bool(x) else: ! b = bool(predicate(x)) if not invert and b or invert and not b: yield x *************** *** 124,130 **** \end{funcdesc} ! \begin{funcdesc}{imap}{func, *iterables} Make an iterator that computes the function using arguments from ! each of the iterables. If \var{func} is set to \code{None}, then \function{imap()} returns the arguments as a tuple. Like \function{map()} except that it returns an iterator instead of a --- 123,129 ---- \end{funcdesc} ! \begin{funcdesc}{imap}{function, *iterables} Make an iterator that computes the function using arguments from ! each of the iterables. If \var{function} is set to \code{None}, then \function{imap()} returns the arguments as a tuple. Like \function{map()} except that it returns an iterator instead of a *************** *** 134,145 **** \begin{verbatim} ! def imap(func, *iterables): iterables = map(iter, iterables) while True: args = [i.next() for i in iterables] ! if func is None: yield tuple(args) else: ! yield func(*args) \end{verbatim} \end{funcdesc} --- 133,144 ---- \begin{verbatim} ! def imap(function, *iterables): iterables = map(iter, iterables) while True: args = [i.next() for i in iterables] ! if function is None: yield tuple(args) else: ! yield function(*args) \end{verbatim} \end{funcdesc} *************** *** 154,158 **** until the iterable is exhausted. Unlike regular slicing, \function{islice()} does not support negative values for \var{start}, ! \var{stop}, or \var{step}. Equivalent to: \begin{verbatim} --- 153,160 ---- until the iterable is exhausted. Unlike regular slicing, \function{islice()} does not support negative values for \var{start}, ! \var{stop}, or \var{step}. Can be used to extract related fields ! from data where the internal structure has been flattened (for ! example, a multi-line report may list a name field on every ! third line). Equivalent to: \begin{verbatim} *************** *** 179,183 **** Make an iterator that aggregates elements from each of the iterables. Like \function{zip()} except that it returns an iterator instead of ! a list. Equivalent to: \begin{verbatim} --- 181,186 ---- Make an iterator that aggregates elements from each of the iterables. Like \function{zip()} except that it returns an iterator instead of ! a list. Used for lock-step iteration over several iterables at a ! time. Equivalent to: \begin{verbatim} *************** *** 192,197 **** \begin{funcdesc}{repeat}{obj} Make an iterator that returns \var{obj} over and over again. ! Used inside map, zip, or loop constructions for multiple ! references to the same object. Equivalent to: \begin{verbatim} --- 195,201 ---- \begin{funcdesc}{repeat}{obj} Make an iterator that returns \var{obj} over and over again. ! Used as argument to \function{imap()} for invariant parameters ! to the called function. Also used with function{izip()} to create ! an invariant part of a tuple record. Equivalent to: \begin{verbatim} *************** *** 202,208 **** \end{funcdesc} ! \begin{funcdesc}{starmap}{func, iterable} Make an iterator that computes the function using arguments tuples ! obtained from the iterable. Equivalent to: \begin{verbatim} --- 206,217 ---- \end{funcdesc} ! \begin{funcdesc}{starmap}{function, iterable} Make an iterator that computes the function using arguments tuples ! obtained from the iterable. Used instead of \function{imap()} when ! argument parameters are already grouped in tuples from a single iterable ! (the data has been ``pre-zipped''). The difference between ! \function{imap()} and \function{starmap} parallels the distinction ! between \code{function(a,b)} and \code{function(*c)}. ! Equivalent to: \begin{verbatim} *************** *** 257,260 **** --- 266,270 ---- Hello + >>> amounts = [120.15, 764.05, 823.14] >>> for checknum, amount in izip(count(1200), amounts): ... print 'Check %d is for $%.2f' % (checknum, amount) *************** *** 272,278 **** 27 ! >>> reportfile = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] ! >>> for name in islice(reportfile, 3, len(reportfile), 2): ... print name.title() ... --- 282,288 ---- 27 ! >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] ! >>> for name in islice(reportlines, 3, len(reportlines), 2): ... print name.title() ... Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_itertools.py 29 Jan 2003 01:52:04 -0000 1.10 --- test_itertools.py 29 Jan 2003 19:08:08 -0000 1.11 *************** *** 108,113 **** 27 ! >>> reportfile = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] ! >>> for name in islice(reportfile, 3, len(reportfile), 2): ... print name.title() ... --- 108,113 ---- 27 ! >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] ! >>> for name in islice(reportlines, 3, len(reportlines), 2): ... print name.title() ... From montanaro@users.sourceforge.net Wed Jan 29 19:28:13 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 29 Jan 2003 11:28:13 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv24469 Modified Files: pep-0304.txt Log Message: add note that this PEP is not about file-level or directory-level control of bytecode file writes. Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pep-0304.txt 29 Jan 2003 18:49:47 -0000 1.7 --- pep-0304.txt 29 Jan 2003 19:28:10 -0000 1.8 *************** *** 19,24 **** the python-dev mailing list [2]_. The introduction of an environment variable will allow people installing Python or Python-based ! third-party packages to control whether or not bytecode files ! should be generated, and if so, where they should be written. --- 19,25 ---- the python-dev mailing list [2]_. The introduction of an environment variable will allow people installing Python or Python-based ! third-party packages to control whether or not bytecode files should ! be generated at installation time, and if so, where they should be ! written. *************** *** 50,53 **** --- 51,58 ---- modified. + Note that this PEP is explicitly *not* about providing + module-by-module or directory-by-directory control over the + disposition of bytecode files. + Glossary *************** *** 106,109 **** --- 111,115 ---- if base[0] == "\\": base = base[1:] augdir = os.path.join(pcb, drive, base) + Fixing the location of the bytecode base From rhettinger@users.sourceforge.net Wed Jan 29 19:28:33 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 29 Jan 2003 11:28:33 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv24598 Modified Files: libitertools.tex Log Message: Spell-out another variable Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** libitertools.tex 29 Jan 2003 19:08:07 -0000 1.15 --- libitertools.tex 29 Jan 2003 19:28:29 -0000 1.16 *************** *** 216,223 **** \begin{verbatim} ! def starmap(func, iterable): iterable = iter(iterable) while True: ! yield func(*iterable.next()) \end{verbatim} \end{funcdesc} --- 216,223 ---- \begin{verbatim} ! def starmap(function, iterable): iterable = iter(iterable) while True: ! yield function(*iterable.next()) \end{verbatim} \end{funcdesc} From tim_one@users.sourceforge.net Wed Jan 29 20:12:24 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Wed, 29 Jan 2003 12:12:24 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv21312/Lib Modified Files: pickletools.py Log Message: dis(): This had a problem with proto 0 pickles, in that POP sometimes popped a MARK, but without stack emulation the disassembler couldn't know that, and subsequent indentation got hosed. Now the disassembler does do enough stack emulation to catch this. While I was at it, also added lots of sanity checks for other stack operations, and correct use of the memo. This goes (I think) a long way toward being a "pickle verifier" now too. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** pickletools.py 29 Jan 2003 15:41:33 -0000 1.21 --- pickletools.py 29 Jan 2003 20:12:21 -0000 1.22 *************** *** 14,21 **** # # - A pickle verifier: read a pickle and check it exhaustively for ! # well-formedness. # # - A protocol identifier: examine a pickle and return its protocol number # (== the highest .proto attr value among all the opcodes in the pickle). # # - A pickle optimizer: for example, tuple-building code is sometimes more --- 14,22 ---- # # - A pickle verifier: read a pickle and check it exhaustively for ! # well-formedness. dis() does a lot of this already. # # - A protocol identifier: examine a pickle and return its protocol number # (== the highest .proto attr value among all the opcodes in the pickle). + # dis() already prints this info at the end. # # - A pickle optimizer: for example, tuple-building code is sometimes more *************** *** 713,716 **** --- 714,720 ---- self.doc = doc + def __repr__(self): + return self.name + pyint = StackObject( *************** *** 1859,1866 **** Optional arg indentlevel is the number of blanks by which to indent a new MARK level. It defaults to 4. """ ! markstack = [] indentchunk = ' ' * indentlevel for opcode, arg, pos in genops(pickle): if pos is not None: --- 1863,1893 ---- Optional arg indentlevel is the number of blanks by which to indent a new MARK level. It defaults to 4. + + In addition to printing the disassembly, some sanity checks are made: + + + All embedded opcode arguments "make sense". + + + Explicit and implicit pop operations have enough items on the stack. + + + When an opcode implicitly refers to a markobject, a markobject is + actually on the stack. + + + A memo entry isn't referenced before it's defined. + + + The markobject isn't stored in the memo. + + + A memo entry isn't redefined. """ ! # Most of the hair here is for sanity checks, but most of it is needed ! # anyway to detect when a protocol 0 POP takes a MARK off the stack ! # (which in turn is needed to indent MARK blocks correctly). ! ! stack = [] # crude emulation of unpickler stack ! memo = {} # crude emulation of unpicker memo ! maxproto = -1 # max protocol number seen ! markstack = [] # bytecode positions of MARK opcodes indentchunk = ' ' * indentlevel + errormsg = None for opcode, arg, pos in genops(pickle): if pos is not None: *************** *** 1871,1880 **** opcode.name) markmsg = None ! if markstack and markobject in opcode.stack_before: ! assert markobject not in opcode.stack_after ! markpos = markstack.pop() ! if markpos is not None: ! markmsg = "(MARK at %d)" % markpos if arg is not None or markmsg: --- 1898,1949 ---- opcode.name) + maxproto = max(maxproto, opcode.proto) + + # See whether a MARK should be popped. + before = opcode.stack_before # don't mutate + after = opcode.stack_after # don't mutate markmsg = None ! if markobject in before or (opcode.name == "POP" and ! stack and ! stack[-1] is markobject): ! assert markobject not in after ! if markstack: ! markpos = markstack.pop() ! if markpos is None: ! markmsg = "(MARK at unknown opcode offset)" ! else: ! markmsg = "(MARK at %d)" % markpos ! # Pop everything at and after the topmost markobject. ! while stack[-1] is not markobject: ! stack.pop() ! stack.pop() ! # Remove markobject stuff from stack_before. ! try: ! i = before.index(markobject) ! before = before[:i] ! except ValueError: ! assert opcode.name == "POP" ! assert len(before) == 1 ! before = [] # stop code later from popping again ! else: ! errormsg = markmsg = "no MARK exists on stack" ! ! # Check for correct memo usage. ! if opcode.name in ("PUT", "BINPUT", "LONG_BINPUT"): ! if arg in memo: ! errormsg = "memo key %r already defined" % arg ! elif not stack: ! errormsg = "stack is empty -- can't store into memo" ! elif stack[-1] is markobject: ! errormsg = "can't store markobject in the memo" ! else: ! memo[arg] = stack[-1] ! ! elif opcode.name in ("GET", "BINGET", "LONG_BINGET"): ! if arg in memo: ! assert len(after) == 1 ! after = [memo[arg]] # for better stack emulation ! else: ! errormsg = "memo key %r has never been stored into" % arg if arg is not None or markmsg: *************** *** 1887,1894 **** print >> out, line ! if markobject in opcode.stack_after: assert markobject not in opcode.stack_before markstack.append(pos) _dis_test = r""" --- 1956,1980 ---- print >> out, line ! if errormsg: ! # Note that we delayed complaining until the offending opcode ! # was printed. ! raise ValueError(errormsg) ! ! # Emulate the stack effects. ! n = len(before) ! if len(stack) < n: ! raise ValueError("tried to pop %d items from stack with " ! "only %d items" % (n, len(stack))) ! if n: ! del stack[-n:] ! if markobject in after: assert markobject not in opcode.stack_before markstack.append(pos) + stack.extend(after) + + print >> out, "highest protocol among opcodes =", maxproto + if stack: + raise ValueError("stack not empty after STOP: %r" % stack) _dis_test = r""" *************** *** 1920,1923 **** --- 2006,2010 ---- 49: a APPEND 50: . STOP + highest protocol among opcodes = 0 Try again with a "binary" pickle. *************** *** 1944,1947 **** --- 2031,2035 ---- 37: e APPENDS (MARK at 3) 38: . STOP + highest protocol among opcodes = 1 Exercise the INST/OBJ/BUILD family. *************** *** 1952,1955 **** --- 2040,2044 ---- 15: p PUT 0 18: . STOP + highest protocol among opcodes = 0 >>> x = [pickle.PicklingError()] * 2 *************** *** 1974,1977 **** --- 2063,2067 ---- 55: a APPEND 56: . STOP + highest protocol among opcodes = 0 >>> dis(pickle.dumps(x, 1)) *************** *** 1994,1997 **** --- 2084,2088 ---- 48: e APPENDS (MARK at 3) 49: . STOP + highest protocol among opcodes = 1 Try "the canonical" recursive-object test. *************** *** 2018,2021 **** --- 2109,2114 ---- 13: a APPEND 14: . STOP + highest protocol among opcodes = 0 + >>> dis(pickle.dumps(L, 1)) 0: ] EMPTY_LIST *************** *** 2027,2037 **** 9: a APPEND 10: . STOP ! The protocol 0 pickle of the tuple causes the disassembly to get confused, ! as it doesn't realize that the POP opcode at 16 gets rid of the MARK at 0 ! (so the output remains indented until the end). The protocol 1 pickle ! doesn't trigger this glitch, because the disassembler realizes that ! POP_MARK gets rid of the MARK. Doing a better job on the protocol 0 ! pickle would require the disassembler to emulate the stack. >>> dis(pickle.dumps(T, 0)) --- 2120,2128 ---- 9: a APPEND 10: . STOP + highest protocol among opcodes = 1 ! Note that, in the protocol 0 pickle of the recursive tuple, the disassembler ! has to emulate the stack in order to realize that the POP opcode at 16 gets ! rid of the MARK at 0. >>> dis(pickle.dumps(T, 0)) *************** *** 2046,2052 **** 14: a APPEND 15: 0 POP ! 16: 0 POP ! 17: g GET 1 ! 20: . STOP >>> dis(pickle.dumps(T, 1)) 0: ( MARK --- 2137,2145 ---- 14: a APPEND 15: 0 POP ! 16: 0 POP (MARK at 0) ! 17: g GET 1 ! 20: . STOP ! highest protocol among opcodes = 0 ! >>> dis(pickle.dumps(T, 1)) 0: ( MARK *************** *** 2061,2064 **** --- 2154,2158 ---- 12: h BINGET 1 14: . STOP + highest protocol among opcodes = 1 Try protocol 2. *************** *** 2073,2076 **** --- 2167,2171 ---- 10: a APPEND 11: . STOP + highest protocol among opcodes = 2 >>> dis(pickle.dumps(T, 2)) *************** *** 2085,2088 **** --- 2180,2184 ---- 12: h BINGET 1 14: . STOP + highest protocol among opcodes = 2 """ From gvanrossum@users.sourceforge.net Wed Jan 29 20:14:27 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 12:14:27 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.123,1.124 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv26284 Modified Files: pickle.py Log Message: Use %c rather than chr() to turn some ints into chars. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.123 retrieving revision 1.124 diff -C2 -d -r1.123 -r1.124 *** pickle.py 29 Jan 2003 17:58:43 -0000 1.123 --- pickle.py 29 Jan 2003 20:14:23 -0000 1.124 *************** *** 476,480 **** return if obj <= 0xffff: ! self.write(BININT2 + chr(obj&0xff) + chr(obj>>8)) return # Next check for 4-byte signed ints: --- 476,480 ---- return if obj <= 0xffff: ! self.write("%c%c%c" % (BININT2, obj&0xff, obj>>8)) return # Next check for 4-byte signed ints: *************** *** 748,752 **** write(EXT1 + chr(code)) elif code <= 0xffff: ! write(EXT2 + chr(code&0xff) + chr(code>>8)) else: write(EXT4 + pack(">8)) else: write(EXT4 + pack(" Update of /cvsroot/python/python/dist/src/PC In directory sc8-pr-cvs1:/tmp/cvs-serv19369 Modified Files: getpathp.c Log Message: Fix [ 583477 ] wrong dest size. Note this code is not used by the core on Win32, but in a block used only by Windows CE. Index: getpathp.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/getpathp.c,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** getpathp.c 31 Dec 2002 12:35:41 -0000 1.30 --- getpathp.c 29 Jan 2003 22:38:29 -0000 1.31 *************** *** 322,326 **** WideCharToMultiByte(CP_ACP, 0, dataBuf, -1, /* source */ ! retval, dataSize+1, /* dest */ NULL, NULL); free(dataBuf); --- 322,326 ---- WideCharToMultiByte(CP_ACP, 0, dataBuf, -1, /* source */ ! retval, reqdSize+1, /* dest */ NULL, NULL); free(dataBuf); From montanaro@users.sourceforge.net Wed Jan 29 22:49:07 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Wed, 29 Jan 2003 14:49:07 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv25834 Modified Files: pep-0304.txt Log Message: Expand abstract slightly. Reference patch containing beginnings of implementation. Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pep-0304.txt 29 Jan 2003 19:28:10 -0000 1.8 --- pep-0304.txt 29 Jan 2003 22:49:04 -0000 1.9 *************** *** 21,25 **** third-party packages to control whether or not bytecode files should be generated at installation time, and if so, where they should be ! written. --- 21,27 ---- third-party packages to control whether or not bytecode files should be generated at installation time, and if so, where they should be ! written. It will also allow users to control whether or not bytecode ! files should be generated at application run-time, and if so, where ! they should be written. *************** *** 274,277 **** --- 276,284 ---- + Implementation + ============== + + See the patch on Sourceforge. [6]_ + References ========== *************** *** 291,294 **** --- 298,304 ---- .. [5] PEP 302, New Import Hooks, van Rossum and Moore (http://www.python.org/dev/peps/pep-0302.html) + + .. [6] patch 677103, PYTHONBYTECODEBASE patch (PEP 304), Montanaro + (http://www.python.org/sf/677103) From rhettinger@users.sourceforge.net Thu Jan 30 00:56:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 29 Jan 2003 16:56:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-riscos riscosenviron.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-riscos In directory sc8-pr-cvs1:/tmp/cvs-serv7018/plat-riscos Modified Files: riscosenviron.py Log Message: SF patch 672098: Three __contains__ implementations Contributed by Jp Calderone. Index: riscosenviron.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-riscos/riscosenviron.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** riscosenviron.py 24 Oct 2001 20:33:34 -0000 1.5 --- riscosenviron.py 30 Jan 2003 00:56:33 -0000 1.6 *************** *** 33,36 **** --- 33,38 ---- value = riscos.getenv(key) return value<>None + def __contains__(self, key): + return riscos.getenv(key) is not None def update(self, dict): for k, v in dict.items(): From rhettinger@users.sourceforge.net Thu Jan 30 00:56:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 29 Jan 2003 16:56:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/lib-tk Canvas.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory sc8-pr-cvs1:/tmp/cvs-serv7018/lib-tk Modified Files: Canvas.py Log Message: SF patch 672098: Three __contains__ implementations Contributed by Jp Calderone. Index: Canvas.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Canvas.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** Canvas.py 10 Apr 2001 21:13:06 -0000 1.17 --- Canvas.py 30 Jan 2003 00:56:32 -0000 1.18 *************** *** 40,43 **** --- 40,45 ---- def has_key(self, key): return key in self.keys() + def __contains__(self, key): + return key in self.keys() def addtag(self, tag, option='withtag'): self.canvas.addtag(tag, option, self.id) From rhettinger@users.sourceforge.net Thu Jan 30 00:56:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 29 Jan 2003 16:56:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/xml/sax xmlreader.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/sax In directory sc8-pr-cvs1:/tmp/cvs-serv7018/xml/sax Modified Files: xmlreader.py Log Message: SF patch 672098: Three __contains__ implementations Contributed by Jp Calderone. Index: xmlreader.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/sax/xmlreader.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** xmlreader.py 7 Jun 2001 05:52:17 -0000 1.16 --- xmlreader.py 30 Jan 2003 00:56:33 -0000 1.17 *************** *** 322,325 **** --- 322,328 ---- return self._attrs.has_key(name) + def __contains__(self, name): + return self._attrs.has_key(name) + def get(self, name, alternative=None): return self._attrs.get(name, alternative) From rhettinger@users.sourceforge.net Thu Jan 30 01:02:20 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 29 Jan 2003 17:02:20 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv8902 Modified Files: libitertools.tex Log Message: Author markup. Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** libitertools.tex 29 Jan 2003 19:28:29 -0000 1.16 --- libitertools.tex 30 Jan 2003 01:02:17 -0000 1.17 *************** *** 4,7 **** --- 4,10 ---- \declaremodule{standard}{itertools} \modulesynopsis{Functions creating iterators for efficient looping.} + \moduleauthor{Raymond Hettinger}{python@rcn.com} + \sectionauthor{Raymond Hettinger}{python@rcn.com} + \versionadded{2.3} *************** *** 9,13 **** by constructs from the Haskell and SML programming languages. Each has been recast in a form suitable for Python. - \versionadded{2.3} With the advent of iterators and generators in Python 2.3, each of --- 12,15 ---- From rhettinger@users.sourceforge.net Thu Jan 30 01:03:40 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 29 Jan 2003 17:03:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libdatetime.tex,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv9256 Modified Files: libdatetime.tex Log Message: Author markup: Andrew got to it first Index: libdatetime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdatetime.tex,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** libdatetime.tex 25 Jan 2003 21:08:30 -0000 1.41 --- libdatetime.tex 30 Jan 2003 01:03:38 -0000 1.42 *************** *** 9,13 **** \sectionauthor{Tim Peters}{tim@zope.com} \sectionauthor{A.M. Kuchling}{amk@amk.ca} - \sectionauthor{Raymond D. Hettinger}{python@rcn.com} \versionadded{2.3} --- 9,12 ---- From rhettinger@users.sourceforge.net Thu Jan 30 04:16:45 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Wed, 29 Jan 2003 20:16:45 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv2145 Modified Files: libitertools.tex Log Message: Incorporated documentation fix-ups based on an excellent review by Terry J. Reedy. Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** libitertools.tex 30 Jan 2003 01:02:17 -0000 1.17 --- libitertools.tex 30 Jan 2003 04:16:43 -0000 1.18 *************** *** 91,101 **** \begin{verbatim} ! def dropwhile(predicate, iterable, invert=False): iterable = iter(iterable) while True: x = iterable.next() ! if not predicate(x): ! yield x ! break while True: yield iterable.next() --- 91,101 ---- \begin{verbatim} ! def dropwhile(predicate, iterable): iterable = iter(iterable) while True: x = iterable.next() ! if predicate(x): continue # drop when predicate is true ! yield x ! break while True: yield iterable.next() *************** *** 129,135 **** each of the iterables. If \var{function} is set to \code{None}, then \function{imap()} returns the arguments as a tuple. Like ! \function{map()} except that it returns an iterator instead of a ! list and that it stops when the shortest iterable is exhausted ! instead of filling in \code{None} for shorter iterables. Equivalent to: --- 129,138 ---- each of the iterables. If \var{function} is set to \code{None}, then \function{imap()} returns the arguments as a tuple. Like ! \function{map()} but stops when the shortest iterable is exhausted ! instead of filling in \code{None} for shorter iterables. The reason ! for the difference is that infinite iterator arguments are typically ! an error for \function{map()} (because the output is fully evaluated) ! but represent a common and useful way of supplying arguments to ! \function{imap()}. Equivalent to: *************** *** 230,234 **** \begin{verbatim} ! def takewhile(predicate, iterable, invert=False): iterable = iter(iterable) while True: --- 233,237 ---- \begin{verbatim} ! def takewhile(predicate, iterable): iterable = iter(iterable) while True: From gvanrossum@users.sourceforge.net Thu Jan 30 05:39:07 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 21:39:07 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.124,1.125 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25722 Modified Files: pickle.py Log Message: In save_newobj(), if an object's __getnewargs__ and __getstate__ are the same function, don't save the state or write a BUILD opcode. This is so that a type (e.g. datetime :-) can support protocol 2 using __getnewargs__ while also supporting protocol 0 and 1 using __getstate__. (Without this, the state would be pickled twice with protocol 2, unless __getstate__ is defined to return None, which breaks protocol 0 and 1.) Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.124 retrieving revision 1.125 diff -C2 -d -r1.124 -r1.125 *** pickle.py 29 Jan 2003 20:14:23 -0000 1.124 --- pickle.py 30 Jan 2003 05:39:04 -0000 1.125 *************** *** 417,420 **** --- 417,443 ---- getstate = getattr(obj, "__getstate__", None) + + # A class may define both __getstate__ and __getnewargs__. + # If they are the same function, we ignore __getstate__. + # This is for the benefit of protocols 0 and 1, which don't + # use __getnewargs__. Note that the only way to make them + # the same function is something like this: + # + # class C(object): + # def __getstate__(self): + # return ... + # __getnewargs__ = __getstate__ + # + # No tricks are needed to ignore __setstate__; it simply + # won't be called when we don't generate BUILD. + # Also note that when __getnewargs__ and __getstate__ are + # the same function, we don't do the default thing of + # looking for __dict__ and slots either -- it is assumed + # that __getnewargs__ returns all the state there is + # (which should be a safe assumption since __getstate__ + # returns the *same* state). + if getstate and getstate == getnewargs: + return + if getstate: try: From gvanrossum@users.sourceforge.net Thu Jan 30 05:41:22 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 21:41:22 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.125,1.126 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv26268 Modified Files: pickle.py Log Message: Slight code rearrangement to avoid testing getstate twice. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.125 retrieving revision 1.126 diff -C2 -d -r1.125 -r1.126 *** pickle.py 30 Jan 2003 05:39:04 -0000 1.125 --- pickle.py 30 Jan 2003 05:41:19 -0000 1.126 *************** *** 418,444 **** getstate = getattr(obj, "__getstate__", None) - # A class may define both __getstate__ and __getnewargs__. - # If they are the same function, we ignore __getstate__. - # This is for the benefit of protocols 0 and 1, which don't - # use __getnewargs__. Note that the only way to make them - # the same function is something like this: - # - # class C(object): - # def __getstate__(self): - # return ... - # __getnewargs__ = __getstate__ - # - # No tricks are needed to ignore __setstate__; it simply - # won't be called when we don't generate BUILD. - # Also note that when __getnewargs__ and __getstate__ are - # the same function, we don't do the default thing of - # looking for __dict__ and slots either -- it is assumed - # that __getnewargs__ returns all the state there is - # (which should be a safe assumption since __getstate__ - # returns the *same* state). - if getstate and getstate == getnewargs: - return - if getstate: try: state = getstate() --- 418,444 ---- getstate = getattr(obj, "__getstate__", None) if getstate: + # A class may define both __getstate__ and __getnewargs__. + # If they are the same function, we ignore __getstate__. + # This is for the benefit of protocols 0 and 1, which don't + # use __getnewargs__. Note that the only way to make them + # the same function is something like this: + # + # class C(object): + # def __getstate__(self): + # return ... + # __getnewargs__ = __getstate__ + # + # No tricks are needed to ignore __setstate__; it simply + # won't be called when we don't generate BUILD. + # Also note that when __getnewargs__ and __getstate__ are + # the same function, we don't do the default thing of + # looking for __dict__ and slots either -- it is assumed + # that __getnewargs__ returns all the state there is + # (which should be a safe assumption since __getstate__ + # returns the *same* state). + if getstate == getnewargs: + return + try: state = getstate() *************** *** 451,454 **** --- 451,455 ---- raise # Not that specific exception getstate = None + if not getstate: state = getattr(obj, "__dict__", None) From gvanrossum@users.sourceforge.net Thu Jan 30 06:01:10 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 22:01:10 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.152,1.153 test_datetime.py,1.106,1.107 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv29803 Modified Files: datetime.py test_datetime.py Log Message: Experimental support for pickle protocol 2. Classes timedelta, date, time, and datetime now have a __new__ method instead of __init__. (Class tzinfo not yet; I'll have to think more about it.) I've added __getnewargs__ as an alias for __getstate__ for each of these classes. The state for date is now a tuple (for the others it already was a tuple). The test suite now tests protocols 0, 1 and 2; this is the only change (except one place where the state of a date was compared to a string literal). It passes for Python 2.2 as well as for Python 2.3. XXX The pickles are not compatible with those of the C implementation! XXX But I think the C implementation can be changed to match, and it XXX will work for all three protocols, in both Python versions. XXX Fingers crossed. Goodnight. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.152 retrieving revision 1.153 diff -C2 -d -r1.152 -r1.153 *** datetime.py 24 Jan 2003 18:56:35 -0000 1.152 --- datetime.py 30 Jan 2003 06:01:06 -0000 1.153 *************** *** 403,409 **** """ ! def __init__(self, days=0, seconds=0, microseconds=0, ! # XXX The following should only be used as keyword args: ! milliseconds=0, minutes=0, hours=0, weeks=0): # Doing this efficiently and accurately in C is going to be difficult # and error-prone, due to ubiquitous overflow possibilities, and that --- 403,409 ---- """ ! def __new__(cls, days=0, seconds=0, microseconds=0, ! # XXX The following should only be used as keyword args: ! milliseconds=0, minutes=0, hours=0, weeks=0): # Doing this efficiently and accurately in C is going to be difficult # and error-prone, due to ubiquitous overflow possibilities, and that *************** *** 506,509 **** --- 506,512 ---- assert isinstance(s, int) and 0 <= s < 24*3600 assert isinstance(us, int) and 0 <= us < 1000000 + + self = object.__new__(cls) + self.__days = d self.__seconds = s *************** *** 512,515 **** --- 515,520 ---- raise OverflowError("timedelta # of days is too large: %d" % d) + return self + def __repr__(self): if self.__microseconds: *************** *** 611,619 **** __safe_for_unpickling__ = True - def __reduce__(self): - return type(self), (), self.__getstate__() - def __getstate__(self): return (self.__days, self.__seconds, self.__microseconds) def __setstate__(self, tup): --- 616,622 ---- __safe_for_unpickling__ = True def __getstate__(self): return (self.__days, self.__seconds, self.__microseconds) + __getnewargs__ = __getstate__ def __setstate__(self, tup): *************** *** 630,634 **** Constructors: ! __init__() fromtimestamp() today() --- 633,637 ---- Constructors: ! __new__() fromtimestamp() today() *************** *** 654,658 **** """ ! def __init__(self, year, month, day): """Constructor. --- 657,661 ---- """ ! def __new__(cls, year, month=None, day=None): """Constructor. *************** *** 661,668 **** --- 664,678 ---- year, month, day (required, base 1) """ + if isinstance(year, str): + # From pickle __getstate__ + self = object.__new__(cls) + self.__setstate__((year,)) + return self _check_date_fields(year, month, day) + self = object.__new__(cls) self.__year = year self.__month = month self.__day = day + return self # Additional constructors *************** *** 845,851 **** def __getstate__(self): yhi, ylo = divmod(self.__year, 256) ! return "%c%c%c%c" % (yhi, ylo, self.__month, self.__day) ! def __setstate__(self, string): assert len(string) == 4 yhi, ylo, self.__month, self.__day = map(ord, string) --- 855,864 ---- def __getstate__(self): yhi, ylo = divmod(self.__year, 256) ! return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) ! __getnewargs__ = __getstate__ ! def __setstate__(self, t): ! assert isinstance(t, tuple) and len(t) == 1, `t` ! string = t[0] assert len(string) == 4 yhi, ylo, self.__month, self.__day = map(ord, string) *************** *** 911,914 **** --- 924,928 ---- # pickle support + # XXX Should do something with __new__ instead __safe_for_unpickling__ = True *************** *** 917,920 **** --- 931,936 ---- return type(self), (), self.__dict__ + _tzinfo_class = tzinfo # so functions w/ args named "tinfo" can get at it + class time(object): """Time with time zone. *************** *** 922,926 **** Constructors: ! __init__() Operators: --- 938,942 ---- Constructors: ! __new__() Operators: *************** *** 941,945 **** """ ! def __init__(self, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. --- 957,961 ---- """ ! def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. *************** *** 950,953 **** --- 966,979 ---- tzinfo (default to None) """ + self = object.__new__(cls) + if isinstance(hour, str): + # Call from protocol 2 unpickling + assert len(hour) == 6 + assert minute == 0 or isinstance(minute, _tzinfo_class), `minute` + self.__hour, self.__minute, self.__second, us1, us2, us3 = \ + map(ord, hour) + self.__microsecond = (((us1 << 8) | us2) << 8) | us3 + self._tzinfo = minute or None + return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) *************** *** 957,960 **** --- 983,987 ---- self.__microsecond = microsecond self._tzinfo = tzinfo + return self # Read-only field accessors *************** *** 1148,1151 **** --- 1175,1179 ---- else: return (basestate, self._tzinfo) + __getnewargs__ = __getstate__ def __setstate__(self, state): *************** *** 1176,1184 **** # See http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo ! def __init__(self, year, month, day, hour=0, minute=0, second=0, ! microsecond=0, tzinfo=None): _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) ! date.__init__(self, year, month, day) # XXX This duplicates __year, __month, __day for convenience :-( self.__year = year --- 1204,1217 ---- # See http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo ! def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, ! microsecond=0, tzinfo=None): ! if isinstance(year, str): ! # Pickle support ! self = date.__new__(cls, 1, 1, 1) ! self.__setstate__((year, month)) ! return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) ! self = date.__new__(cls, year, month, day) # XXX This duplicates __year, __month, __day for convenience :-( self.__year = year *************** *** 1190,1193 **** --- 1223,1227 ---- self.__microsecond = microsecond self._tzinfo = tzinfo + return self # Read-only field accessors *************** *** 1533,1536 **** --- 1567,1571 ---- else: return (basestate, self._tzinfo) + __getnewargs__ = __getstate__ def __setstate__(self, state): *************** *** 1607,1618 **** self.__setstate__(state) return self - - # Register pickle/unpickle functions. - from copy_reg import pickle - pickle(date, _date_pickler, _date_unpickler) - pickle(tzinfo, _tzinfo_pickler, _tzinfo_unpickler) - pickle(time, _time_pickler, _time_unpickler) - pickle(datetime, _datetime_pickler, _datetime_unpickler) - del pickle """ --- 1642,1645 ---- Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.106 retrieving revision 1.107 diff -C2 -d -r1.106 -r1.107 *** test_datetime.py 24 Jan 2003 22:32:27 -0000 1.106 --- test_datetime.py 30 Jan 2003 06:01:07 -0000 1.107 *************** *** 107,112 **** self.failUnless(type(orig) is tzinfo) for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.failUnless(type(derived) is tzinfo) --- 107,112 ---- self.failUnless(type(orig) is tzinfo) for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.failUnless(type(derived) is tzinfo) *************** *** 123,128 **** self.assertEqual(orig.tzname(None), 'cookie') for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.failUnless(isinstance(derived, tzinfo)) --- 123,128 ---- self.assertEqual(orig.tzname(None), 'cookie') for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.failUnless(isinstance(derived, tzinfo)) *************** *** 272,277 **** self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.assertEqual(orig, derived) --- 272,277 ---- self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.assertEqual(orig, derived) *************** *** 826,836 **** orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, '\x00\x06\x07\x17') derived = self.theclass(1, 1, 1) derived.__setstate__(state) self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.assertEqual(orig, derived) --- 826,836 ---- orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, ('\x00\x06\x07\x17',)) derived = self.theclass(1, 1, 1) derived.__setstate__(state) self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.assertEqual(orig, derived) *************** *** 1190,1195 **** self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1190,1195 ---- self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.assertEqual(orig, derived) *************** *** 1576,1581 **** self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1576,1581 ---- self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.assertEqual(orig, derived) *************** *** 1892,1897 **** self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1892,1897 ---- self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.assertEqual(orig, derived) *************** *** 1909,1914 **** for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1909,1914 ---- for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.assertEqual(orig, derived) *************** *** 2111,2116 **** self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.assertEqual(orig, derived) --- 2111,2116 ---- self.assertEqual(orig, derived) for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.assertEqual(orig, derived) *************** *** 2128,2133 **** for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) derived = pickler.loads(green) self.assertEqual(orig, derived) --- 2128,2133 ---- for pickler in pickle, cPickle: ! for proto in 0, 1, 2: ! green = pickler.dumps(orig, proto) derived = pickler.loads(green) self.assertEqual(orig, derived) From gvanrossum@users.sourceforge.net Thu Jan 30 06:10:52 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 22:10:52 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime Makefile,1.7,NONE Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv2471 Removed Files: Makefile Log Message: Makefile is no longer needed here. --- Makefile DELETED --- From gvanrossum@users.sourceforge.net Thu Jan 30 06:37:44 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 29 Jan 2003 22:37:44 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.126,1.127 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv9358 Modified Files: pickle.py Log Message: There was a subtle big in save_newobj(): it used self.save_global(t) on the type instead of self.save(t). This defeated the purpose of NEWOBJ, because it didn't generate a BINGET opcode when t was already memoized; but moreover, it would generate multiple BINPUT opcodes for the same type! pickletools.dis() doesn't like this. How I found this? I was playing with picklesize.py in the datetime sandbox, and noticed that protocol 2 pickles for multiple objects were in fact larger than protocol 1 pickles! That was suspicious, so I decided to disassemble one of the pickles. This really needs a unit test, but I'm exhausted. I'll be late for work as it is. :-( Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -d -r1.126 -r1.127 *** pickle.py 30 Jan 2003 05:41:19 -0000 1.126 --- pickle.py 30 Jan 2003 06:37:41 -0000 1.127 *************** *** 234,237 **** --- 234,238 ---- if self.fast: return + assert id(obj) not in self.memo memo_len = len(self.memo) self.write(self.put(memo_len)) *************** *** 387,391 **** write = self.write ! self.save_global(t) save(args) write(NEWOBJ) --- 388,392 ---- write = self.write ! self.save(t) save(args) write(NEWOBJ) From mwh@users.sourceforge.net Thu Jan 30 10:12:54 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 30 Jan 2003 02:12:54 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.58,2.59 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv12271 Modified Files: readline.c Log Message: Add the get_completer() function based on Michael Stone's patch in [ 676342 ] after using pdb readline does not work correctly which is required to fix that bug. So maaybe a bugfix candidate. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.58 retrieving revision 2.59 diff -C2 -d -r2.58 -r2.59 *** readline.c 7 Jan 2003 20:31:20 -0000 2.58 --- readline.c 30 Jan 2003 10:12:51 -0000 2.59 *************** *** 351,354 **** --- 351,370 ---- + static PyObject * + get_completer(PyObject *self, PyObject *args) + { + if (completer == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + Py_INCREF(completer); + return completer; + } + + PyDoc_STRVAR(doc_get_completer, + "get_completer() -> function\n\ + \n\ + Returns current completer function."); + /* Exported function to get any element of history */ *************** *** 460,463 **** --- 476,480 ---- METH_VARARGS, get_history_length_doc}, {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, + {"get_completer", get_completer, METH_NOARGS, doc_get_completer}, {"get_begidx", (PyCFunction)get_begidx, METH_NOARGS, doc_get_begidx}, {"get_endidx", (PyCFunction)get_endidx, METH_NOARGS, doc_get_endidx}, From mwh@users.sourceforge.net Thu Jan 30 10:27:47 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 30 Jan 2003 02:27:47 -0800 Subject: [Python-checkins] python/nondist/peps pep-0306.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv18166 Modified Files: pep-0306.txt Log Message: Update after comments from Guido. Index: pep-0306.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0306.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep-0306.txt 29 Jan 2003 15:07:17 -0000 1.1 --- pep-0306.txt 30 Jan 2003 10:27:45 -0000 1.2 *************** *** 22,26 **** This PEP is not intended to be an instruction manual on Python ! grammar hacking. --- 22,26 ---- This PEP is not intended to be an instruction manual on Python ! grammar hacking, for several reasons. *************** *** 50,53 **** --- 50,63 ---- suite, didn't you? There's a script in Tools/compiler that does this. + + __ If you've gone so far as to change the token structure of + Python, then the tokenizer library module will need to be + changed. + + __ Certain changes may require tweaks to the library module + pycblr. + + __ Jython too will need work, but I don't know what. Explanations + gratefully received. From walter@livinglogic.de Thu Jan 30 11:44:03 2003 From: walter@livinglogic.de (=?ISO-8859-1?Q?Walter_D=F6rwald?=) Date: Thu, 30 Jan 2003 12:44:03 +0100 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 In-Reply-To: <20030128115507.GA20057@fallin.lv> References: <3E352ADE.3090908@livinglogic.de> <3E3669D9.3090807@livinglogic.de> <20030128115507.GA20057@fallin.lv> Message-ID: <3E391003.5080702@livinglogic.de> Hye-Shik Chang wrote: > On Tue, Jan 28, 2003 at 12:30:33PM +0100, Walter D?rwald wrote: > >>Martin v. L?wis wrote: >> [...] >> >>>In any case, I'ld like to request that the documentation is clarified >>>in this aspect (preferable, the "proper" documentation, not (just) the >>>PEP). Once that clarification is added, the incorrect codecs should be >>>corrected. >> >>So how should we handle these cases? >> >>a) Treat negative positions as relative to the end > +1 > >>b) Treat negative positions as 0 > -1 > >>c) Clip out of bounds positions to the length of the input > -0 > >>d) Raise an exception > +0 > >>I'd vote for a) + d) >> >>If that's what we want to do I'll update the PEP, the documentation >>and the implemenation. OK, I've uploaded a patch that implements a) + d): http://www.python.org/sf/677429 Bye, Walter Dörwald From davecole@users.sourceforge.net Thu Jan 30 12:11:31 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Thu, 30 Jan 2003 04:11:31 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv25349 Modified Files: pep-0305.txt Log Message: Trying to bring PEP up to date with discussions on mailing list. I hope I have not misinterpreted the conclusions. * dialect argument is now either a string to identify one of the internally defined parameter sets, otherwise it is an object which contains attributes which correspond to the parameter set. * Altered set_dialect() to take dialect name and dialect object. * Altered get_dialect() to take dialect name and return dialect object. * Fleshed out formatting parameters, adding escapechar, lineterminator, quoting. Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pep-0305.txt 29 Jan 2003 14:09:45 -0000 1.4 --- pep-0305.txt 30 Jan 2003 12:11:27 -0000 1.5 *************** *** 106,122 **** Readers and writers support a dialect argument which is just a ! convenient (string) handle on a group of lower level parameters. Dialects will generally be named after applications or organizations which define specific sets of format constraints. The initial dialect ! is "excel2000", which describes the format constraints of Excel 2000's CSV format. Another possible dialect (used here only as an example) might be "gnumeric". Two functions are defined in the API to set and retrieve dialects:: ! set_dialect(dialect, pdict) ! pdict = get_dialect(dialect) ! The pdict parameter is a dictionary whose keys are the names the formatting parameters defined in the next section. --- 106,145 ---- Readers and writers support a dialect argument which is just a ! convenient handle on a group of lower level parameters. ! ! When dialect is a string it identifies one of the dialect which is ! known to the module, otherwise it is processed as a dialect class as ! described below. ! Dialects will generally be named after applications or organizations which define specific sets of format constraints. The initial dialect ! is excel2000, which describes the format constraints of Excel 2000's CSV format. Another possible dialect (used here only as an example) might be "gnumeric". + Dialects are implemented as attribute only classes to enable user to + construct variant dialects by subclassing. The excel2000 dialect is + implemented as follows:: + + class excel2000: + quotechar = '"' + delimiter = ',' + escapechar = None + skipinitialspace = False + lineterminator = '\r\n' + quoting = 'minimal' + + An excel tab separated dialect can then be defined in user code as + follows:: + + class exceltsv(csv.excel2000): + delimiter = '\t' + Two functions are defined in the API to set and retrieve dialects:: ! set_dialect(name, dialect) ! dialect = get_dialect(name) ! The dialect parameter is a class or instance whose attributes are the formatting parameters defined in the next section. *************** *** 136,139 **** --- 159,165 ---- separator. It defaults to ','. + - escapechar specifies a one character string used to escape the + delimiter when quotechar is set to None. + - skipinitialspace specifies how to interpret whitespace which immediately follows a delimiter. It defaults to False, which means *************** *** 143,146 **** --- 169,183 ---- - lineterminator specifies the character sequence which should terminate rows. + + - quoting controls when quotes should be generated by the + writer. + + "minimal" means only when required, for example, when a field + contains either the quotechar or the delimiter + + "always" means that quotes are always placed around fields. + + "nonnumeric" means that quotes are always placed around fields + which contain characters other than [+-0-9.]. ... XXX More to come XXX ... From davecole@users.sourceforge.net Thu Jan 30 12:20:57 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Thu, 30 Jan 2003 04:20:57 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv32119 Modified Files: csv.py Log Message: Brought dialect specification in line with the PEP. Did not touch the treatment of the dialect argument to the reader/writer to match the PEP since I am not sure we have consensus yet. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** csv.py 29 Jan 2003 14:18:20 -0000 1.2 --- csv.py 30 Jan 2003 12:20:54 -0000 1.3 *************** *** 2,9 **** class excel2000: ! pass class excel2000_tab: ! field_sep='\t' dialects = { --- 2,14 ---- class excel2000: ! quotechar = '"' ! delimiter = ',' ! escapechar = None ! skipinitialspace = False ! lineterminator = '\r\n' ! quoting = 'minimal' class excel2000_tab: ! delimiter = '\t' dialects = { *************** *** 13,16 **** --- 18,27 ---- 'excel2000-tab': excel2000_tab, } + + def set_dialect(name, dialect): + dialects[name] = dialect + + def get_dialect(name): + return dialects[name] class Error(Exception): From montanaro@users.sourceforge.net Thu Jan 30 12:53:43 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 30 Jan 2003 04:53:43 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv15918 Modified Files: pep-0305.txt Log Message: add some To Do items (to David Goodger - don't shoot me because the text now has embedded URLs - they are temporary. ;-). added [optional keyword args] to the constructor prototypes. Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0305.txt 30 Jan 2003 12:11:27 -0000 1.5 --- pep-0305.txt 30 Jan 2003 12:53:40 -0000 1.6 *************** *** 28,31 **** --- 28,44 ---- + To Do (Notes for the Interested and Ambitious) + ============================================== + + - Need to better explain the advantages of a purpose-built csv module + over the simple ",".join() and [].split() approach. + + - Need to complete initial list of formatting parameters and settle on + names. + + - Better motivation for the choice of passing a file object to the + constructors. See http://manatee.mojam.com/pipermail/csv/2003-January/000179.html + + Existing Modules ================ *************** *** 64,74 **** writing. The basic reading interface is:: ! reader(fileobj [, dialect='excel2000']) A reader object is an iterable which takes a file-like object opened for reading as the sole required parameter. The optional dialect ! parameter is discussed below. It also accepts several keyword ! parameters which define specific format settings (see the section ! "Formatting Parameters"). Readers are typically used as follows:: csvreader = csv.reader(file("some.csv")) --- 77,88 ---- writing. The basic reading interface is:: ! reader(fileobj [, dialect='excel2000'] [optional keyword args]) A reader object is an iterable which takes a file-like object opened for reading as the sole required parameter. The optional dialect ! parameter is discussed below. It also accepts several optional ! keyword arguments which define specific format settings for the parser ! (see the section "Formatting Parameters"). Readers are typically used ! as follows:: csvreader = csv.reader(file("some.csv")) *************** *** 78,86 **** The writing interface is similar:: ! writer(fileobj [, dialect='excel2000'], [, fieldnames=list]) A writer object is a wrapper around a file-like object opened for ! writing. It accepts the same keyword parameters as the reader ! constructor. In addition, it accepts an optional fieldnames argument. This is a list which defines the order of fields in the output file. It allows the write() method to accept mapping objects --- 92,101 ---- The writing interface is similar:: ! writer(fileobj [, dialect='excel2000'], [, fieldnames=list] ! [optional keyword args]) A writer object is a wrapper around a file-like object opened for ! writing. It accepts the same optional keyword parameters as the ! reader constructor. In addition, it accepts an optional fieldnames argument. This is a list which defines the order of fields in the output file. It allows the write() method to accept mapping objects From guido@python.org Thu Jan 30 13:03:23 2003 From: guido@python.org (Guido van Rossum) Date: Thu, 30 Jan 2003 08:03:23 -0500 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 In-Reply-To: "Your message of Thu, 30 Jan 2003 12:44:03 +0100." <3E391003.5080702@livinglogic.de> References: <3E352ADE.3090908@livinglogic.de> <3E3669D9.3090807@livinglogic.de> <20030128115507.GA20057@fallin.lv> <3E391003.5080702@livinglogic.de> Message-ID: <200301301303.h0UD3N229128@pcp02138704pcs.reston01.va.comcast.net> > OK, I've uploaded a patch that implements a) + d): > http://www.python.org/sf/677429 I don't know anything about iconv, but I noticed that its unit tests fail for me. Is anyone able to fix this before MvL returns from vacation at the end of February? (I want to do an alpha release before then, if Tim & I get the new pickling stuff working.) --Guido van Rossum (home page: http://www.python.org/~guido/) From davecole@users.sourceforge.net Thu Jan 30 13:11:24 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Thu, 30 Jan 2003 05:11:24 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv23703 Modified Files: csv.py Log Message: Changed the quoting format argument to integer. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** csv.py 30 Jan 2003 12:20:54 -0000 1.3 --- csv.py 30 Jan 2003 13:11:21 -0000 1.4 *************** *** 1,4 **** --- 1,6 ---- import _csv + QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC = range(3) + class excel2000: quotechar = '"' *************** *** 7,11 **** skipinitialspace = False lineterminator = '\r\n' ! quoting = 'minimal' class excel2000_tab: --- 9,13 ---- skipinitialspace = False lineterminator = '\r\n' ! quoting = QUOTE_MINIMAL class excel2000_tab: From davecole@users.sourceforge.net Thu Jan 30 13:16:09 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Thu, 30 Jan 2003 05:16:09 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv24039 Modified Files: _csv.c Log Message: * More formatting changes to bring code closer to the Guido style. * Changed all internal parser settings to match those in the PEP. * Added PEP settings to allow _csv use by csv.py - new parameters are not handled yet (skipinitialspace, lineterminator, quoting). * Removed overloading of quotechar and escapechar values by introducing have_quotechar and have_escapechar attributes. Barest minimum of testing has been done. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _csv.c 29 Jan 2003 11:21:34 -0000 1.2 --- _csv.c 30 Jan 2003 13:16:06 -0000 1.3 *************** *** 1,2 **** --- 1,17 ---- + /* TODO: + + Add reader() and writer() functions which return CSV + reader/writer objects which implement the PEP interface: + + csvreader = csv.reader(file("blah.csv", "rb"), kwargs) + for row in csvreader: + process(row) + + csvwriter = csv.writer(file("some.csv", "wb"), kwargs) + for row in someiter: + csvwriter.write(row) + + + Add CsvWriter.writelines(someiter) + */ + #include "Python.h" #include "structmember.h" *************** *** 9,24 **** } ParserState; typedef struct { PyObject_HEAD ! int ms_double_quote; /* is " represented by ""? */ ! char field_sep; /* field separator */ ! char quote_char; /* quote character */ ! char escape_char; /* escape character */ ParserState state; /* current CSV parse state */ PyObject *fields; /* field list for current record */ ! int auto_clear; /* should fields be cleared on next parse() after exception? */ int strict; /* raise exception on bad CSV */ --- 24,48 ---- } ParserState; + typedef enum { + QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC + } QuoteStyle; + typedef struct { PyObject_HEAD ! int doublequote; /* is " represented by ""? */ ! char delimiter; /* field separator */ ! int have_quotechar; /* is a quotechar defined */ ! char quotechar; /* quote character */ ! int have_escapechar; /* is an escapechar defined */ ! char escapechar; /* escape character */ ! int skipinitialspace; /* ignore spaces following delimiter? */ ! PyObject *lineterminator; /* string to write between records */ ! QuoteStyle quoting; /* style of quoting to write */ ParserState state; /* current CSV parse state */ PyObject *fields; /* field list for current record */ ! int autoclear; /* should fields be cleared on next parse() after exception? */ int strict; /* raise exception on bad CSV */ *************** *** 78,82 **** self->field_size = 4096; self->field = PyMem_Malloc(self->field_size); ! } else { self->field_size *= 2; self->field = PyMem_Realloc(self->field, self->field_size); --- 102,107 ---- self->field_size = 4096; self->field = PyMem_Malloc(self->field_size); ! } ! else { self->field_size *= 2; self->field = PyMem_Realloc(self->field, self->field_size); *************** *** 125,138 **** parse_save_field(self); self->state = START_RECORD; ! } else if (c == self->quote_char) { /* start quoted field */ self->state = IN_QUOTED_FIELD; ! } else if (c == self->escape_char) { /* possible escaped character */ self->state = ESCAPED_CHAR; ! } else if (c == self->field_sep) { /* save empty field */ parse_save_field(self); ! } else { /* begin new unquoted field */ parse_add_char(self, c); --- 150,167 ---- parse_save_field(self); self->state = START_RECORD; ! } ! else if (c == self->quotechar) { /* start quoted field */ self->state = IN_QUOTED_FIELD; ! } ! else if (c == self->escapechar) { /* possible escaped character */ self->state = ESCAPED_CHAR; ! } ! else if (c == self->delimiter) { /* save empty field */ parse_save_field(self); ! } ! else { /* begin new unquoted field */ parse_add_char(self, c); *************** *** 142,148 **** case ESCAPED_CHAR: ! if (c != self->escape_char && c != self->field_sep && ! c != self->quote_char) ! parse_add_char(self, self->escape_char); parse_add_char(self, c); self->state = IN_FIELD; --- 171,177 ---- case ESCAPED_CHAR: ! if (c != self->escapechar && c != self->delimiter && ! c != self->quotechar) ! parse_add_char(self, self->escapechar); parse_add_char(self, c); self->state = IN_FIELD; *************** *** 155,166 **** parse_save_field(self); self->state = START_RECORD; ! } else if (c == self->escape_char) { /* possible escaped character */ self->state = ESCAPED_CHAR; ! } else if (c == self->field_sep) { /* save field - wait for new field */ parse_save_field(self); self->state = START_FIELD; ! } else { /* normal character - save in field */ parse_add_char(self, c); --- 184,198 ---- parse_save_field(self); self->state = START_RECORD; ! } ! else if (c == self->escapechar) { /* possible escaped character */ self->state = ESCAPED_CHAR; ! } ! else if (c == self->delimiter) { /* save field - wait for new field */ parse_save_field(self); self->state = START_FIELD; ! } ! else { /* normal character - save in field */ parse_add_char(self, c); *************** *** 173,188 **** /* end of line - save '\n' in field */ parse_add_char(self, '\n'); ! } else if (c == self->escape_char) { /* Possible escape character */ self->state = ESCAPE_IN_QUOTED_FIELD; ! } else if (c == self->quote_char) { ! if (self->ms_double_quote) { /* microsoft style double quotes; " represented by "" */ self->state = QUOTE_IN_QUOTED_FIELD; ! } else { /* end of quote part of field */ self->state = IN_FIELD; } ! } else { /* normal character - save in field */ parse_add_char(self, c); --- 205,224 ---- /* end of line - save '\n' in field */ parse_add_char(self, '\n'); ! } ! else if (c == self->escapechar) { /* Possible escape character */ self->state = ESCAPE_IN_QUOTED_FIELD; ! } ! else if (c == self->quotechar) { ! if (self->doublequote) { /* microsoft style double quotes; " represented by "" */ self->state = QUOTE_IN_QUOTED_FIELD; ! } ! else { /* end of quote part of field */ self->state = IN_FIELD; } ! } ! else { /* normal character - save in field */ parse_add_char(self, c); *************** *** 191,197 **** case ESCAPE_IN_QUOTED_FIELD: ! if (c != self->escape_char && c != self->field_sep && ! c != self->quote_char) ! parse_add_char(self, self->escape_char); parse_add_char(self, c); self->state = IN_QUOTED_FIELD; --- 227,233 ---- case ESCAPE_IN_QUOTED_FIELD: ! if (c != self->escapechar && c != self->delimiter && ! c != self->quotechar) ! parse_add_char(self, self->escapechar); parse_add_char(self, c); self->state = IN_QUOTED_FIELD; *************** *** 200,223 **** case QUOTE_IN_QUOTED_FIELD: /* microsoft double quotes - seen a quote in an quoted field */ ! if (self->quote_char && c == self->quote_char) { /* save "" as " */ parse_add_char(self, c); self->state = IN_QUOTED_FIELD; ! } else if (c == self->field_sep) { /* save field - wait for new field */ parse_save_field(self); self->state = START_FIELD; ! } else if (c == '\0') { /* end of line - return [fields] */ parse_save_field(self); self->state = START_RECORD; ! } else if (!self->strict) { parse_add_char(self, c); self->state = IN_FIELD; ! } else { /* illegal */ self->had_parse_error = 1; raise_exception("%c expected after %c", ! self->field_sep, self->quote_char); } break; --- 236,263 ---- case QUOTE_IN_QUOTED_FIELD: /* microsoft double quotes - seen a quote in an quoted field */ ! if (self->have_quotechar && c == self->quotechar) { /* save "" as " */ parse_add_char(self, c); self->state = IN_QUOTED_FIELD; ! } ! else if (c == self->delimiter) { /* save field - wait for new field */ parse_save_field(self); self->state = START_FIELD; ! } ! else if (c == '\0') { /* end of line - return [fields] */ parse_save_field(self); self->state = START_RECORD; ! } ! else if (!self->strict) { parse_add_char(self, c); self->state = IN_FIELD; ! } ! else { /* illegal */ self->had_parse_error = 1; raise_exception("%c expected after %c", ! self->delimiter, self->quotechar); } break; *************** *** 257,261 **** return NULL; ! if (self->auto_clear && self->had_parse_error) clear_fields_and_status(self); --- 297,301 ---- return NULL; ! if (self->autoclear && self->had_parse_error) clear_fields_and_status(self); *************** *** 350,354 **** if (self->num_fields > 0) { if (copy_phase) ! self->rec[rec_len] = self->field_sep; rec_len++; } --- 390,394 ---- if (self->num_fields > 0) { if (copy_phase) ! self->rec[rec_len] = self->delimiter; rec_len++; } *************** *** 356,360 **** */ if (copy_phase && *quoted) { ! self->rec[rec_len] = self->quote_char; rec_len++; } --- 396,400 ---- */ if (copy_phase && *quoted) { ! self->rec[rec_len] = self->quotechar; rec_len++; } *************** *** 367,373 **** * quote. */ ! if (c == self->quote_char && self->ms_double_quote) { if (copy_phase) ! self->rec[rec_len] = self->quote_char; *quoted = 1; rec_len++; --- 407,413 ---- * quote. */ ! if (c == self->have_quotechar && self->doublequote) { if (copy_phase) ! self->rec[rec_len] = self->quotechar; *quoted = 1; rec_len++; *************** *** 378,388 **** */ if (!*quoted ! && (c == self->field_sep || c == self->escape_char || c == '\n' || c == '\r')) { ! if (self->quote_char) *quoted = 1; ! else if (self->escape_char) { if (copy_phase) ! self->rec[rec_len] = self->escape_char; rec_len++; } --- 418,428 ---- */ if (!*quoted ! && (c == self->delimiter || c == self->escapechar || c == '\n' || c == '\r')) { ! if (self->have_quotechar) *quoted = 1; ! else if (self->escapechar) { if (copy_phase) ! self->rec[rec_len] = self->escapechar; rec_len++; } *************** *** 397,401 **** /* If field is empty check if it needs to be quoted. */ ! if (i == 0 && quote_empty && self->quote_char) *quoted = 1; --- 437,441 ---- /* If field is empty check if it needs to be quoted. */ ! if (i == 0 && quote_empty && self->have_quotechar) *quoted = 1; *************** *** 404,408 **** if (*quoted) { if (copy_phase) ! self->rec[rec_len] = self->quote_char; else /* Didn't know about leading quote until we found it --- 444,448 ---- if (*quoted) { if (copy_phase) ! self->rec[rec_len] = self->quotechar; else /* Didn't know about leading quote until we found it *************** *** 429,433 **** self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR; self->rec = PyMem_Malloc(self->rec_size); ! } else { char *old_rec = self->rec; --- 469,474 ---- self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR; self->rec = PyMem_Malloc(self->rec_size); ! } ! else { char *old_rec = self->rec; *************** *** 488,495 **** append_ok = join_append(self, PyString_AsString(field), len == 1); Py_DECREF(field); ! } else if (field == Py_None) { append_ok = join_append(self, "", len == 1); Py_DECREF(field); ! } else { PyObject *str; --- 529,538 ---- append_ok = join_append(self, PyString_AsString(field), len == 1); Py_DECREF(field); ! } ! else if (field == Py_None) { append_ok = join_append(self, "", len == 1); Py_DECREF(field); ! } ! else { PyObject *str; *************** *** 524,530 **** if (self->field) free(self->field); ! if (self->fields) { ! Py_XDECREF(self->fields); ! } if (self->rec) free(self->rec); --- 567,573 ---- if (self->field) free(self->field); ! Py_XDECREF(self->fields); ! Py_XDECREF(self->lineterminator); ! if (self->rec) free(self->rec); *************** *** 536,549 **** static struct memberlist Parser_memberlist[] = { ! { "ms_double_quote", T_INT, OFF(ms_double_quote) }, ! { "fields", T_OBJECT, OFF(fields) }, ! { "field_sep", T_CHAR, OFF(field_sep) }, ! { "quote_char", T_CHAR, OFF(quote_char) }, ! { "escape_char", T_CHAR, OFF(escape_char) }, ! { "auto_clear", T_INT, OFF(auto_clear) }, ! { "strict", T_INT, OFF(strict) }, ! { "had_parse_error", T_INT, OFF(had_parse_error), RO }, ! ! { NULL } /* Sentinel */ }; --- 579,594 ---- static struct memberlist Parser_memberlist[] = { ! { "quotechar", T_CHAR, OFF(quotechar) }, ! { "delimiter", T_CHAR, OFF(delimiter) }, ! { "escapechar", T_CHAR, OFF(escapechar) }, ! { "skipinitialspace", T_INT, OFF(skipinitialspace) }, ! { "lineterminator", T_OBJECT, OFF(lineterminator) }, ! { "quoting", T_INT, OFF(quoting) }, ! { "doublequote", T_INT, OFF(doublequote) }, ! { "fields", T_OBJECT, OFF(fields) }, ! { "autoclear", T_INT, OFF(autoclear) }, ! { "strict", T_INT, OFF(strict) }, ! { "had_parse_error", T_INT, OFF(had_parse_error), RO }, ! { NULL } }; *************** *** 561,565 **** static int ! _set_char_attr(char *attr, PyObject *v) { /* Special case for constructor - NULL == use default. --- 606,610 ---- static int ! _set_char_attr(char *attr, int *have_attr, PyObject *v) { /* Special case for constructor - NULL == use default. *************** *** 570,581 **** if (v == Py_None) { *attr = 0; return 0; ! } else if (PyInt_Check(v) && PyInt_AsLong(v) == 0) { *attr = 0; return 0; ! } else if (PyString_Check(v) && PyString_Size(v) == 1) { *attr = PyString_AsString(v)[0]; return 0; ! } else { PyErr_BadArgument(); return -1; --- 615,632 ---- if (v == Py_None) { *attr = 0; + *have_attr = 0; return 0; ! } ! else if (PyInt_Check(v) && PyInt_AsLong(v) == 0) { ! *have_attr = 0; *attr = 0; return 0; ! } ! else if (PyString_Check(v) && PyString_Size(v) == 1) { *attr = PyString_AsString(v)[0]; + *have_attr = 1; return 0; ! } ! else { PyErr_BadArgument(); return -1; *************** *** 590,599 **** return -1; } ! if (strcmp(name, "field_sep") == 0) ! return _set_char_attr(&self->field_sep, v); ! else if (strcmp(name, "quote_char") == 0) ! return _set_char_attr(&self->quote_char, v); ! else if (strcmp(name, "escape_char") == 0) ! return _set_char_attr(&self->escape_char, v); else return PyMember_Set((char *)self, Parser_memberlist, name, v); --- 641,656 ---- return -1; } ! if (strcmp(name, "delimiter") == 0) { ! int have_delimiter; ! ! return _set_char_attr(&self->delimiter, ! &have_delimiter, v); ! } ! else if (strcmp(name, "quotechar") == 0) ! return _set_char_attr(&self->quotechar, ! &self->have_quotechar, v); ! else if (strcmp(name, "escapechar") == 0) ! return _set_char_attr(&self->escapechar, ! &self->have_escapechar, v); else return PyMember_Set((char *)self, Parser_memberlist, name, v); *************** *** 630,647 **** PyDoc_STRVAR(csv_parser_doc, ! "parser(ms_double_quote = 1, field_sep = ',',\n" ! " auto_clear = 1, strict = 0,\n" ! " quote_char = '\"', escape_char = None) -> Parser\n" ! "\n" ! "Constructs a CSV parser object. \n" "\n" ! " ms_double_quote\n" ! " When True, quotes in a fields must be doubled up.\n" "\n" ! " field_sep\n" " Defines the character that will be used to separate\n" " fields in the CSV record.\n" "\n" ! " auto_clear\n" " When True, calling parse() will automatically call\n" " the clear() method if the previous call to parse() raised an\n" --- 687,723 ---- PyDoc_STRVAR(csv_parser_doc, ! "parser(delimiter=',', quotechar='\"', escapechar=None,\n" ! " doublequote=1, lineterminator='\\r\\n', quoting='minimal',\n" ! " autoclear=1, strict=0) -> Parser\n" "\n" ! "Constructs a CSV parser object.\n" "\n" ! " delimiter\n" " Defines the character that will be used to separate\n" " fields in the CSV record.\n" "\n" ! " quotechar\n" ! " Defines the character used to quote fields that\n" ! " contain the field separator or newlines. If set to None\n" ! " special characters will be escaped using the escapechar.\n" ! "\n" ! " escapechar\n" ! " Defines the character used to escape special\n" ! " characters. Only used if quotechar is None.\n" ! "\n" ! " doublequote\n" ! " When True, quotes in a fields must be doubled up.\n" ! "\n" ! " skipinitialspace\n" ! " When True spaces following the delimiter are ignored.\n" ! "\n" ! " lineterminator\n" ! " The string used to terminate records.\n" ! "\n" ! " quoting\n" ! " Controls the generation of quotes around fields when writing\n" ! " records. This is only used when quotechar is not None.\n" ! "\n" ! " autoclear\n" " When True, calling parse() will automatically call\n" " the clear() method if the previous call to parse() raised an\n" *************** *** 651,664 **** " When True, the parser will raise an exception on\n" " malformed fields rather than attempting to guess the right\n" ! " behavior.\n" ! "\n" ! " quote_char\n" ! " Defines the character used to quote fields that\n" ! " contain the field separator or newlines. If set to None\n" ! " special characters will be escaped using the escape_char.\n" ! "\n" ! " escape_char\n" ! " Defines the character used to escape special\n" ! " characters. Only used if quote_char is None.\n"); static PyObject * --- 727,731 ---- " When True, the parser will raise an exception on\n" " malformed fields rather than attempting to guess the right\n" ! " behavior.\n"); static PyObject * *************** *** 666,673 **** { static char *keywords[] = { ! "ms_double_quote", "field_sep", "auto_clear", "strict", ! "quote_char", "escape_char", NULL }; ! PyObject *quote_char, *escape_char; ParserObj *self = PyObject_NEW(ParserObj, &Parser_Type); --- 733,742 ---- { static char *keywords[] = { ! "quotechar", "delimiter", "escapechar", "skipinitialspace", ! "lineterminator", "quoting", "doublequote", ! "autoclear", "strict", ! NULL }; ! PyObject *quotechar, *escapechar; ParserObj *self = PyObject_NEW(ParserObj, &Parser_Type); *************** *** 675,690 **** return NULL; ! self->state = START_RECORD; ! self->fields = PyList_New(0); ! self->ms_double_quote = 1; ! self->auto_clear = 1; self->strict = 0; - self->field_sep = ','; - quote_char = escape_char = NULL; - self->quote_char = '"'; - self->escape_char = '\0'; self->had_parse_error = 0; - self->field = NULL; self->field_size = 0; --- 744,762 ---- return NULL; ! self->quotechar = '"'; ! self->have_quotechar = 1; ! self->delimiter = ','; ! self->escapechar = '\0'; ! self->have_escapechar = 0; ! self->skipinitialspace = 0; ! self->lineterminator = PyString_FromString("\r\n"); ! self->quoting = QUOTE_MINIMAL; ! self->doublequote = 1; ! self->autoclear = 1; self->strict = 0; + self->state = START_RECORD; + self->fields = PyList_New(0); self->had_parse_error = 0; self->field = NULL; self->field_size = 0; *************** *** 696,707 **** self->num_fields = 0; ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|iciiOO", keywords, ! &self->ms_double_quote, ! &self->field_sep, ! &self->auto_clear, &self->strict, ! "e_char, &escape_char) ! && !_set_char_attr(&self->quote_char, quote_char) ! && !_set_char_attr(&self->escape_char, escape_char)) return (PyObject*)self; --- 768,788 ---- self->num_fields = 0; ! if (self->lineterminator == NULL || self->fields == NULL) { ! Py_DECREF(self); ! return NULL; ! } ! ! quotechar = escapechar = NULL; ! if (PyArg_ParseTupleAndKeywords(args, keyword_args, "|OcOisiiii", keywords, ! "echar, &self->delimiter, ! &escapechar, &self->skipinitialspace, ! &self->lineterminator, &self->quoting, ! &self->doublequote, ! &self->autoclear, &self->strict) ! && !_set_char_attr(&self->quotechar, ! &self->have_quotechar, quotechar) ! && !_set_char_attr(&self->escapechar, ! &self->have_escapechar, escapechar)) return (PyObject*)self; *************** *** 722,726 **** "following methods:\n" " clear()\n" ! " Discards all fields parsed so far. If auto_clear is set to\n" " zero. You should call this after a parser exception.\n" "\n" --- 803,807 ---- "following methods:\n" " clear()\n" ! " Discards all fields parsed so far. If autoclear is set to\n" " zero. You should call this after a parser exception.\n" "\n" From davecole@users.sourceforge.net Thu Jan 30 13:34:32 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Thu, 30 Jan 2003 05:34:32 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv740 Modified Files: pep-0305.txt Log Message: Use symbolic constants for quoting parameter rather than a string. Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0305.txt 30 Jan 2003 12:53:40 -0000 1.6 --- pep-0305.txt 30 Jan 2003 13:34:29 -0000 1.7 *************** *** 143,147 **** skipinitialspace = False lineterminator = '\r\n' ! quoting = 'minimal' An excel tab separated dialect can then be defined in user code as --- 143,147 ---- skipinitialspace = False lineterminator = '\r\n' ! quoting = QUOTE_MINIMAL An excel tab separated dialect can then be defined in user code as From davecole@users.sourceforge.net Thu Jan 30 13:36:12 2003 From: davecole@users.sourceforge.net (davecole@users.sourceforge.net) Date: Thu, 30 Jan 2003 05:36:12 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv _csv.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv1538 Modified Files: _csv.c Log Message: Fixed typo in csv_parser_doc docstring. Index: _csv.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/_csv.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _csv.c 30 Jan 2003 13:16:06 -0000 1.3 --- _csv.c 30 Jan 2003 13:36:06 -0000 1.4 *************** *** 707,711 **** "\n" " doublequote\n" ! " When True, quotes in a fields must be doubled up.\n" "\n" " skipinitialspace\n" --- 707,711 ---- "\n" " doublequote\n" ! " When True, quotes in a field must be doubled up.\n" "\n" " skipinitialspace\n" From mwh@users.sourceforge.net Thu Jan 30 14:17:21 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 30 Jan 2003 06:17:21 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.59,2.60 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv17657 Modified Files: readline.c Log Message: I was in this module anyway, so I did some janitorial things. METH_NOARGS functions are still called with two arguments, one NULL, so put that back into the function definitions (I didn't know this until recently). Make get_history_length() METH_NOARGS. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.59 retrieving revision 2.60 diff -C2 -d -r2.59 -r2.60 *** readline.c 30 Jan 2003 10:12:51 -0000 2.59 --- readline.c 30 Jan 2003 14:17:16 -0000 2.60 *************** *** 151,159 **** static PyObject* ! get_history_length(PyObject *self, PyObject *args) { ! if (!PyArg_ParseTuple(args, ":get_history_length")) ! return NULL; ! return Py_BuildValue("i", history_length); } --- 151,157 ---- static PyObject* ! get_history_length(PyObject *self, PyObject *noarg) { ! return PyInt_FromLong(history_length); } *************** *** 256,260 **** static PyObject * ! get_begidx(PyObject *self) { Py_INCREF(begidx); --- 254,258 ---- static PyObject * ! get_begidx(PyObject *self, PyObject *noarg) { Py_INCREF(begidx); *************** *** 270,274 **** static PyObject * ! get_endidx(PyObject *self) { Py_INCREF(endidx); --- 268,272 ---- static PyObject * ! get_endidx(PyObject *self, PyObject *noarg) { Py_INCREF(endidx); *************** *** 325,329 **** static PyObject * ! get_completer_delims(PyObject *self) { return PyString_FromString(rl_completer_word_break_characters); --- 323,327 ---- static PyObject * ! get_completer_delims(PyObject *self, PyObject *noarg) { return PyString_FromString(rl_completer_word_break_characters); *************** *** 393,397 **** static PyObject * ! get_current_history_length(PyObject *self) { HISTORY_STATE *hist_st; --- 391,395 ---- static PyObject * ! get_current_history_length(PyObject *self, PyObject *noarg) { HISTORY_STATE *hist_st; *************** *** 409,413 **** static PyObject * ! get_line_buffer(PyObject *self) { return PyString_FromString(rl_line_buffer); --- 407,411 ---- static PyObject * ! get_line_buffer(PyObject *self, PyObject *noarg) { return PyString_FromString(rl_line_buffer); *************** *** 440,444 **** static PyObject * ! redisplay(PyObject *self) { rl_redisplay(); --- 438,442 ---- static PyObject * ! redisplay(PyObject *self, PyObject *noarg) { rl_redisplay(); *************** *** 458,465 **** { {"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind}, ! {"get_line_buffer", (PyCFunction)get_line_buffer, ! METH_NOARGS, doc_get_line_buffer}, {"insert_text", insert_text, METH_VARARGS, doc_insert_text}, ! {"redisplay", (PyCFunction)redisplay, METH_NOARGS, doc_redisplay}, {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file}, {"read_history_file", read_history_file, --- 456,462 ---- { {"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind}, ! {"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer}, {"insert_text", insert_text, METH_VARARGS, doc_insert_text}, ! {"redisplay", redisplay, METH_NOARGS, doc_redisplay}, {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file}, {"read_history_file", read_history_file, *************** *** 474,487 **** METH_VARARGS, set_history_length_doc}, {"get_history_length", get_history_length, ! METH_VARARGS, get_history_length_doc}, {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, {"get_completer", get_completer, METH_NOARGS, doc_get_completer}, ! {"get_begidx", (PyCFunction)get_begidx, METH_NOARGS, doc_get_begidx}, ! {"get_endidx", (PyCFunction)get_endidx, METH_NOARGS, doc_get_endidx}, {"set_completer_delims", set_completer_delims, METH_VARARGS, doc_set_completer_delims}, {"add_history", py_add_history, METH_VARARGS, doc_add_history}, ! {"get_completer_delims", (PyCFunction)get_completer_delims, METH_NOARGS, doc_get_completer_delims}, --- 471,484 ---- METH_VARARGS, set_history_length_doc}, {"get_history_length", get_history_length, ! METH_NOARGS, get_history_length_doc}, {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, {"get_completer", get_completer, METH_NOARGS, doc_get_completer}, ! {"get_begidx", get_begidx, METH_NOARGS, doc_get_begidx}, ! {"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx}, {"set_completer_delims", set_completer_delims, METH_VARARGS, doc_set_completer_delims}, {"add_history", py_add_history, METH_VARARGS, doc_add_history}, ! {"get_completer_delims", get_completer_delims, METH_NOARGS, doc_get_completer_delims}, From gvanrossum@users.sourceforge.net Thu Jan 30 14:34:10 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 30 Jan 2003 06:34:10 -0800 Subject: [Python-checkins] python/nondist/sandbox/sets set.py,1.9,NONE test_set.py,1.6,NONE Message-ID: Update of /cvsroot/python/python/nondist/sandbox/sets In directory sc8-pr-cvs1:/tmp/cvs-serv25579 Removed Files: set.py test_set.py Log Message: This sandbox has served its purpose. --- set.py DELETED --- --- test_set.py DELETED --- From gvanrossum@users.sourceforge.net Thu Jan 30 14:54:17 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 30 Jan 2003 06:54:17 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.153,1.154 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv753/datetime Modified Files: datetime.py Log Message: doctools has served its purpose; inspect and pydoc are standard modules. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.153 retrieving revision 1.154 diff -C2 -d -r1.153 -r1.154 *** datetime.py 30 Jan 2003 06:01:06 -0000 1.153 --- datetime.py 30 Jan 2003 14:54:13 -0000 1.154 *************** *** 665,669 **** """ if isinstance(year, str): ! # From pickle __getstate__ self = object.__new__(cls) self.__setstate__((year,)) --- 665,669 ---- """ if isinstance(year, str): ! # Pickle support self = object.__new__(cls) self.__setstate__((year,)) *************** *** 923,934 **** return dt - # pickle support - # XXX Should do something with __new__ instead - - __safe_for_unpickling__ = True - - def __reduce__(self): - return type(self), (), self.__dict__ - _tzinfo_class = tzinfo # so functions w/ args named "tinfo" can get at it --- 923,926 ---- *************** *** 968,978 **** self = object.__new__(cls) if isinstance(hour, str): ! # Call from protocol 2 unpickling ! assert len(hour) == 6 ! assert minute == 0 or isinstance(minute, _tzinfo_class), `minute` ! self.__hour, self.__minute, self.__second, us1, us2, us3 = \ ! map(ord, hour) ! self.__microsecond = (((us1 << 8) | us2) << 8) | us3 ! self._tzinfo = minute or None return self _check_tzinfo_arg(tzinfo) --- 960,965 ---- self = object.__new__(cls) if isinstance(hour, str): ! # Pickle support ! self.__setstate__((hour, minute or None)) return self _check_tzinfo_arg(tzinfo) From gvanrossum@users.sourceforge.net Thu Jan 30 14:54:17 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 30 Jan 2003 06:54:17 -0800 Subject: [Python-checkins] python/nondist/sandbox/doctools README,1.2,NONE htmldoc.py,1.2,NONE inspect.py,1.1,NONE onlinehelp.py,1.4,NONE textdoc.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/nondist/sandbox/doctools In directory sc8-pr-cvs1:/tmp/cvs-serv753/doctools Removed Files: README htmldoc.py inspect.py onlinehelp.py textdoc.py Log Message: doctools has served its purpose; inspect and pydoc are standard modules. --- README DELETED --- --- htmldoc.py DELETED --- --- inspect.py DELETED --- --- onlinehelp.py DELETED --- --- textdoc.py DELETED --- From tim_one@users.sourceforge.net Thu Jan 30 15:02:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 30 Jan 2003 07:02:17 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv4758/Lib Modified Files: pickletools.py Log Message: dis(): Simplified stack emulation a bit. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** pickletools.py 29 Jan 2003 20:12:21 -0000 1.22 --- pickletools.py 30 Jan 2003 15:02:12 -0000 1.23 *************** *** 1899,1906 **** maxproto = max(maxproto, opcode.proto) - - # See whether a MARK should be popped. before = opcode.stack_before # don't mutate after = opcode.stack_after # don't mutate markmsg = None if markobject in before or (opcode.name == "POP" and --- 1899,1907 ---- maxproto = max(maxproto, opcode.proto) before = opcode.stack_before # don't mutate after = opcode.stack_after # don't mutate + numtopop = len(before) + + # See whether a MARK should be popped. markmsg = None if markobject in before or (opcode.name == "POP" and *************** *** 1908,1911 **** --- 1909,1915 ---- stack[-1] is markobject): assert markobject not in after + if __debug__: + if markobject in before: + assert before[-1] is stackslice if markstack: markpos = markstack.pop() *************** *** 1918,1929 **** stack.pop() stack.pop() ! # Remove markobject stuff from stack_before. try: ! i = before.index(markobject) ! before = before[:i] except ValueError: assert opcode.name == "POP" ! assert len(before) == 1 ! before = [] # stop code later from popping again else: errormsg = markmsg = "no MARK exists on stack" --- 1922,1931 ---- stack.pop() stack.pop() ! # Stop later code from popping too much. try: ! numtopop = before.index(markobject) except ValueError: assert opcode.name == "POP" ! numtopop = 0 else: errormsg = markmsg = "no MARK exists on stack" *************** *** 1931,1934 **** --- 1933,1937 ---- # Check for correct memo usage. if opcode.name in ("PUT", "BINPUT", "LONG_BINPUT"): + assert arg is not None if arg in memo: errormsg = "memo key %r already defined" % arg *************** *** 1962,1973 **** # Emulate the stack effects. ! n = len(before) ! if len(stack) < n: ! raise ValueError("tried to pop %d items from stack with " ! "only %d items" % (n, len(stack))) ! if n: ! del stack[-n:] if markobject in after: ! assert markobject not in opcode.stack_before markstack.append(pos) --- 1965,1975 ---- # Emulate the stack effects. ! if len(stack) < numtopop: ! raise ValueError("tries to pop %d items from stack with " ! "only %d items" % (numtopop, len(stack))) ! if numtopop: ! del stack[-numtopop:] if markobject in after: ! assert markobject not in before markstack.append(pos) From fdrake@users.sourceforge.net Thu Jan 30 15:08:29 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 30 Jan 2003 07:08:29 -0800 Subject: [Python-checkins] python/dist/src/Python modsupport.c,2.63,2.64 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv8109 Modified Files: modsupport.c Log Message: Style consistency, so "grep ^function ..." works as expected. Index: modsupport.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/modsupport.c,v retrieving revision 2.63 retrieving revision 2.64 diff -C2 -d -r2.63 -r2.64 *** modsupport.c 15 Dec 2002 13:45:32 -0000 2.63 --- modsupport.c 30 Jan 2003 15:08:25 -0000 2.64 *************** *** 90,94 **** /* Helper for mkvalue() to scan the length of a format */ ! static int countformat(char *format, int endchar) { int count = 0; --- 90,95 ---- /* Helper for mkvalue() to scan the length of a format */ ! static int ! countformat(char *format, int endchar) { int count = 0; *************** *** 401,405 **** ! PyObject *Py_BuildValue(char *format, ...) { va_list va; --- 402,407 ---- ! PyObject * ! Py_BuildValue(char *format, ...) { va_list va; From mwh@users.sourceforge.net Thu Jan 30 15:23:02 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 30 Jan 2003 07:23:02 -0800 Subject: [Python-checkins] python/nondist/peps pep-0306.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv15906 Modified Files: pep-0306.txt Log Message: Note posting to python-dev. Index: pep-0306.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0306.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pep-0306.txt 30 Jan 2003 10:27:45 -0000 1.2 --- pep-0306.txt 30 Jan 2003 15:22:56 -0000 1.3 *************** *** 8,12 **** Content-Type: text/plain Created: 29-Jan-2003 ! Post-History: --- 8,12 ---- Content-Type: text/plain Created: 29-Jan-2003 ! Post-History: 30-Jan-2003 From tim_one@users.sourceforge.net Thu Jan 30 15:41:59 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 30 Jan 2003 07:41:59 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.127,1.128 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv30069/Lib Modified Files: pickle.py Log Message: load_inst(), load_obj(): Put the bulk of these into a common new _instantiate() method. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.127 retrieving revision 1.128 diff -C2 -d -r1.127 -r1.128 *** pickle.py 30 Jan 2003 06:37:41 -0000 1.127 --- pickle.py 30 Jan 2003 15:41:46 -0000 1.128 *************** *** 1066,1079 **** dispatch[DICT] = load_dict ! def load_inst(self): ! k = self.marker() args = tuple(self.stack[k+1:]) del self.stack[k:] - module = self.readline()[:-1] - name = self.readline()[:-1] - klass = self.find_class(module, name) instantiated = 0 ! if (not args and type(klass) is ClassType and ! not hasattr(klass, "__getinitargs__")): try: value = _EmptyClass() --- 1066,1081 ---- dispatch[DICT] = load_dict ! # INST and OBJ differ only in how they get a class object. It's not ! # only sensible to do the rest in a common routine, the two routines ! # previously diverged and grew different bugs. ! # klass is the class to instantiate, and k points to the topmost mark ! # object, following which are the arguments for klass.__init__. ! def _instantiate(self, klass, k): args = tuple(self.stack[k+1:]) del self.stack[k:] instantiated = 0 ! if (not args and ! type(klass) is ClassType and ! not hasattr(klass, "__getinitargs__")): try: value = _EmptyClass() *************** *** 1091,1117 **** klass.__name__, str(err)), sys.exc_info()[2] self.append(value) dispatch[INST] = load_inst def load_obj(self): ! stack = self.stack k = self.marker() ! klass = stack[k + 1] ! del stack[k + 1] ! args = tuple(stack[k + 1:]) ! del stack[k:] ! instantiated = 0 ! if (not args and type(klass) is ClassType and ! not hasattr(klass, "__getinitargs__")): ! try: ! value = _EmptyClass() ! value.__class__ = klass ! instantiated = 1 ! except RuntimeError: ! # In restricted execution, assignment to inst.__class__ is ! # prohibited ! pass ! if not instantiated: ! value = klass(*args) ! self.append(value) dispatch[OBJ] = load_obj --- 1093,1109 ---- klass.__name__, str(err)), sys.exc_info()[2] self.append(value) + + def load_inst(self): + module = self.readline()[:-1] + name = self.readline()[:-1] + klass = self.find_class(module, name) + self._instantiate(klass, self.marker()) dispatch[INST] = load_inst def load_obj(self): ! # Stack is ... markobject classobject arg1 arg2 ... k = self.marker() ! klass = self.stack.pop(k+1) ! self._instantiate(klass, k) dispatch[OBJ] = load_obj From tim_one@users.sourceforge.net Thu Jan 30 16:35:16 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 30 Jan 2003 08:35:16 -0800 Subject: [Python-checkins] python/dist/src/Lib pickletools.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv1955/Lib Modified Files: pickletools.py Log Message: Updated the INST/OBJ docs, to say they really are (almost) identical in 2.3. Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** pickletools.py 30 Jan 2003 15:02:12 -0000 1.23 --- pickletools.py 30 Jan 2003 16:35:08 -0000 1.24 *************** *** 1615,1618 **** --- 1615,1620 ---- argtuple obtained from the stack, and the resulting instance object is pushed on the stack. + + NOTE: checks for __safe_for_unpickling__ went away in Python 2.3. """), *************** *** 1644,1647 **** --- 1646,1653 ---- a bug; cPickle does test __safe_for_unpickling__). See INST for the gory details. + + NOTE: In Python 2.3, INST and OBJ are identical except for how they + get the class object. That was always the intent; the implementations + had diverged for accidental reasons. """), From rhettinger@users.sourceforge.net Thu Jan 30 17:08:03 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 30 Jan 2003 09:08:03 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools libitertools.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv17703 Modified Files: libitertools.tex Log Message: Review comments from Paul Moore. Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** libitertools.tex 30 Jan 2003 04:16:43 -0000 1.18 --- libitertools.tex 30 Jan 2003 17:07:59 -0000 1.19 *************** *** 72,78 **** \begin{funcdesc}{count}{\optional{n}} Make an iterator that returns consecutive integers starting with \var{n}. ! Often used as a argument to \function{imap()} to generate consecutive ! data points. Also, used in \function{izip()} to add sequence numbers. ! Equivalent to: \begin{verbatim} --- 72,78 ---- \begin{funcdesc}{count}{\optional{n}} Make an iterator that returns consecutive integers starting with \var{n}. ! Does not currently support python long integers. Often used as an ! argument to \function{imap()} to generate consecutive data points. ! Also, used in \function{izip()} to add sequence numbers. Equivalent to: \begin{verbatim} *************** *** 87,92 **** \begin{funcdesc}{dropwhile}{predicate, iterable} Make an iterator that drops elements from the iterable as long as ! the predicate is true; afterwards, returns every element. ! Equivalent to: \begin{verbatim} --- 87,93 ---- \begin{funcdesc}{dropwhile}{predicate, iterable} Make an iterator that drops elements from the iterable as long as ! the predicate is true; afterwards, returns every element. Note, ! the iterator does not produce \emph{any} output until the predicate ! is true, so it may have a lengthy start-up time. Equivalent to: \begin{verbatim} *************** *** 105,111 **** \begin{funcdesc}{ifilter}{predicate, iterable \optional{, invert}} Make an iterator that filters elements from iterable returning only ! those for which the predicate function evaluates to \code{True}. If \var{invert} is \code{True}, then reverse the process and pass through ! only those elements for which the function evaluates to \code{False}. If \var{predicate} is \code{None}, return the items that are true (or false if \var{invert} has been set). Equivalent to: --- 106,112 ---- \begin{funcdesc}{ifilter}{predicate, iterable \optional{, invert}} Make an iterator that filters elements from iterable returning only ! those for which the predicate is \code{True}. If \var{invert} is \code{True}, then reverse the process and pass through ! only those elements for which the predicate is \code{False}. If \var{predicate} is \code{None}, return the items that are true (or false if \var{invert} has been set). Equivalent to: *************** *** 300,305 **** \end{verbatim} ! As a further example of how itertools can be combined, here ! are a few ways to define higher level tools: \begin{verbatim} --- 301,309 ---- \end{verbatim} ! This section has further examples of how itertools can be combined. ! Note that \function{enumerate()} and \method{iteritems()} already ! have highly efficient implementations in Python. They are only ! included here to illustrate how higher level tools can be created ! from building blocks. \begin{verbatim} From guido@python.org Thu Jan 30 17:23:55 2003 From: guido@python.org (Guido van Rossum) Date: Thu, 30 Jan 2003 12:23:55 -0500 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.59,2.60 In-Reply-To: Your message of "Thu, 30 Jan 2003 06:17:21 PST." References: Message-ID: <200301301723.h0UHNtY04045@odiug.zope.com> > METH_NOARGS functions are still called with two arguments, one NULL, > so put that back into the function definitions (I didn't know this > until recently). Hm, isn't this a bug??? --Guido van Rossum (home page: http://www.python.org/~guido/) From walter@livinglogic.de Thu Jan 30 18:25:38 2003 From: walter@livinglogic.de (=?ISO-8859-15?Q?Walter_D=F6rwald?=) Date: Thu, 30 Jan 2003 19:25:38 +0100 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,NONE,1.1 In-Reply-To: <200301301303.h0UD3N229128@pcp02138704pcs.reston01.va.comcast.net> References: <3E352ADE.3090908@livinglogic.de> <3E3669D9.3090807@livinglogic.de> <20030128115507.GA20057@fallin.lv> <3E391003.5080702@livinglogic.de> <200301301303.h0UD3N229128@pcp02138704pcs.reston01.va.comcast.net> Message-ID: <3E396E22.80601@livinglogic.de> Guido van Rossum wrote: >>OK, I've uploaded a patch that implements a) + d): >>http://www.python.org/sf/677429 > > I don't know anything about iconv, but I noticed that its unit tests > fail for me. Is anyone able to fix this before MvL returns from > vacation at the end of February? (I want to do an alpha release > before then, if Tim & I get the new pickling stuff working.) I don't know anything about iconv either, but it seems to have endianess problems on Linux/Intel. The encodings "ucs-2-internal" and "ucs-4-internal" (which are used if __GNU_LIBRARY__ is undefined) use native endianess, but "ucs-2" and "ucs-4" (which are use if __GNU_LIBRARY__ is defined) always use big-endian order. I've uploaded a patch against current CVS to the original SF patch (#670715) that seems to fix those problems. It simply byteswaps the input before encoding and byteswaps the output pieces after decoding. The only remaining test that fails is test_sane(), because this test tries to encode to/decode from the internal encoding, which of course has the same problems. The patch detects whether it should byteswap via #ifndef WORDS_BIGENDIAN #ifdef __GNU_LIBRARY__ but this might not work with all iconv implementations. It would probably be better to do a little test call to iconv() in Modules/_conv_codec.c::init_iconv_codec() to detect whether byteswapping is neccessary. Bye, Walter Dörwald From doerwalter@users.sourceforge.net Thu Jan 30 19:55:30 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Thu, 30 Jan 2003 11:55:30 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_iconv_codecs.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25417/Lib/test Modified Files: test_iconv_codecs.py Log Message: Check whether the choosen encoding requires byte swapping for this iconv() implementation in the init function. For encoding: use a byteswapped version of the input if neccessary. For decoding: byteswap every piece returned by iconv() if neccessary (but not those pieces returned from the callback) Comment out test_sane() in the test script, because whether this works depends on whether byte swapping is neccessary or not (an on Py_UNICODE_SIZE) Index: test_iconv_codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_iconv_codecs.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_iconv_codecs.py 27 Jan 2003 11:28:52 -0000 1.1 --- test_iconv_codecs.py 30 Jan 2003 19:55:28 -0000 1.2 *************** *** 8,24 **** if sys.byteorder == 'big': ! spam = '\x00s\x00p\x00a\x00m\x00s\x00p\x00a\x00m' else: ! spam = 's\x00p\x00a\x00m\x00s\x00p\x00a\x00m\x00' def test_sane(self): ! self.encoder, self.decoder, self.reader, self.writer = \ ! codecs.lookup(_iconv_codec.internal_encoding) ! self.assertEqual(self.decoder(self.spam), (u'spamspam', 16)) ! self.assertEqual(self.encoder(u'spamspam'), (self.spam, 8)) ! self.assertEqual(self.reader(StringIO(self.spam)).read(), u'spamspam') ! f = StringIO() ! self.writer(f).write(u'spamspam') ! self.assertEqual(f.getvalue(), self.spam) def test_basic_errors(self): --- 8,28 ---- if sys.byteorder == 'big': ! spam = '\x00s\x00p\x00a\x00m' * 2 else: ! spam = 's\x00p\x00a\x00m\x00' * 2 def test_sane(self): ! # FIXME: Commented out, because it's not clear whether ! # the internal encoding choosen requires byte swapping ! # for this iconv() implementation. ! if False: ! self.encoder, self.decoder, self.reader, self.writer = \ ! codecs.lookup(_iconv_codec.internal_encoding) ! self.assertEqual(self.decoder(self.spam), (u'spamspam', 16)) ! self.assertEqual(self.encoder(u'spamspam'), (self.spam, 8)) ! self.assertEqual(self.reader(StringIO(self.spam)).read(), u'spamspam') ! f = StringIO() ! self.writer(f).write(u'spamspam') ! self.assertEqual(f.getvalue(), self.spam) def test_basic_errors(self): From doerwalter@users.sourceforge.net Thu Jan 30 19:55:30 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Thu, 30 Jan 2003 11:55:30 -0800 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv25417/Modules Modified Files: _iconv_codec.c Log Message: Check whether the choosen encoding requires byte swapping for this iconv() implementation in the init function. For encoding: use a byteswapped version of the input if neccessary. For decoding: byteswap every piece returned by iconv() if neccessary (but not those pieces returned from the callback) Comment out test_sane() in the test script, because whether this works depends on whether byte swapping is neccessary or not (an on Py_UNICODE_SIZE) Index: _iconv_codec.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** _iconv_codec.c 27 Jan 2003 11:39:04 -0000 1.4 --- _iconv_codec.c 30 Jan 2003 19:55:28 -0000 1.5 *************** *** 43,46 **** --- 43,50 ---- staticforward PyTypeObject iconvcodec_Type; + /* does the choosen internal encoding require + * byteswapping to get native endianness? + * 0=no, 1=yes, -1=unknown */ + static int byteswap = -1; #define ERROR_STRICT (PyObject *)(1) *************** *** 89,92 **** --- 93,98 ---- PyObject *outputobj = NULL, *errorcb = NULL, *exceptionobj = NULL; + Py_UNICODE *swappedinput; + int swapi; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "u#|s:encode", *************** *** 122,125 **** --- 128,149 ---- out_top = PyString_AS_STRING(outputobj); \ } + if (byteswap) { + swappedinput = PyMem_Malloc(inplen); + if (swappedinput == NULL) + return NULL; + for (swapi = 0; swapi 0) { if (iconv(self->enchdl, (char**)&inp, &inplen, &out, &outlen) == -1) { *************** *** 254,257 **** --- 278,283 ---- if (rettup == NULL) { Py_DECREF(outputobj); + if (byteswap) + PyMem_Free(swappedinput); return NULL; } *************** *** 267,270 **** --- 293,298 ---- } Py_XDECREF(exceptionobj); + if (byteswap) + PyMem_Free(swappedinput); return NULL; *************** *** 320,324 **** } while (inplen > 0) { ! if (iconv(self->dechdl, (char**)&inp, &inplen, &out, &outlen) == -1) { char reason[128], *reasonpos = (char *)reason; int errpos; --- 348,372 ---- } while (inplen > 0) { ! char *oldout = out; ! char res = iconv(self->dechdl, (char**)&inp, &inplen, &out, &outlen); ! ! if (byteswap) { ! while (oldout < out) ! { ! char c0 = oldout[0]; ! #if Py_UNICODE_SIZE == 2 ! oldout[0] = oldout[1]; ! oldout[1] = c0; ! #else ! char c1 = oldout[1]; ! oldout[0] = oldout[3]; ! oldout[1] = oldout[2]; ! oldout[2] = c1; ! oldout[3] = c0; ! #endif ! oldout += sizeof(Py_UNICODE); ! } ! } ! if (res == -1) { char reason[128], *reasonpos = (char *)reason; int errpos; *************** *** 602,605 **** --- 650,683 ---- { PyObject *m; + + char in = 1; + char *inptr = ∈ + int insize = 1; + Py_UNICODE out = 0; + char *outptr = (char *)&out; + int outsize = sizeof(out); + int res; + + iconv_t hdl = iconv_open(UNICODE_ENCODING, "ASCII"); + + if (hdl == (iconv_t)-1) + Py_FatalError("can't initialize the _iconv_codec module: iconv_open() failed"); + + res = iconv(hdl, &inptr, &insize, &outptr, &outsize); + if (res == -1) + Py_FatalError("can't initialize the _iconv_codec module: iconv() failed"); + + /* Check whether conv() returned native endianess or not for the choosen encoding */ + if (out == 0x1) + byteswap = 0; + #if Py_UNICODE_SIZE == 2 + else if (out == 0x0100) + #else + else if (out == 0x01000000) + #endif + byteswap = 1; + else + Py_FatalError("can't initialize the _iconv_codec module: mixed endianess"); + iconv_close(hdl); m = Py_InitModule("_iconv_codec", _iconv_codec_methods); From tim_one@users.sourceforge.net Thu Jan 30 21:27:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 30 Jan 2003 13:27:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_pickle.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv1781/Lib/test Modified Files: test_pickle.py Log Message: pickle.py has a few doctest'ed internal functions, so run their tests. Index: test_pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pickle.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** test_pickle.py 29 Jan 2003 17:58:44 -0000 1.15 --- test_pickle.py 30 Jan 2003 21:27:37 -0000 1.16 *************** *** 70,73 **** --- 70,74 ---- suite.addTest(loader.loadTestsFromTestCase(PersPicklerTests)) test_support.run_suite(suite) + test_support.run_doctest(pickle) if __name__ == "__main__": From gvanrossum@users.sourceforge.net Thu Jan 30 22:01:49 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 30 Jan 2003 14:01:49 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.154,1.155 test_datetime.py,1.107,1.108 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv13206 Modified Files: datetime.py test_datetime.py Log Message: Switched the pickling strategy around again. Never mind protocol 2 in Python 2.3 or the copy_reg registry, we can do just as well with __reduce__. Pay special attention to tzinfo.__reduce__, which calls self.__getinitargs__ and self.__getstate__ if they exist, and defaults to self.__dict__ if it exists and is non-empty. The other __reduce__ implementations simply recycle __getstate__. All __reduce__ implementations return self.__class__ as the callable. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.154 retrieving revision 1.155 diff -C2 -d -r1.154 -r1.155 *** datetime.py 30 Jan 2003 14:54:13 -0000 1.154 --- datetime.py 30 Jan 2003 22:01:30 -0000 1.155 *************** *** 612,626 **** # Pickle support. ! # This magic class attr is necessary for pickle compatibility with the ! # C implementation. ! __safe_for_unpickling__ = True def __getstate__(self): return (self.__days, self.__seconds, self.__microseconds) - __getnewargs__ = __getstate__ def __setstate__(self, tup): self.__days, self.__seconds, self.__microseconds = tup timedelta.min = timedelta(-999999999) timedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59, --- 612,627 ---- # Pickle support. ! ! __safe_for_unpickling__ = True # For Python 2.2 def __getstate__(self): return (self.__days, self.__seconds, self.__microseconds) def __setstate__(self, tup): self.__days, self.__seconds, self.__microseconds = tup + def __reduce__(self): + return (self.__class__, self.__getstate__()) + timedelta.min = timedelta(-999999999) timedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59, *************** *** 853,860 **** # Pickle support. def __getstate__(self): yhi, ylo = divmod(self.__year, 256) return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) - __getnewargs__ = __getstate__ def __setstate__(self, t): --- 854,862 ---- # Pickle support. + __safe_for_unpickling__ = True # For Python 2.2 + def __getstate__(self): yhi, ylo = divmod(self.__year, 256) return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) def __setstate__(self, t): *************** *** 865,868 **** --- 867,873 ---- self.__year = yhi * 256 + ylo + def __reduce__(self): + return (self.__class__, self.__getstate__()) + _date_class = date # so functions w/ args named "date" can get at the class *************** *** 923,926 **** --- 928,951 ---- return dt + # Pickle support. + + __safe_for_unpickling__ = True # For Python 2.2 + + def __reduce__(self): + getinitargs = getattr(self, "__getinitargs__", None) + if getinitargs: + args = getinitargs() + else: + args = () + getstate = getattr(self, "__getstate__", None) + if getstate: + state = getstate() + else: + state = getattr(self, "__dict__", None) or None + if state is None: + return (self.__class__, args) + else: + return (self.__class__, args, state) + _tzinfo_class = tzinfo # so functions w/ args named "tinfo" can get at it *************** *** 1153,1156 **** --- 1178,1183 ---- # Pickle support. + __safe_for_unpickling__ = True # For Python 2.2 + def __getstate__(self): us2, us3 = divmod(self.__microsecond, 256) *************** *** 1162,1166 **** else: return (basestate, self._tzinfo) - __getnewargs__ = __getstate__ def __setstate__(self, state): --- 1189,1192 ---- *************** *** 1180,1183 **** --- 1206,1212 ---- self._tzinfo = state[1] + def __reduce__(self): + return (self.__class__, self.__getstate__()) + _time_class = time # so functions w/ args named "time" can get at the class *************** *** 1543,1546 **** --- 1572,1579 ---- return hash(timedelta(days, seconds, self.microsecond)) + # Pickle support. + + __safe_for_unpickling__ = True # For Python 2.2 + def __getstate__(self): yhi, ylo = divmod(self.__year, 256) *************** *** 1554,1558 **** else: return (basestate, self._tzinfo) - __getnewargs__ = __getstate__ def __setstate__(self, state): --- 1587,1590 ---- *************** *** 1573,1576 **** --- 1605,1611 ---- self._tzinfo = state[1] + def __reduce__(self): + return (self.__class__, self.__getstate__()) + datetime.min = datetime(1, 1, 1) *************** *** 1589,1632 **** week1monday += 7 return week1monday - - # Pickle support. __getstate__ and __setstate__ work fine on their own, - # but only because the classes here are implemented in Python. The C - # implementation had to get much trickier, and the code following emulates - # what the C code had to do, so that pickles produced by the Python - # implementation can be read by the C implementation, and vice versa. - - def _date_pickler(date): - state = date.__getstate__() - return _date_unpickler, (state,) - - def _date_unpickler(state): - self = date(1, 1, 1) - self.__setstate__(state) - return self - - def _tzinfo_pickler(tz): - return _tzinfo_unpickler, () - - def _tzinfo_unpickler(): - self = tzinfo() - return self - - def _time_pickler(tz): - state = tz.__getstate__() - return _time_unpickler, (state,) - - def _time_unpickler(state): - self = time() - self.__setstate__(state) - return self - - def _datetime_pickler(dtz): - state = dtz.__getstate__() - return _datetime_unpickler, (state,) - - def _datetime_unpickler(state): - self = datetime(1, 1, 1) - self.__setstate__(state) - return self """ --- 1624,1627 ---- Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.107 retrieving revision 1.108 diff -C2 -d -r1.107 -r1.108 *** test_datetime.py 30 Jan 2003 06:01:07 -0000 1.107 --- test_datetime.py 30 Jan 2003 22:01:39 -0000 1.108 *************** *** 5,8 **** --- 5,10 ---- import sys + import pickle + import cPickle import unittest *************** *** 14,17 **** --- 16,35 ---- + pickle_choices = [ + (pickle, pickle, 0), + (pickle, pickle, 1), + (pickle, pickle, 2), + (cPickle, cPickle, 0), + (cPickle, cPickle, 1), + ## (cPickle, cPickle, 2), + (pickle, cPickle, 0), + (pickle, cPickle, 1), + ## (pickle, cPickle, 2), + (cPickle, pickle, 0), + (cPickle, pickle, 1), + ## (cPickle, pickle, 2), + ] + + # XXX The test suite uncovered a bug in Python 2.2.2: if x and y are # XXX instances of new-style classes (like date and time) that both *************** *** 99,104 **** def test_pickling_base(self): - import pickle, cPickle - # There's no point to pickling tzinfo objects on their own (they # carry no data), but they need to be picklable anyway else --- 117,120 ---- *************** *** 106,118 **** orig = tzinfo.__new__(tzinfo) self.failUnless(type(orig) is tzinfo) ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.failUnless(type(derived) is tzinfo) def test_pickling_subclass(self): - import pickle, cPickle - # Make sure we can pickle/unpickle an instance of a subclass. offset = timedelta(minutes=-300) --- 122,131 ---- orig = tzinfo.__new__(tzinfo) self.failUnless(type(orig) is tzinfo) ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.failUnless(type(derived) is tzinfo) def test_pickling_subclass(self): # Make sure we can pickle/unpickle an instance of a subclass. offset = timedelta(minutes=-300) *************** *** 122,129 **** self.assertEqual(orig.utcoffset(None), offset) self.assertEqual(orig.tzname(None), 'cookie') ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.failUnless(isinstance(derived, tzinfo)) self.failUnless(type(derived) is PicklableFixedOffset) --- 135,141 ---- self.assertEqual(orig.utcoffset(None), offset) self.assertEqual(orig.tzname(None), 'cookie') ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.failUnless(isinstance(derived, tzinfo)) self.failUnless(type(derived) is PicklableFixedOffset) *************** *** 263,267 **** def test_pickling(self): - import pickle, cPickle args = 12, 34, 56 orig = timedelta(*args) --- 275,278 ---- *************** *** 271,278 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 282,288 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 822,837 **** def test_pickling(self): - import pickle, cPickle args = 6, 7, 23 orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, ('\x00\x06\x07\x17',)) derived = self.theclass(1, 1, 1) derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 832,845 ---- def test_pickling(self): args = 6, 7, 23 orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass) derived = self.theclass(1, 1, 1) derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 1181,1185 **** def test_pickling(self): - import pickle, cPickle args = 6, 7, 23, 20, 59, 1, 64**2 orig = self.theclass(*args) --- 1189,1192 ---- *************** *** 1189,1196 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1196,1202 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 1567,1571 **** def test_pickling(self): - import pickle, cPickle args = 20, 59, 16, 64**2 orig = self.theclass(*args) --- 1573,1576 ---- *************** *** 1575,1582 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1580,1586 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 1881,1886 **** def test_pickling(self): - import pickle, cPickle - # Try one without a tzinfo. args = 20, 59, 16, 64**2 --- 1885,1888 ---- *************** *** 1891,1898 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1893,1899 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 1908,1915 **** self.assertEqual(derived.tzname(), 'cookie') ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, --- 1909,1915 ---- self.assertEqual(derived.tzname(), 'cookie') ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, *************** *** 2100,2105 **** def test_pickling(self): - import pickle, cPickle - # Try one without a tzinfo. args = 6, 7, 23, 20, 59, 1, 64**2 --- 2100,2103 ---- *************** *** 2110,2117 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 2108,2114 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 2127,2134 **** self.assertEqual(derived.tzname(), 'cookie') ! for pickler in pickle, cPickle: ! for proto in 0, 1, 2: green = pickler.dumps(orig, proto) ! derived = pickler.loads(green) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, --- 2124,2130 ---- self.assertEqual(derived.tzname(), 'cookie') ! for pickler, unpickler, proto in pickle_choices: green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, From gvanrossum@users.sourceforge.net Thu Jan 30 22:06:28 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 30 Jan 2003 14:06:28 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv16937/Lib/test Modified Files: test_datetime.py Log Message: Change the approach to pickling to use __reduce__ everywhere. Most classes have a __reduce__ that returns (self.__class__, self.__getstate__()). tzinfo.__reduce__() is a bit smarter, calling __getinitargs__ and __getstate__ if they exist, and falling back to __dict__ if it exists and isn't empty. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** test_datetime.py 24 Jan 2003 22:36:30 -0000 1.30 --- test_datetime.py 30 Jan 2003 22:06:23 -0000 1.31 *************** *** 5,8 **** --- 5,10 ---- import sys + import pickle + import cPickle import unittest *************** *** 16,19 **** --- 18,37 ---- + pickle_choices = [ + (pickle, pickle, 0), + (pickle, pickle, 1), + (pickle, pickle, 2), + (cPickle, cPickle, 0), + (cPickle, cPickle, 1), + ## (cPickle, cPickle, 2), + (pickle, cPickle, 0), + (pickle, cPickle, 1), + ## (pickle, cPickle, 2), + (cPickle, pickle, 0), + (cPickle, pickle, 1), + ## (cPickle, pickle, 2), + ] + + # XXX The test suite uncovered a bug in Python 2.2.2: if x and y are # XXX instances of new-style classes (like date and time) that both *************** *** 101,106 **** def test_pickling_base(self): - import pickle, cPickle - # There's no point to pickling tzinfo objects on their own (they # carry no data), but they need to be picklable anyway else --- 119,122 ---- *************** *** 108,120 **** orig = tzinfo.__new__(tzinfo) self.failUnless(type(orig) is tzinfo) ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.failUnless(type(derived) is tzinfo) def test_pickling_subclass(self): - import pickle, cPickle - # Make sure we can pickle/unpickle an instance of a subclass. offset = timedelta(minutes=-300) --- 124,133 ---- orig = tzinfo.__new__(tzinfo) self.failUnless(type(orig) is tzinfo) ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.failUnless(type(derived) is tzinfo) def test_pickling_subclass(self): # Make sure we can pickle/unpickle an instance of a subclass. offset = timedelta(minutes=-300) *************** *** 124,131 **** self.assertEqual(orig.utcoffset(None), offset) self.assertEqual(orig.tzname(None), 'cookie') ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.failUnless(isinstance(derived, tzinfo)) self.failUnless(type(derived) is PicklableFixedOffset) --- 137,143 ---- self.assertEqual(orig.utcoffset(None), offset) self.assertEqual(orig.tzname(None), 'cookie') ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.failUnless(isinstance(derived, tzinfo)) self.failUnless(type(derived) is PicklableFixedOffset) *************** *** 265,269 **** def test_pickling(self): - import pickle, cPickle args = 12, 34, 56 orig = timedelta(*args) --- 277,280 ---- *************** *** 273,280 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 284,290 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 824,839 **** def test_pickling(self): - import pickle, cPickle args = 6, 7, 23 orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, '\x00\x06\x07\x17') derived = self.theclass(1, 1, 1) derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 834,847 ---- def test_pickling(self): args = 6, 7, 23 orig = self.theclass(*args) state = orig.__getstate__() ! self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass) derived = self.theclass(1, 1, 1) derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 1183,1187 **** def test_pickling(self): - import pickle, cPickle args = 6, 7, 23, 20, 59, 1, 64**2 orig = self.theclass(*args) --- 1191,1194 ---- *************** *** 1191,1198 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1198,1204 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 1569,1573 **** def test_pickling(self): - import pickle, cPickle args = 20, 59, 16, 64**2 orig = self.theclass(*args) --- 1575,1578 ---- *************** *** 1577,1584 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1582,1588 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 1883,1888 **** def test_pickling(self): - import pickle, cPickle - # Try one without a tzinfo. args = 20, 59, 16, 64**2 --- 1887,1890 ---- *************** *** 1893,1900 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 1895,1901 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 1910,1917 **** self.assertEqual(derived.tzname(), 'cookie') ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, --- 1911,1917 ---- self.assertEqual(derived.tzname(), 'cookie') ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, *************** *** 2102,2107 **** def test_pickling(self): - import pickle, cPickle - # Try one without a tzinfo. args = 6, 7, 23, 20, 59, 1, 64**2 --- 2102,2105 ---- *************** *** 2112,2119 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.assertEqual(orig, derived) --- 2110,2116 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) *************** *** 2129,2136 **** self.assertEqual(derived.tzname(), 'cookie') ! for pickler in pickle, cPickle: ! for binary in 0, 1: ! green = pickler.dumps(orig, binary) ! derived = pickler.loads(green) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, --- 2126,2132 ---- self.assertEqual(derived.tzname(), 'cookie') ! for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) self.assertEqual(orig, derived) self.failUnless(isinstance(derived.tzinfo, From gvanrossum@users.sourceforge.net Thu Jan 30 22:06:58 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 30 Jan 2003 14:06:58 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.48,1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv16937/Modules Modified Files: datetimemodule.c Log Message: Change the approach to pickling to use __reduce__ everywhere. Most classes have a __reduce__ that returns (self.__class__, self.__getstate__()). tzinfo.__reduce__() is a bit smarter, calling __getinitargs__ and __getstate__ if they exist, and falling back to __dict__ if it exists and isn't empty. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -d -r1.48 -r1.49 *** datetimemodule.c 24 Jan 2003 22:36:34 -0000 1.48 --- datetimemodule.c 30 Jan 2003 22:06:21 -0000 1.49 *************** *** 1351,1360 **** static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */ - /* Callables to support unpickling. */ - static PyObject *date_unpickler_object = NULL; - static PyObject *datetime_unpickler_object = NULL; - static PyObject *tzinfo_unpickler_object = NULL; - static PyObject *time_unpickler_object = NULL; - /* --------------------------------------------------------------------------- * Class implementations. --- 1351,1354 ---- *************** *** 2004,2007 **** --- 1998,2002 ---- static PyMemberDef delta_members[] = { + {"days", T_INT, OFFSET(days), READONLY, PyDoc_STR("Number of days.")}, *************** *** 2016,2027 **** static PyMethodDef delta_methods[] = { - {"__setstate__", (PyCFunction)delta_setstate, METH_O, - PyDoc_STR("__setstate__(state)")}, ! {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, PyDoc_STR("__setstate__(state)")}, {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS, PyDoc_STR("__getstate__() -> state")}, {NULL, NULL}, }; --- 2011,2024 ---- static PyMethodDef delta_methods[] = { ! {"__setstate__", (PyCFunction)delta_setstate, METH_O, PyDoc_STR("__setstate__(state)")}, {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS, PyDoc_STR("__getstate__() -> state")}, + + {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + {NULL, NULL}, }; *************** *** 2149,2152 **** --- 2146,2151 ---- static char *date_kws[] = {"year", "month", "day", NULL}; + static PyObject *date_setstate(PyDateTime_Date *self, PyObject *arg); + static PyObject * date_new(PyTypeObject *type, PyObject *args, PyObject *kw) *************** *** 2157,2160 **** --- 2156,2177 ---- int day; + /* Check for invocation from pickle with __getstate__ state */ + if (PyTuple_GET_SIZE(args) == 1 && + PyString_Check(PyTuple_GET_ITEM(args, 0))) + { + self = new_date(1, 1, 1); + if (self != NULL) { + PyObject *res = date_setstate( + (PyDateTime_Date *)self, args); + if (res == Py_None) + Py_DECREF(res); + else { + Py_DECREF(self); + self = NULL; + } + } + return self; + } + if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws, &year, &month, &day)) { *************** *** 2519,2538 **** date_getstate(PyDateTime_Date *self) { ! return PyString_FromStringAndSize((char *)self->data, ! _PyDateTime_DATE_DATASIZE); } static PyObject * ! date_setstate(PyDateTime_Date *self, PyObject *state) { ! const int len = PyString_Size(state); ! unsigned char *pdata = (unsigned char*)PyString_AsString(state); ! if (! PyString_Check(state) || ! len != _PyDateTime_DATE_DATASIZE) { PyErr_SetString(PyExc_TypeError, "bad argument to date.__setstate__"); return NULL; } memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE); self->hashcode = -1; --- 2536,2567 ---- date_getstate(PyDateTime_Date *self) { ! return Py_BuildValue( ! "(N)", ! PyString_FromStringAndSize((char *)self->data, ! _PyDateTime_DATE_DATASIZE)); } static PyObject * ! date_setstate(PyDateTime_Date *self, PyObject *arg) { ! PyObject *state; ! int len; ! unsigned char *pdata; ! if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1) { ! error: PyErr_SetString(PyExc_TypeError, "bad argument to date.__setstate__"); return NULL; } + state = PyTuple_GET_ITEM(arg, 0); + if (!PyString_Check(state)) + goto error; + + len = PyString_Size(state); + if (len != _PyDateTime_DATE_DATASIZE) + goto error; + + pdata = (unsigned char*)PyString_AsString(state); memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE); self->hashcode = -1; *************** *** 2542,2591 **** } - /* XXX This seems a ridiculously inefficient way to pickle a short string. */ static PyObject * ! date_pickler(PyObject *module, PyDateTime_Date *date) ! { ! PyObject *state; ! PyObject *result = NULL; ! ! if (! PyDate_CheckExact(date)) { ! PyErr_Format(PyExc_TypeError, ! "bad type passed to date pickler: %s", ! date->ob_type->tp_name); ! return NULL; ! } ! state = date_getstate(date); ! if (state) { ! result = Py_BuildValue("O(O)", date_unpickler_object, state); ! Py_DECREF(state); ! } ! return result; ! } ! ! static PyObject * ! date_unpickler(PyObject *module, PyObject *arg) { ! PyDateTime_Date *self; ! ! if (! PyString_CheckExact(arg)) { ! PyErr_Format(PyExc_TypeError, ! "bad type passed to date unpickler: %s", ! arg->ob_type->tp_name); ! return NULL; ! } ! self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType); ! if (self != NULL) { ! PyObject *res = date_setstate(self, arg); ! if (res == NULL) { ! Py_DECREF(self); ! return NULL; ! } ! Py_DECREF(res); ! } ! return (PyObject *)self; } static PyMethodDef date_methods[] = { /* Class methods: */ {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS | METH_CLASS, --- 2571,2584 ---- } static PyObject * ! date_reduce(PyDateTime_Date *self, PyObject *arg) { ! return Py_BuildValue("(ON)", self->ob_type, date_getstate(self)); } static PyMethodDef date_methods[] = { + /* Class methods: */ + {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS | METH_CLASS, *************** *** 2641,2644 **** --- 2634,2640 ---- PyDoc_STR("__getstate__() -> state")}, + {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + {NULL, NULL} }; *************** *** 2835,2855 **** /* * Pickle support. This is solely so that tzinfo subclasses can use ! * pickling -- tzinfo itself is supposed to be uninstantiable. The ! * pickler and unpickler functions are given module-level private ! * names, and registered with copy_reg, by the module init function. */ ! static PyObject* ! tzinfo_pickler(PyDateTime_TZInfo *self) { ! return Py_BuildValue("O()", tzinfo_unpickler_object); ! } ! static PyObject* ! tzinfo_unpickler(PyObject * unused) { ! return PyType_GenericNew(&PyDateTime_TZInfoType, NULL, NULL); ! } static PyMethodDef tzinfo_methods[] = { {"tzname", (PyCFunction)tzinfo_tzname, METH_O, PyDoc_STR("datetime -> string name of time zone.")}, --- 2831,2894 ---- /* * Pickle support. This is solely so that tzinfo subclasses can use ! * pickling -- tzinfo itself is supposed to be uninstantiable. */ ! static PyObject * ! tzinfo_reduce(PyObject *self) ! { ! PyObject *args, *state, *tmp; ! PyObject *getinitargs, *getstate; ! tmp = PyTuple_New(0); ! if (tmp == NULL) ! return NULL; ! ! getinitargs = PyObject_GetAttrString(self, "__getinitargs__"); ! if (getinitargs != NULL) { ! args = PyObject_CallObject(getinitargs, tmp); ! Py_DECREF(getinitargs); ! if (args == NULL) { ! Py_DECREF(tmp); ! return NULL; ! } ! } ! else { ! PyErr_Clear(); ! args = tmp; ! Py_INCREF(args); ! } + getstate = PyObject_GetAttrString(self, "__getstate__"); + if (getstate != NULL) { + state = PyObject_CallObject(getstate, tmp); + Py_DECREF(getstate); + if (state == NULL) { + Py_DECREF(args); + Py_DECREF(tmp); + return NULL; + } + } + else { + PyObject **dictptr; + PyErr_Clear(); + state = Py_None; + dictptr = _PyObject_GetDictPtr(self); + if (dictptr && *dictptr && PyDict_Size(*dictptr)) + state = *dictptr; + Py_INCREF(state); + } + + Py_DECREF(tmp); + + if (state == Py_None) { + Py_DECREF(state); + return Py_BuildValue("(ON)", self->ob_type, args); + } + else + return Py_BuildValue("(ONN)", self->ob_type, args, state); + } static PyMethodDef tzinfo_methods[] = { + {"tzname", (PyCFunction)tzinfo_tzname, METH_O, PyDoc_STR("datetime -> string name of time zone.")}, *************** *** 2865,2868 **** --- 2904,2910 ---- PyDoc_STR("datetime in UTC -> datetime in local time.")}, + {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS, + PyDoc_STR("-> (cls, state)")}, + {NULL, NULL} }; *************** *** 2971,2974 **** --- 3013,3018 ---- "tzinfo", NULL}; + static PyObject *time_setstate(PyDateTime_Time *self, PyObject *state); + static PyObject * time_new(PyTypeObject *type, PyObject *args, PyObject *kw) *************** *** 2981,2984 **** --- 3025,3049 ---- PyObject *tzinfo = Py_None; + /* Check for invocation from pickle with __getstate__ state */ + if (PyTuple_GET_SIZE(args) >= 1 && + PyTuple_GET_SIZE(args) <= 2 && + PyString_Check(PyTuple_GET_ITEM(args, 0))) + { + if (PyTuple_GET_SIZE(args) == 2) + tzinfo = PyTuple_GET_ITEM(args, 1); + self = new_time(0, 0, 0, 0, tzinfo); + if (self != NULL) { + PyObject *res = time_setstate( + (PyDateTime_Time *)self, args); + if (res == Py_None) + Py_DECREF(res); + else { + Py_DECREF(self); + self = NULL; + } + } + return self; + } + if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws, &hour, &minute, &second, &usecond, *************** *** 3338,3397 **** static PyObject * ! time_pickler(PyObject *module, PyDateTime_Time *time) ! { ! PyObject *state; ! PyObject *result = NULL; ! ! if (! PyTime_CheckExact(time)) { ! PyErr_Format(PyExc_TypeError, ! "bad type passed to time pickler: %s", ! time->ob_type->tp_name); ! return NULL; ! } ! state = time_getstate(time); ! if (state) { ! result = Py_BuildValue("O(O)", ! time_unpickler_object, ! state); ! Py_DECREF(state); ! } ! return result; ! } ! ! static PyObject * ! time_unpickler(PyObject *module, PyObject *arg) { ! PyDateTime_Time *self; ! ! /* We don't want to allocate space for tzinfo if it's not needed. ! * Figuring that out in advance is irritating, so for now we ! * realloc later. ! */ ! self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType); ! if (self != NULL) { ! PyObject *res; ! ! self->tzinfo = Py_None; ! Py_INCREF(self->tzinfo); ! self->hastzinfo = (char)1; /* true */ ! res = time_setstate(self, arg); ! if (res == NULL) { ! Py_DECREF(self); ! return NULL; ! } ! Py_DECREF(res); ! if (self->tzinfo == Py_None) { ! /* shrinking; can't fail */ ! Py_DECREF(self->tzinfo); ! self = (PyDateTime_Time *)PyObject_Realloc(self, ! sizeof(_PyDateTime_BaseTime)); ! assert(self != NULL); ! self->hastzinfo = (char)0; ! } ! } ! return (PyObject *)self; } static PyMethodDef time_methods[] = { {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS, PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]" --- 3403,3413 ---- static PyObject * ! time_reduce(PyDateTime_Time *self, PyObject *arg) { ! return Py_BuildValue("(ON)", self->ob_type, time_getstate(self)); } static PyMethodDef time_methods[] = { + {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS, PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]" *************** *** 3418,3421 **** --- 3434,3441 ---- {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS, PyDoc_STR("__getstate__() -> state")}, + + {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + {NULL, NULL} }; *************** *** 3540,3543 **** --- 3560,3565 ---- }; + static PyObject *datetime_setstate(PyDateTime_DateTime *self, PyObject *state); + static PyObject * datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) *************** *** 3553,3556 **** --- 3575,3599 ---- PyObject *tzinfo = Py_None; + /* Check for invocation from pickle with __getstate__ state */ + if (PyTuple_GET_SIZE(args) >= 1 && + PyTuple_GET_SIZE(args) <= 2 && + PyString_Check(PyTuple_GET_ITEM(args, 0))) + { + if (PyTuple_GET_SIZE(args) == 2) + tzinfo = PyTuple_GET_ITEM(args, 1); + self = new_datetime(1, 1, 1, 0, 0, 0, 0, tzinfo); + if (self != NULL) { + PyObject *res = datetime_setstate( + (PyDateTime_DateTime *)self, args); + if (res == Py_None) + Py_DECREF(res); + else { + Py_DECREF(self); + self = NULL; + } + } + return self; + } + if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws, &year, &month, &day, &hour, &minute, *************** *** 4364,4424 **** static PyObject * ! datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime) ! { ! PyObject *state; ! PyObject *result = NULL; ! ! if (! PyDateTime_CheckExact(datetime)) { ! PyErr_Format(PyExc_TypeError, ! "bad type passed to datetime pickler: %s", ! datetime->ob_type->tp_name); ! return NULL; ! } ! state = datetime_getstate(datetime); ! if (state) { ! result = Py_BuildValue("O(O)", ! datetime_unpickler_object, ! state); ! Py_DECREF(state); ! } ! return result; ! } ! ! static PyObject * ! datetime_unpickler(PyObject *module, PyObject *arg) { ! PyDateTime_DateTime *self; ! ! /* We don't want to allocate space for tzinfo if it's not needed. ! * Figuring that out in advance is irritating, so for now we ! * realloc later. ! */ ! self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType); ! if (self != NULL) { ! PyObject *res; ! ! self->tzinfo = Py_None; ! Py_INCREF(self->tzinfo); ! self->hastzinfo = (char)1; /* true */ ! res = datetime_setstate(self, arg); ! if (res == NULL) { ! Py_DECREF(self); ! return NULL; ! } ! Py_DECREF(res); ! if (self->tzinfo == Py_None) { ! /* shrinking; can't fail */ ! Py_DECREF(self->tzinfo); ! self = (PyDateTime_DateTime *)PyObject_Realloc(self, ! sizeof(_PyDateTime_BaseDateTime)); ! assert(self != NULL); ! self->hastzinfo = (char)0; ! } ! } ! return (PyObject *)self; } - static PyMethodDef datetime_methods[] = { /* Class methods: */ --- 4407,4417 ---- static PyObject * ! datetime_reduce(PyDateTime_DateTime *self, PyObject *arg) { ! return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self)); } static PyMethodDef datetime_methods[] = { + /* Class methods: */ *************** *** 4445,4448 **** --- 4438,4442 ---- /* Instance methods: */ + {"date", (PyCFunction)datetime_getdate, METH_NOARGS, PyDoc_STR("Return date object with same year, month and day.")}, *************** *** 4489,4492 **** --- 4483,4490 ---- {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS, PyDoc_STR("__getstate__() -> state")}, + + {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + {NULL, NULL} }; *************** *** 4558,4573 **** static PyMethodDef module_methods[] = { - /* Private functions for pickling support, registered with the - * copy_reg module by the module init function. - */ - {"_date_pickler", (PyCFunction)date_pickler, METH_O, NULL}, - {"_date_unpickler", (PyCFunction)date_unpickler, METH_O, NULL}, - {"_datetime_pickler", (PyCFunction)datetime_pickler, METH_O, NULL}, - {"_datetime_unpickler", (PyCFunction)datetime_unpickler,METH_O, NULL}, - {"_time_pickler", (PyCFunction)time_pickler, METH_O, NULL}, - {"_time_unpickler", (PyCFunction)time_unpickler, METH_O, NULL}, - {"_tzinfo_pickler", (PyCFunction)tzinfo_pickler, METH_O, NULL}, - {"_tzinfo_unpickler", (PyCFunction)tzinfo_unpickler, METH_NOARGS, - NULL}, {NULL, NULL} }; --- 4556,4559 ---- *************** *** 4601,4666 **** return; ! /* Pickling support, via registering functions with copy_reg. */ { ! PyObject *pickler; ! PyObject *copyreg = PyImport_ImportModule("copy_reg"); ! ! if (copyreg == NULL) return; ! pickler = PyObject_GetAttrString(m, "_date_pickler"); ! if (pickler == NULL) return; ! date_unpickler_object = PyObject_GetAttrString(m, ! "_date_unpickler"); ! if (date_unpickler_object == NULL) return; ! x = PyObject_CallMethod(copyreg, "pickle", "OOO", ! &PyDateTime_DateType, ! pickler, ! date_unpickler_object); ! if (x == NULL) return; ! Py_DECREF(x); ! Py_DECREF(pickler); ! pickler = PyObject_GetAttrString(m, "_time_pickler"); ! if (pickler == NULL) return; ! time_unpickler_object = PyObject_GetAttrString(m, ! "_time_unpickler"); ! if (time_unpickler_object == NULL) return; ! x = PyObject_CallMethod(copyreg, "pickle", "OOO", ! &PyDateTime_TimeType, ! pickler, ! time_unpickler_object); ! if (x == NULL) return; ! Py_DECREF(x); ! Py_DECREF(pickler); ! pickler = PyObject_GetAttrString(m, "_tzinfo_pickler"); ! if (pickler == NULL) return; ! tzinfo_unpickler_object = PyObject_GetAttrString(m, ! "_tzinfo_unpickler"); ! if (tzinfo_unpickler_object == NULL) return; ! x = PyObject_CallMethod(copyreg, "pickle", "OOO", ! &PyDateTime_TZInfoType, ! pickler, ! tzinfo_unpickler_object); ! if (x== NULL) return; ! Py_DECREF(x); ! Py_DECREF(pickler); ! pickler = PyObject_GetAttrString(m, "_datetime_pickler"); ! if (pickler == NULL) return; ! datetime_unpickler_object = PyObject_GetAttrString(m, ! "_datetime_unpickler"); ! if (datetime_unpickler_object == NULL) return; ! x = PyObject_CallMethod(copyreg, "pickle", "OOO", ! &PyDateTime_DateTimeType, ! pickler, ! datetime_unpickler_object); ! if (x== NULL) return; ! Py_DECREF(x); ! Py_DECREF(pickler); ! Py_DECREF(copyreg); } /* timedelta values */ d = PyDateTime_DeltaType.tp_dict; --- 4587,4636 ---- return; ! /* Make __getnewargs__ a true alias for __getstate__ */ { ! PyObject *d, *f; ! d = PyDateTime_DateType.tp_dict; ! f = PyDict_GetItemString(d, "__getstate__"); ! if (f != NULL) { ! if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) ! return; ! } ! d = PyDateTime_DateTimeType.tp_dict; ! f = PyDict_GetItemString(d, "__getstate__"); ! if (f != NULL) { ! if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) ! return; ! } ! d = PyDateTime_DeltaType.tp_dict; ! f = PyDict_GetItemString(d, "__getstate__"); ! if (f != NULL) { ! if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) ! return; ! } ! d = PyDateTime_TimeType.tp_dict; ! f = PyDict_GetItemString(d, "__getstate__"); ! if (f != NULL) { ! if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) ! return; ! } ! d = PyDateTime_TZInfoType.tp_dict; ! f = PyDict_GetItemString(d, "__getstate__"); ! if (f != NULL) { ! if (PyDict_SetItemString(d, "__getnewargs__", f) < 0) ! return; ! } } + /* tzinfo values */ + d = PyDateTime_TZInfoType.tp_dict; + + if (PyDict_SetItem(d, safepickle, Py_True) < 0) + return; + /* timedelta values */ d = PyDateTime_DeltaType.tp_dict; *************** *** 4687,4690 **** --- 4657,4663 ---- d = PyDateTime_DateType.tp_dict; + if (PyDict_SetItem(d, safepickle, Py_True) < 0) + return; + x = new_date(1, 1, 1); if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) *************** *** 4705,4708 **** --- 4678,4684 ---- d = PyDateTime_TimeType.tp_dict; + if (PyDict_SetItem(d, safepickle, Py_True) < 0) + return; + x = new_time(0, 0, 0, 0, Py_None); if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) *************** *** 4722,4725 **** --- 4698,4704 ---- /* datetime values */ d = PyDateTime_DateTimeType.tp_dict; + + if (PyDict_SetItem(d, safepickle, Py_True) < 0) + return; x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None); From fdrake@users.sourceforge.net Thu Jan 30 22:23:04 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 30 Jan 2003 14:23:04 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libtraceback.tex,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv24696 Modified Files: libtraceback.tex Log Message: Fix markup error. Index: libtraceback.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtraceback.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** libtraceback.tex 15 Aug 2002 14:59:00 -0000 1.16 --- libtraceback.tex 30 Jan 2003 22:22:59 -0000 1.17 *************** *** 120,124 **** This function returns the current line number set in the traceback object. This function was necessary because in versions of Python ! prior to 2.3 when the \programopt{O} flag was passed to Python the \code{\var{tb}.tb_lineno} was not updated correctly. This function has no use in versions past 2.3. --- 120,124 ---- This function returns the current line number set in the traceback object. This function was necessary because in versions of Python ! prior to 2.3 when the \programopt{-O} flag was passed to Python the \code{\var{tb}.tb_lineno} was not updated correctly. This function has no use in versions past 2.3. From rhettinger@users.sourceforge.net Fri Jan 31 00:19:03 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 30 Jan 2003 16:19:03 -0800 Subject: [Python-checkins] python/nondist/peps pep-0042.txt,1.65,1.66 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv5868 Modified Files: pep-0042.txt Log Message: Remove an entry for an RFE that was already implemented. Index: pep-0042.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0042.txt,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** pep-0042.txt 18 Dec 2002 01:33:24 -0000 1.65 --- pep-0042.txt 31 Jan 2003 00:18:59 -0000 1.66 *************** *** 209,216 **** http://www.python.org/sf/232493 - - Fatter math module docs and docstrings. - - http://www.python.org/sf/426539 - - Jim Fulton suggested the following: --- 209,212 ---- From nascheme@users.sourceforge.net Fri Jan 31 00:36:03 2003 From: nascheme@users.sourceforge.net (nascheme@users.sourceforge.net) Date: Thu, 30 Jan 2003 16:36:03 -0800 Subject: [Python-checkins] python/dist/src/Lib re.py,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv11809/Lib Modified Files: re.py Log Message: Give people who run "pydoc re" a clue. Index: re.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/re.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** re.py 19 Oct 2002 20:19:10 -0000 1.45 --- re.py 31 Jan 2003 00:35:58 -0000 1.46 *************** *** 1,3 **** ! """Minimal "re" compatibility wrapper""" engine = "sre" # Some apps might use this undocumented variable --- 1,3 ---- ! """Minimal "re" compatibility wrapper. See "sre" for documentation.""" engine = "sre" # Some apps might use this undocumented variable From andrewmcnamara@users.sourceforge.net Fri Jan 31 00:43:10 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 30 Jan 2003 16:43:10 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test - New directory Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv14124/test Log Message: Directory /cvsroot/python/python/nondist/sandbox/csv/test added to the repository From tim_one@users.sourceforge.net Fri Jan 31 01:37:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 30 Jan 2003 17:37:38 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.49,1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv30063/Modules Modified Files: datetimemodule.c Log Message: Backward branches are disgusting, at least when a forward branch is just as easy. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -d -r1.49 -r1.50 *** datetimemodule.c 30 Jan 2003 22:06:21 -0000 1.49 --- datetimemodule.c 31 Jan 2003 01:37:35 -0000 1.50 *************** *** 2549,2558 **** unsigned char *pdata; ! if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1) { ! error: ! PyErr_SetString(PyExc_TypeError, ! "bad argument to date.__setstate__"); ! return NULL; ! } state = PyTuple_GET_ITEM(arg, 0); if (!PyString_Check(state)) --- 2549,2554 ---- unsigned char *pdata; ! if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1) ! goto error; state = PyTuple_GET_ITEM(arg, 0); if (!PyString_Check(state)) *************** *** 2569,2572 **** --- 2565,2572 ---- Py_INCREF(Py_None); return Py_None; + error: + PyErr_SetString(PyExc_TypeError, + "bad argument to date.__setstate__"); + return NULL; } From bwarsaw@users.sourceforge.net Fri Jan 31 03:30:12 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Thu, 30 Jan 2003 19:30:12 -0800 Subject: [Python-checkins] python/dist/src/Lib UserDict.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv29574 Modified Files: UserDict.py Log Message: typo in comment Index: UserDict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/UserDict.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** UserDict.py 22 Jan 2003 01:39:06 -0000 1.22 --- UserDict.py 31 Jan 2003 03:30:09 -0000 1.23 *************** *** 78,82 **** # and keys. Without knowledge of the subclass constructor, the mixin # does not define __init__() or copy(). In addition to the four base ! # methods, progessively more efficiency comes with defining # __contains__(), __iter__(), and iteritems(). --- 78,82 ---- # and keys. Without knowledge of the subclass constructor, the mixin # does not define __init__() or copy(). In addition to the four base ! # methods, progressively more efficiency comes with defining # __contains__(), __iter__(), and iteritems(). From tim_one@users.sourceforge.net Fri Jan 31 03:44:00 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 30 Jan 2003 19:44:00 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.128,1.129 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv2828/Lib Modified Files: pickle.py Log Message: Linear-time implementations of {encode,decode}_long. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.128 retrieving revision 1.129 diff -C2 -d -r1.128 -r1.129 *** pickle.py 30 Jan 2003 15:41:46 -0000 1.128 --- pickle.py 31 Jan 2003 03:43:58 -0000 1.129 *************** *** 1286,1293 **** pass ! # Encode/decode longs. def encode_long(x): ! r"""Encode a long to a two's complement little-ending binary string. >>> encode_long(255L) '\xff\x00' --- 1286,1295 ---- pass ! # Encode/decode longs in linear time. ! ! import binascii as _binascii def encode_long(x): ! r"""Encode a long to a two's complement little-endian binary string. >>> encode_long(255L) '\xff\x00' *************** *** 1304,1315 **** >>> """ ! # XXX This is still a quadratic algorithm. ! # Should use hex() to get started. ! digits = [] ! while not -128 <= x < 128: ! digits.append(x & 0xff) ! x >>= 8 ! digits.append(x & 0xff) ! return "".join(map(chr, digits)) def decode_long(data): --- 1306,1349 ---- >>> """ ! ! if x == 0: ! return '\x00' ! if x > 0: ! ashex = hex(x) ! assert ashex.startswith("0x") ! njunkchars = 2 + ashex.endswith('L') ! nibbles = len(ashex) - njunkchars ! if nibbles & 1: ! # need an even # of nibbles for unhexlify ! ashex = "0x0" + ashex[2:] ! elif ashex[2] >= '8': ! # "looks negative", so need a byte of sign bits ! ashex = "0x00" + ashex[2:] ! else: ! # Build the 256's-complement: (1L << nbytes) + x. The trick is ! # to find the number of bytes in linear time (although that should ! # really be a constant-time task). ! ashex = hex(-x) ! assert ashex.startswith("0x") ! njunkchars = 2 + ashex.endswith('L') ! nibbles = len(ashex) - njunkchars ! if nibbles & 1: ! # need an even # of nibbles for unhexlify ! nibbles += 1 ! nbytes = nibbles >> 1 ! x += 1L << (nbytes * 8) ! assert x > 0 ! ashex = hex(x) ! if x >> (nbytes * 8 - 1) == 0: ! # "looks positive", so need a byte of sign bits ! ashex = "0xff" + x[2:] ! ! if ashex.endswith('L'): ! ashex = ashex[2:-1] ! else: ! ashex = ashex[2:] ! assert len(ashex) & 1 == 0 ! binary = _binascii.unhexlify(ashex) ! return binary[::-1] def decode_long(data): *************** *** 1328,1340 **** 127L """ ! # XXX This is quadratic too. ! x = 0L ! i = 0L ! for c in data: ! x |= long(ord(c)) << i ! i += 8L ! if data and ord(c) >= 0x80: ! x -= 1L << i ! return x # Shorthands --- 1362,1371 ---- 127L """ ! ! ashex = _binascii.hexlify(data[::-1]) ! n = long(ashex, 16) ! if data[-1] >= '\x80': ! n -= 1L << (len(data) * 8) ! return n # Shorthands From nnorwitz@users.sourceforge.net Fri Jan 31 04:04:26 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 30 Jan 2003 20:04:26 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.129,1.130 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv12677/Lib Modified Files: pickle.py Log Message: Fix typo Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.129 retrieving revision 1.130 diff -C2 -d -r1.129 -r1.130 *** pickle.py 31 Jan 2003 03:43:58 -0000 1.129 --- pickle.py 31 Jan 2003 04:04:23 -0000 1.130 *************** *** 381,385 **** getnewargs = getattr(obj, "__getnewargs__", None) if getnewargs: ! args = getnewargs() # This bette not reference obj else: args = () --- 381,385 ---- getnewargs = getattr(obj, "__getnewargs__", None) if getnewargs: ! args = getnewargs() # This better not reference obj else: args = () From andrewmcnamara@users.sourceforge.net Fri Jan 31 04:07:43 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 30 Jan 2003 20:07:43 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv13504 Modified Files: csv.py Log Message: Rename dialects from excel2000 to excel. Rename Error to be CSVError. Explicity fetch iterator in reader class, rather than simply calling next() (which only works for self-iterators). Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** csv.py 30 Jan 2003 13:11:21 -0000 1.4 --- csv.py 31 Jan 2003 04:07:40 -0000 1.5 *************** *** 3,31 **** QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC = range(3) ! class excel2000: quotechar = '"' delimiter = ',' escapechar = None skipinitialspace = False ! lineterminator = '\r\n' quoting = QUOTE_MINIMAL ! class excel2000_tab: delimiter = '\t' dialects = { ! 'excel': excel2000, ! 'excel2000': excel2000, ! 'excel-tab': excel2000_tab, ! 'excel2000-tab': excel2000_tab, } ! def set_dialect(name, dialect): ! dialects[name] = dialect ! ! def get_dialect(name): ! return dialects[name] ! ! class Error(Exception): pass --- 3,25 ---- QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC = range(3) ! class excel: quotechar = '"' delimiter = ',' escapechar = None skipinitialspace = False ! # XXX - andrewm - This is causing weird errors from the _csv module - needs ! # investigation: ! # lineterminator = '\r\n' quoting = QUOTE_MINIMAL ! class excel_tab(excel): delimiter = '\t' dialects = { ! 'excel': excel, ! 'excel-tab': excel_tab, } ! class CSVError(Exception): pass *************** *** 35,42 **** dialect_obj = dialects[dialect] except KeyError: ! raise Error('Unknown dialect') parser_options = {} for attr in dir(dialect_obj): ! if attr[0] == '_': continue parser_options[attr] = getattr(dialect_obj, attr) --- 29,36 ---- dialect_obj = dialects[dialect] except KeyError: ! raise CSVError('Unknown dialect') parser_options = {} for attr in dir(dialect_obj): ! if attr.startswith('_'): continue parser_options[attr] = getattr(dialect_obj, attr) *************** *** 45,53 **** self.parser = _csv.parser(**parser_options) except _csv.Error, e: ! raise Error(e) class reader(OCcvs): ! def __init__(self, fileobj, dialect = 'excel2000', **options): ! self.fileobj = fileobj OCcvs.__init__(self, dialect, **options) --- 39,47 ---- self.parser = _csv.parser(**parser_options) except _csv.Error, e: ! raise CSVError(e) class reader(OCcvs): ! def __init__(self, iterobj, dialect = 'excel', **options): ! self.iterobj = iter(iterobj) OCcvs.__init__(self, dialect, **options) *************** *** 57,66 **** def next(self): while 1: ! fields = self.parser.parse(self.fileobj.next()) if fields: return fields class writer(OCcvs): ! def __init__(self, fileobj, dialect='excel2000', **options): self.fileobj = fileobj OCcvs.__init__(self, dialect, **options) --- 51,60 ---- def next(self): while 1: ! fields = self.parser.parse(self.iterobj.next()) if fields: return fields class writer(OCcvs): ! def __init__(self, fileobj, dialect='excel', **options): self.fileobj = fileobj OCcvs.__init__(self, dialect, **options) *************** *** 83,84 **** --- 77,102 ---- except: pass + + def set_dialect(name, dialect): + dialects[name] = dialect + + def get_dialect(name): + return dialects[name] + + def list_dialects(): + return dialects.keys() + + # An alternate way of populating the dialects dictionary... + #def _init_dialects(): + # global dialects + # mod = sys.modules[__name__] + # for name in dir(mod): + # attr = getattr(mod, name) + # try: + # if issubclass(attr, Dialect) and attr is not Dialect: + # dialect = attr() + # dialects[dialect.name] = dialect + # except TypeError: + # pass + # + #_init_dialects() From andrewmcnamara@users.sourceforge.net Fri Jan 31 04:08:20 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 30 Jan 2003 20:08:20 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test __init__.py,NONE,1.1 test_csv.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv14214/test Added Files: __init__.py test_csv.py Log Message: Added a test framework, and some tests for the "excel" dialect (reader only, so far). --- NEW FILE: __init__.py --- # Copyright (C) 2001,2002 Python Software Foundation # email package unit tests --- NEW FILE: test_csv.py --- # Copyright (C) 2001,2002 Python Software Foundation # csv package unit tests import sys import unittest from StringIO import StringIO import csv class TestCsvBase(unittest.TestCase): def readerAssertEqual(self, input, expected_result): reader = csv.reader(StringIO(input), dialect = self.dialect) fields = list(reader) self.assertEqual(fields, expected_result) class TestDialectExcel(TestCsvBase): dialect = 'excel' def test_single(self): self.readerAssertEqual('abc', [['abc']]) def test_simple(self): self.readerAssertEqual('1,2,3,4,5', [['1','2','3','4','5']]) def test_blankline(self): self.readerAssertEqual('', []) def test_empty_fields(self): self.readerAssertEqual(',', [['', '']]) def test_singlequoted(self): self.readerAssertEqual('""', [['']]) def test_singlequoted_left_empty(self): self.readerAssertEqual('"",', [['','']]) def test_singlequoted_right_empty(self): self.readerAssertEqual(',""', [['','']]) def test_single_quoted_quote(self): self.readerAssertEqual('""""', [['"']]) def test_quoted_quotes(self): self.readerAssertEqual('""""""', [['""']]) def test_inline_quote(self): self.readerAssertEqual('a""b', [['a""b']]) def test_inline_quotes(self): self.readerAssertEqual('a"b"c', [['a"b"c']]) def test_quotes_and_more(self): self.readerAssertEqual('"a"b', [['ab']]) def test_lone_quote(self): self.readerAssertEqual('a"b', [['a"b']]) def test_quote_and_quote(self): self.readerAssertEqual('"a" "b"', [['a "b"']]) def test_space_and_quote(self): self.readerAssertEqual(' "a"', [[' "a"']]) def test_quoted(self): self.readerAssertEqual('1,2,3,"I think, therefore I am",5,6', [['1', '2', '3', 'I think, therefore I am', '5', '6']]) def test_quoted_quote(self): self.readerAssertEqual('1,2,3,"""I see,"" said the blind man","as he picked up his hammer and saw"', [['1', '2', '3', '"I see," said the blind man', 'as he picked up his hammer and saw']]) def test_quoted_nl(self): input = '''\ 1,2,3,"""I see,"" said the blind man","as he picked up his hammer and saw" 9,8,7,6''' self.readerAssertEqual(input, [['1', '2', '3', '"I see,"\nsaid the blind man', 'as he picked up his\nhammer and saw'], ['9','8','7','6']]) def test_dubious_quote(self): self.readerAssertEqual('12,12,1",', [['12', '12', '1"', '']]) def _testclasses(): mod = sys.modules[__name__] return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')] def suite(): suite = unittest.TestSuite() for testclass in _testclasses(): suite.addTest(unittest.makeSuite(testclass)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') From neal@metaslash.com Fri Jan 31 04:12:20 2003 From: neal@metaslash.com (Neal Norwitz) Date: Thu, 30 Jan 2003 23:12:20 -0500 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.128,1.129 In-Reply-To: References: Message-ID: <20030131041220.GX24222@epoch.metaslash.com> > ! for c in data: > ! x |= long(ord(c)) << i > ! i += 8L > ! if data and ord(c) >= 0x80: > ! x -= 1L << i > ! return x --- > ! ashex = _binascii.hexlify(data[::-1]) > ! n = long(ashex, 16) > ! if data[-1] >= '\x80': > ! n -= 1L << (len(data) * 8) > ! return n The old version allowed data to be an empty string, the new version does not. Is that a problem? Neal From tim@zope.com Fri Jan 31 04:22:51 2003 From: tim@zope.com (Tim Peters) Date: Thu, 30 Jan 2003 23:22:51 -0500 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.128,1.129 In-Reply-To: <20030131041220.GX24222@epoch.metaslash.com> Message-ID: > The old version allowed data to be an empty string, > the new version does not. Is that a problem? Since encode_long never produces an empty string, no. I meant to ask Guido about his intent, though, since (1) the 0 case was conspicuous by absence in the doctests, and (2) allowing an empty string would allow a shorter encoding of 0L. It will get straightened out before we die . From andrewmcnamara@users.sourceforge.net Fri Jan 31 04:53:51 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 30 Jan 2003 20:53:51 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv889 Modified Files: test_csv.py Log Message: Added some "writer" tests. Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_csv.py 31 Jan 2003 04:08:18 -0000 1.1 --- test_csv.py 31 Jan 2003 04:53:49 -0000 1.2 *************** *** 13,16 **** --- 13,22 ---- self.assertEqual(fields, expected_result) + def writerAssertEqual(self, input, expected_result): + fileobj = StringIO() + writer = csv.writer(fileobj, dialect = self.dialect) + writer.writelines(input) + self.assertEqual(fileobj.getvalue(), expected_result) + class TestDialectExcel(TestCsvBase): dialect = 'excel' *************** *** 63,75 **** def test_quoted(self): self.readerAssertEqual('1,2,3,"I think, therefore I am",5,6', ! [['1', '2', '3', ! 'I think, therefore I am', ! '5', '6']]) def test_quoted_quote(self): self.readerAssertEqual('1,2,3,"""I see,"" said the blind man","as he picked up his hammer and saw"', ! [['1', '2', '3', ! '"I see," said the blind man', ! 'as he picked up his hammer and saw']]) def test_quoted_nl(self): --- 69,81 ---- def test_quoted(self): self.readerAssertEqual('1,2,3,"I think, therefore I am",5,6', ! [['1', '2', '3', ! 'I think, therefore I am', ! '5', '6']]) def test_quoted_quote(self): self.readerAssertEqual('1,2,3,"""I see,"" said the blind man","as he picked up his hammer and saw"', ! [['1', '2', '3', ! '"I see," said the blind man', ! 'as he picked up his hammer and saw']]) def test_quoted_nl(self): *************** *** 80,90 **** 9,8,7,6''' self.readerAssertEqual(input, ! [['1', '2', '3', ! '"I see,"\nsaid the blind man', ! 'as he picked up his\nhammer and saw'], ! ['9','8','7','6']]) def test_dubious_quote(self): self.readerAssertEqual('12,12,1",', [['12', '12', '1"', '']]) def _testclasses(): --- 86,114 ---- 9,8,7,6''' self.readerAssertEqual(input, ! [['1', '2', '3', ! '"I see,"\nsaid the blind man', ! 'as he picked up his\nhammer and saw'], ! ['9','8','7','6']]) def test_dubious_quote(self): self.readerAssertEqual('12,12,1",', [['12', '12', '1"', '']]) + + def test_null(self): + self.writerAssertEqual([], '') + + def test_single(self): + self.writerAssertEqual([['abc']], 'abc\n') + + def test_simple(self): + self.writerAssertEqual([[1, 2, 'abc', 3, 4]], '1,2,abc,3,4\n') + + def test_quotes(self): + self.writerAssertEqual([[1, 2, 'a"bc"', 3, 4]], '1,2,"a""bc""",3,4\n') + + def test_quote_fieldsep(self): + self.writerAssertEqual([['abc,def']], '"abc,def"\n') + + def test_newlines(self): + self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\n') def _testclasses(): From rhettinger@users.sourceforge.net Fri Jan 31 05:17:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 30 Jan 2003 21:17:35 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstringio.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv8180 Modified Files: libstringio.tex Log Message: SF bug #671447: StringIO doc doesn't say it's sometimes read-only. Index: libstringio.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstringio.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** libstringio.tex 6 Jul 2001 20:30:11 -0000 1.6 --- libstringio.tex 31 Jan 2003 05:17:33 -0000 1.7 *************** *** 60,63 **** --- 60,68 ---- strings that cannot be encoded as plain \ASCII{} strings. + Another difference from the \refmodule{StringIO} module is that calling + \function{StringIO()} with a string parameter creates a read-only object. + Unlike an object created without a string parameter, it does not have + write methods. + The following data objects are provided as well: From rhettinger@users.sourceforge.net Fri Jan 31 05:44:27 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 30 Jan 2003 21:44:27 -0800 Subject: [Python-checkins] python/dist/src/Doc/api newtypes.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv21327 Modified Files: newtypes.tex Log Message: Fix typo Index: newtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/newtypes.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** newtypes.tex 5 Nov 2002 22:19:45 -0000 1.18 --- newtypes.tex 31 Jan 2003 05:44:25 -0000 1.19 *************** *** 442,446 **** \begin{cmemberdesc}{PyTypeObject}{int}{tp_basicsize} \cmemberline{PyTypeObject}{int}{tp_itemsize} ! These fields allow calculating the size in byte of instances of the type. --- 442,446 ---- \begin{cmemberdesc}{PyTypeObject}{int}{tp_basicsize} \cmemberline{PyTypeObject}{int}{tp_itemsize} ! These fields allow calculating the size in bytes of instances of the type. From andrewmcnamara@users.sourceforge.net Fri Jan 31 06:25:10 2003 From: andrewmcnamara@users.sourceforge.net (andrewmcnamara@users.sourceforge.net) Date: Thu, 30 Jan 2003 22:25:10 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv27946 Modified Files: csv.py Log Message: Give the dialect's a common Dialect base class, made the reader factor accept an instance as dialect (as well as strings). ---------------------------------------------------------------------- Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** csv.py 31 Jan 2003 04:07:40 -0000 1.5 --- csv.py 31 Jan 2003 06:25:08 -0000 1.6 *************** *** 3,7 **** QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC = range(3) ! class excel: quotechar = '"' delimiter = ',' --- 3,7 ---- QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC = range(3) ! class Dialect: quotechar = '"' delimiter = ',' *************** *** 13,22 **** quoting = QUOTE_MINIMAL class excel_tab(excel): delimiter = '\t' dialects = { ! 'excel': excel, ! 'excel-tab': excel_tab, } --- 13,25 ---- quoting = QUOTE_MINIMAL + class excel(Dialect): + pass + class excel_tab(excel): delimiter = '\t' dialects = { ! 'excel': excel(), ! 'excel-tab': excel_tab(), } *************** *** 26,33 **** class OCcvs: def __init__(self, dialect, **options): ! try: ! dialect_obj = dialects[dialect] ! except KeyError: ! raise CSVError('Unknown dialect') parser_options = {} for attr in dir(dialect_obj): --- 29,39 ---- class OCcvs: def __init__(self, dialect, **options): ! if isinstance(dialect, Dialect): ! dialect_obj = dialect ! else: ! try: ! dialect_obj = dialects[dialect] ! except KeyError: ! raise CSVError('Unknown dialect') parser_options = {} for attr in dir(dialect_obj): From rhettinger@users.sourceforge.net Fri Jan 31 06:30:43 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 30 Jan 2003 22:30:43 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.14,1.15 todo.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv29743 Modified Files: itertools.c todo.txt Log Message: Fix refcounting in imap(). Use consistent wording in docstrings. Update todo list. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** itertools.c 28 Jan 2003 02:16:13 -0000 1.14 --- itertools.c 31 Jan 2003 06:30:40 -0000 1.15 *************** *** 602,606 **** imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! PyObject *it, *iters, *argtuple; imapobject *lz; int numargs, i; --- 602,606 ---- imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ! PyObject *it, *iters, *argtuple, *func; imapobject *lz; int numargs, i; *************** *** 643,647 **** lz->iters = iters; lz->argtuple = argtuple; ! lz->func = PyTuple_GET_ITEM(args, 0); return (PyObject *)lz; --- 643,649 ---- lz->iters = iters; lz->argtuple = argtuple; ! func = PyTuple_GET_ITEM(args, 0); ! Py_INCREF(func); ! lz->func = func; return (PyObject *)lz; *************** *** 654,657 **** --- 656,660 ---- Py_XDECREF(lz->argtuple); Py_XDECREF(lz->iters); + Py_XDECREF(lz->func); lz->ob_type->tp_free(lz); } *************** *** 1377,1384 **** seq[start:stop:step]\n\ imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\ ! starmap(fun, s) --> fun(*s[0]), fun(*s[1]), ...\n\ times(n) --> None, None, ... for n times.\n\ ! takewhile(pred, seq) --> s[0], s[1], until pred fails\n\ ! dropwhile(pred, seq) --> s[n], s[n+1], starting when pred fails\n\ "); --- 1380,1387 ---- seq[start:stop:step]\n\ imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\ ! starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ times(n) --> None, None, ... for n times.\n\ ! takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ ! dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ "); Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** todo.txt 28 Jan 2003 01:05:29 -0000 1.12 --- todo.txt 31 Jan 2003 06:30:40 -0000 1.13 *************** *** 1,4 **** Comments from Skip and Jack: - provide in-line motivating examples ? add default arg to times() --- 1,3 ---- *************** *** 8,16 **** exists() and any() ?? these don't return iterators - Verify: - proper GC - refcounts subclassability Things dropped because they bug me: --- 7,15 ---- exists() and any() ?? these don't return iterators Verify: subclassability + + Fixup: + tp_traverse looks incomplete Things dropped because they bug me: From rhettinger@users.sourceforge.net Fri Jan 31 07:09:26 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 30 Jan 2003 23:09:26 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.15,1.16 todo.txt,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv22307 Modified Files: itertools.c todo.txt Log Message: Result of another code review Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** itertools.c 31 Jan 2003 06:30:40 -0000 1.15 --- itertools.c 31 Jan 2003 07:09:23 -0000 1.16 *************** *** 74,78 **** good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { - printf("R"); Py_DECREF(item); return NULL; --- 74,77 ---- *************** *** 392,396 **** if (item == NULL) return NULL; ! lz->cnt += 1; lz->next += lz->step; return item; --- 391,395 ---- if (item == NULL) return NULL; ! lz->cnt++; lz->next += lz->step; return item; *************** *** 930,935 **** if (lz->func == Py_None) { ok = PyObject_IsTrue(item); ! } ! else { PyObject *good; good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); --- 929,933 ---- if (lz->func == Py_None) { ok = PyObject_IsTrue(item); ! } else { PyObject *good; good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); *************** *** 1188,1196 **** it = PyTuple_GET_ITEM(lz->ittuple, i); item = PyIter_Next(it); ! if (item == NULL) return NULL; PyTuple_SET_ITEM(result, i, item); } - Py_INCREF(result); return result; } --- 1186,1195 ---- it = PyTuple_GET_ITEM(lz->ittuple, i); item = PyIter_Next(it); ! if (item == NULL) { ! Py_DECREF(result); return NULL; + } PyTuple_SET_ITEM(result, i, item); } return result; } *************** *** 1371,1375 **** Infinite iterators:\n\ count([n]) --> n, n+1, n+2, ...\n\ ! repeat(elem) --> elem, elem, elem, elem\n\ \n\ Iterators terminating on the shortest input sequence:\n\ --- 1370,1374 ---- Infinite iterators:\n\ count([n]) --> n, n+1, n+2, ...\n\ ! repeat(elem) --> elem, elem, elem, ...\n\ \n\ Iterators terminating on the shortest input sequence:\n\ Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** todo.txt 31 Jan 2003 06:30:40 -0000 1.13 --- todo.txt 31 Jan 2003 07:09:24 -0000 1.14 *************** *** 13,16 **** --- 13,20 ---- tp_traverse looks incomplete + + ? Should times() and count() be subclassable + With no accessible methods or members, I would think not. + Things dropped because they bug me: cycle(seqn) requires auxilliary storage (which is surprising From rhettinger@users.sourceforge.net Fri Jan 31 07:20:52 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 30 Jan 2003 23:20:52 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.16,1.17 todo.txt,1.14,1.15 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv25720 Modified Files: itertools.c todo.txt Log Message: Make tp_traverse complete Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** itertools.c 31 Jan 2003 07:09:23 -0000 1.16 --- itertools.c 31 Jan 2003 07:20:49 -0000 1.17 *************** *** 54,59 **** dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) { ! if (lz->it) ! return visit(lz->it, arg); return 0; } --- 54,69 ---- dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) { ! int err; ! ! if (lz->it) { ! err = visit(lz->it, arg); ! if (err) ! return err; ! } ! if (lz->func) { ! err = visit(lz->func, arg); ! if (err) ! return err; ! } return 0; } *************** *** 198,203 **** takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) { ! if (lz->it) ! return visit(lz->it, arg); return 0; } --- 208,223 ---- takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) { ! int err; ! ! if (lz->it) { ! err = visit(lz->it, arg); ! if (err) ! return err; ! } ! if (lz->func) { ! err = visit(lz->func, arg); ! if (err) ! return err; ! } return 0; } *************** *** 509,514 **** starmap_traverse(starmapobject *lz, visitproc visit, void *arg) { ! if (lz->it) ! return visit(lz->it, arg); return 0; } --- 529,544 ---- starmap_traverse(starmapobject *lz, visitproc visit, void *arg) { ! int err; ! ! if (lz->it) { ! err = visit(lz->it, arg); ! if (err) ! return err; ! } ! if (lz->func) { ! err = visit(lz->func, arg); ! if (err) ! return err; ! } return 0; } *************** *** 662,667 **** imap_traverse(imapobject *lz, visitproc visit, void *arg) { ! if (lz->argtuple) ! return visit(lz->argtuple, arg); return 0; } --- 692,712 ---- imap_traverse(imapobject *lz, visitproc visit, void *arg) { ! int err; ! ! if (lz->iters) { ! err = visit(lz->iters, arg); ! if (err) ! return err; ! } ! if (lz->argtuple) { ! err = visit(lz->argtuple, arg); ! if (err) ! return err; ! } ! if (lz->func) { ! err = visit(lz->func, arg); ! if (err) ! return err; ! } return 0; } *************** *** 911,916 **** ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg) { ! if (lz->it) ! return visit(lz->it, arg); return 0; } --- 956,971 ---- ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg) { ! int err; ! ! if (lz->it) { ! err = visit(lz->it, arg); ! if (err) ! return err; ! } ! if (lz->func) { ! err = visit(lz->func, arg); ! if (err) ! return err; ! } return 0; } Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** todo.txt 31 Jan 2003 07:09:24 -0000 1.14 --- todo.txt 31 Jan 2003 07:20:49 -0000 1.15 *************** *** 10,17 **** subclassability - Fixup: - tp_traverse looks incomplete - - ? Should times() and count() be subclassable With no accessible methods or members, I would think not. --- 10,13 ---- From rhettinger@users.sourceforge.net Fri Jan 31 08:53:17 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 00:53:17 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.17,1.18 test_itertools.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv23128 Modified Files: itertools.c test_itertools.py Log Message: Fix refcount leak in imap(). Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** itertools.c 31 Jan 2003 07:20:49 -0000 1.17 --- itertools.c 31 Jan 2003 08:53:14 -0000 1.18 *************** *** 661,664 **** --- 661,666 ---- } PyTuple_SET_ITEM(iters, i-1, it); + Py_INCREF(Py_None); + PyTuple_SET_ITEM(argtuple, i-1, Py_None); } *************** *** 724,738 **** if (argtuple == NULL) return NULL; - } ! for (i=0 ; iiters, i)); ! if (val == NULL) ! return NULL; ! PyTuple_SET_ITEM(argtuple, i, val); ! } ! if (lz->func == Py_None) return argtuple; ! return PyObject_Call(lz->func, argtuple, NULL); } --- 726,749 ---- if (argtuple == NULL) return NULL; ! for (i=0 ; iiters, i)); ! if (val == NULL) { ! Py_DECREF(argtuple); ! return NULL; ! } ! PyTuple_SET_ITEM(argtuple, i, val); ! } return argtuple; ! } else { ! for (i=0 ; iiters, i)); ! if (val == NULL) ! return NULL; ! Py_DECREF(PyTuple_GET_ITEM(argtuple, i)); ! PyTuple_SET_ITEM(argtuple, i, val); ! } ! return PyObject_Call(lz->func, argtuple, NULL); ! } } Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_itertools.py 29 Jan 2003 19:08:08 -0000 1.11 --- test_itertools.py 31 Jan 2003 08:53:15 -0000 1.12 *************** *** 145,148 **** --- 145,157 ---- test_support.run_doctest(test_itertools, verbose) + # verify reference counting + import sys + if verbose and hasattr(sys, "gettotalrefcount"): + counts = [] + for i in xrange(5): + test_support.run_suite(suite) + counts.append(sys.gettotalrefcount()) + print counts + if __name__ == "__main__": test_main(verbose=True) From rhettinger@users.sourceforge.net Fri Jan 31 09:14:41 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 01:14:41 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.18,1.19 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv32569 Modified Files: itertools.c Log Message: Time to put my name on it. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** itertools.c 31 Jan 2003 08:53:14 -0000 1.18 --- itertools.c 31 Jan 2003 09:14:38 -0000 1.19 *************** *** 2,5 **** --- 2,9 ---- #include "Python.h" + /* Itertools module written and maintained + by Raymond D. Hettinger + */ + /* dropwhile object ************************************************************/ From mwh@python.net Fri Jan 31 12:53:22 2003 From: mwh@python.net (Michael Hudson) Date: Fri, 31 Jan 2003 12:53:22 +0000 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.59,2.60 In-Reply-To: <200301301723.h0UHNtY04045@odiug.zope.com> (Guido van Rossum's message of "Thu, 30 Jan 2003 12:23:55 -0500") References: <200301301723.h0UHNtY04045@odiug.zope.com> Message-ID: <2mlm11lbul.fsf@starship.python.net> Guido van Rossum writes: >> METH_NOARGS functions are still called with two arguments, one NULL, >> so put that back into the function definitions (I didn't know this >> until recently). > > Hm, isn't this a bug??? What, that most METH_NOARGS functions are defined mod_foo(PyObject* self) or that the call in ceval.c:3211 is x = (*meth)(self, NULL); ? Tim said in a comment on patch #660559: Note that a METH_NOARGS function is still called, at the C level, with two arguments. The second argument is always NULL, and sooner or later some platform C is going to blow up when that's passed to a function declared to take only one argument ("the usual" cast to PyCFunction shuts up the compile-time warnings). It's not your job to fix that everywhere, but new uses of METH_NOARGS shouldn't add to this problem. Declaring a second PyObject * argument with a name like "unused" or "dummy" would be fine. As I was mucking about with readline.c anyway, I thought I'd put in the unused argument and take out the casts. Cheers, M. -- There's a difference between random people with stripy jumpers, and a respected scientist with a reputation. -- Steve Kitson, ucam.chat From jhylton@users.sourceforge.net Fri Jan 31 14:07:35 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 31 Jan 2003 06:07:35 -0800 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.42.10.9,1.42.10.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv21881 Modified Files: Tag: release22-maint httplib.py Log Message: Remove references to pages that don't exist anymore. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.42.10.9 retrieving revision 1.42.10.10 diff -C2 -d -r1.42.10.9 -r1.42.10.10 *** httplib.py 7 Oct 2002 01:18:17 -0000 1.42.10.9 --- httplib.py 31 Jan 2003 14:07:31 -0000 1.42.10.10 *************** *** 1215,1220 **** for host, selector in (('sourceforge.net', '/projects/python'), - ('dbserv2.theopalgroup.com', '/mediumfile'), - ('dbserv2.theopalgroup.com', '/smallfile'), ): print "https://%s%s" % (host, selector) --- 1215,1218 ---- *************** *** 1232,1266 **** for header in headers.headers: print header.strip() print - - # Test a buggy server -- returns garbled status line. - # http://www.yahoo.com/promotions/mom_com97/supermom.html - c = HTTPConnection("promotions.yahoo.com") - c.set_debuglevel(1) - c.connect() - c.request("GET", "/promotions/mom_com97/supermom.html") - r = c.getresponse() - print r.status, r.version - lines = r.read().split("\n") - print "\n".join(lines[:5]) - - c = HTTPConnection("promotions.yahoo.com", strict=1) - c.set_debuglevel(1) - c.connect() - c.request("GET", "/promotions/mom_com97/supermom.html") - try: - r = c.getresponse() - except BadStatusLine, err: - print "strict mode failed as expected" - print err - else: - print "XXX strict mode should have failed" - - for strict in 0, 1: - h = HTTP(strict=strict) - h.connect("promotions.yahoo.com") - h.putrequest('GET', "/promotions/mom_com97/supermom.html") - h.endheaders() - status, reason, headers = h.getreply() - assert (strict and status == -1) or status == 200, (strict, status) if __name__ == '__main__': --- 1230,1233 ---- From guido@python.org Fri Jan 31 14:56:01 2003 From: guido@python.org (Guido van Rossum) Date: Fri, 31 Jan 2003 09:56:01 -0500 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.59,2.60 In-Reply-To: Your message of "Fri, 31 Jan 2003 12:53:22 GMT." <2mlm11lbul.fsf@starship.python.net> References: <200301301723.h0UHNtY04045@odiug.zope.com> <2mlm11lbul.fsf@starship.python.net> Message-ID: <200301311456.h0VEu1x07134@odiug.zope.com> > >> METH_NOARGS functions are still called with two arguments, one NULL, > >> so put that back into the function definitions (I didn't know this > >> until recently). > > > > Hm, isn't this a bug??? > > What, that most METH_NOARGS functions are defined > > mod_foo(PyObject* self) > > or that the call in ceval.c:3211 is > > x = (*meth)(self, NULL); I was thinking of the latter, but after reading below I understand the point. > ? Tim said in a comment on patch #660559: > > Note that a METH_NOARGS function is still called, at the C > level, with two arguments. The second argument is always > NULL, and sooner or later some platform C is going to blow > up when that's passed to a function declared to take only > one argument ("the usual" cast to PyCFunction shuts up the > compile-time warnings). > > It's not your job to fix that everywhere, but new uses of > METH_NOARGS shouldn't add to this problem. Declaring a > second PyObject * argument with a name like "unused" > or "dummy" would be fine. > > As I was mucking about with readline.c anyway, I thought I'd put in > the unused argument and take out the casts. +1 --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one@users.sourceforge.net Fri Jan 31 15:52:37 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 07:52:37 -0800 Subject: [Python-checkins] python/dist/src/Include longobject.h,2.27,2.28 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv32241/Include Modified Files: longobject.h Log Message: _PyLong_NumBits(): The definition of this was too specific to the quirky needs of pickling longs. Backed off to a definition that's much easier to understand. The pickler will have to work a little harder, but other uses are more likely to be correct <0.5 wink>. _PyLong_Sign(): New teensy function to characterize a long, as to <0, ==0, or >0. Index: longobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v retrieving revision 2.27 retrieving revision 2.28 diff -C2 -d -r2.27 -r2.28 *** longobject.h 28 Jan 2003 20:37:41 -0000 2.27 --- longobject.h 31 Jan 2003 15:52:03 -0000 2.28 *************** *** 45,53 **** #endif ! /* _PyLong_NumBits. Return the number of bits needed to represent a long ! in contiguous 2's-complement form, including 1 for the sign bit. For ! example, this returns 1 for 0, and 2 for 1 and -1. Note that the ! ceiling of this divided by 8 is the number of bytes needed by ! _PyLong_AsByteArray to store the long in 256's-complement form. v must not be NULL, and must be a normalized long. (size_t)-1 is returned and OverflowError set if the true result doesn't --- 45,59 ---- #endif ! /* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. ! v must not be NULL, and must be a normalized long. ! There are no error cases. ! */ ! 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. v must not be NULL, and must be a normalized long. (size_t)-1 is returned and OverflowError set if the true result doesn't From tim_one@users.sourceforge.net Fri Jan 31 15:52:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 07:52:38 -0800 Subject: [Python-checkins] python/dist/src/Modules _testcapimodule.c,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv32241/Modules Modified Files: _testcapimodule.c Log Message: _PyLong_NumBits(): The definition of this was too specific to the quirky needs of pickling longs. Backed off to a definition that's much easier to understand. The pickler will have to work a little harder, but other uses are more likely to be correct <0.5 wink>. _PyLong_Sign(): New teensy function to characterize a long, as to <0, ==0, or >0. Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** _testcapimodule.c 28 Jan 2003 20:37:43 -0000 1.18 --- _testcapimodule.c 31 Jan 2003 15:52:04 -0000 1.19 *************** *** 335,369 **** #endif ! /* Simple test of _PyLong_NumBits. */ static PyObject * test_long_numbits(PyObject *self) { ! struct pair { long input; ! size_t output; ! } testcases[] = {{0, 1}, ! {1L, 2}, ! {-1L, 2}, ! {2L, 3}, ! {-2L, 3}, ! {3L, 3}, ! {-3L, 3}, ! {4L, 4}, ! {-4L, 4}, ! {0x7fffL, 16}, /* one Python long digit */ ! {-0x7fffL, 16}, ! {0xfffffffL, 29}, ! {-0xfffffffL, 29}}; int i; ! for (i = 0; i < sizeof(testcases) / sizeof(struct pair); ++i) { ! long input = testcases[i].input; ! PyObject *plong = PyLong_FromLong(input); size_t nbits = _PyLong_NumBits(plong); Py_DECREF(plong); ! if (nbits != testcases[i].output) return raiseTestError("test_long_numbits", ! "wrong result"); } Py_INCREF(Py_None); --- 335,375 ---- #endif ! /* Simple test of _PyLong_NumBits and _PyLong_Sign. */ static PyObject * test_long_numbits(PyObject *self) { ! struct triple { long input; ! size_t nbits; ! int sign; ! } testcases[] = {{0, 0, 0}, ! {1L, 1, 1}, ! {-1L, 1, -1}, ! {2L, 2, 1}, ! {-2L, 2, -1}, ! {3L, 2, 1}, ! {-3L, 2, -1}, ! {4L, 3, 1}, ! {-4L, 3, -1}, ! {0x7fffL, 15, 1}, /* one Python long digit */ ! {-0x7fffL, 15, -1}, ! {0xffffL, 16, 1}, ! {-0xffffL, 16, -1}, ! {0xfffffffL, 28, 1}, ! {-0xfffffffL, 28, -1}}; int i; ! for (i = 0; i < sizeof(testcases) / sizeof(struct triple); ++i) { ! PyObject *plong = PyLong_FromLong(testcases[i].input); size_t nbits = _PyLong_NumBits(plong); + int sign = _PyLong_Sign(plong); Py_DECREF(plong); ! if (nbits != testcases[i].nbits) return raiseTestError("test_long_numbits", ! "wrong result for _PyLong_NumBits"); ! if (sign != testcases[i].sign) ! return raiseTestError("test_long_numbits", ! "wrong result for _PyLong_Sign"); } Py_INCREF(Py_None); From tim_one@users.sourceforge.net Fri Jan 31 15:52:38 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 07:52:38 -0800 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.148,1.149 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv32241/Objects Modified Files: longobject.c Log Message: _PyLong_NumBits(): The definition of this was too specific to the quirky needs of pickling longs. Backed off to a definition that's much easier to understand. The pickler will have to work a little harder, but other uses are more likely to be correct <0.5 wink>. _PyLong_Sign(): New teensy function to characterize a long, as to <0, ==0, or >0. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.148 retrieving revision 1.149 diff -C2 -d -r1.148 -r1.149 *** longobject.c 29 Jan 2003 17:58:45 -0000 1.148 --- longobject.c 31 Jan 2003 15:52:05 -0000 1.149 *************** *** 261,270 **** } size_t _PyLong_NumBits(PyObject *vv) { PyLongObject *v = (PyLongObject *)vv; ! size_t result = 1; /* for the sign bit */ ! size_t ndigits = ABS(v->ob_size); assert(v != NULL); --- 261,283 ---- } + int + _PyLong_Sign(PyObject *vv) + { + PyLongObject *v = (PyLongObject *)vv; + const int ndigits = v->ob_size; + + assert(v != NULL); + assert(PyLong_Check(v)); + assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + + return ndigits == 0 ? 0 : (ndigits < 0 ? -1 : 1); + } + size_t _PyLong_NumBits(PyObject *vv) { PyLongObject *v = (PyLongObject *)vv; ! size_t result = 0; ! int ndigits = ABS(v->ob_size); assert(v != NULL); *************** *** 272,283 **** assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); if (ndigits > 0) { - size_t product; digit msd = v->ob_digit[ndigits - 1]; ! product = (ndigits - 1) * SHIFT; ! if (product / SHIFT != ndigits - 1) ! goto Overflow; ! result += product; ! if (result < product) goto Overflow; do { --- 285,292 ---- assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); if (ndigits > 0) { digit msd = v->ob_digit[ndigits - 1]; ! result = (ndigits - 1) * SHIFT; ! if (result / SHIFT != ndigits - 1) goto Overflow; do { From gvanrossum@users.sourceforge.net Fri Jan 31 16:04:18 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 08:04:18 -0800 Subject: [Python-checkins] python/dist/src/Lib StringIO.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv5281 Modified Files: StringIO.py Log Message: Make StringIO its own iterator, similar to real files. (This should also be done to cStringIO.) Index: StringIO.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/StringIO.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** StringIO.py 17 Sep 2002 18:10:34 -0000 1.28 --- StringIO.py 31 Jan 2003 16:04:15 -0000 1.29 *************** *** 60,64 **** def __iter__(self): ! return iter(self.readline, '') def close(self): --- 60,72 ---- def __iter__(self): ! return self ! ! def next(self): ! if self.closed: ! raise StopIteration ! r = self.readline() ! if not r: ! raise StopIteration ! return r def close(self): From python@rcn.com Fri Jan 31 16:19:15 2003 From: python@rcn.com (Raymond Hettinger) Date: Fri, 31 Jan 2003 11:19:15 -0500 Subject: [Python-checkins] python/dist/src/Lib StringIO.py,1.28,1.29 References: Message-ID: <003701c2c944$7fe26de0$ed0fa044@oemcomputer> > Make StringIO its own iterator, similar to real files. > > (This should also be done to cStringIO.) I'll take care of that. Raymond Hettinger From doerwalter@users.sourceforge.net Fri Jan 31 16:26:53 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 31 Jan 2003 08:26:53 -0800 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv15042/Modules Modified Files: _iconv_codec.c Log Message: Initialize swappedinput to silence the compiler warning about uninitialized variables. Index: _iconv_codec.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** _iconv_codec.c 30 Jan 2003 19:55:28 -0000 1.5 --- _iconv_codec.c 31 Jan 2003 16:26:50 -0000 1.6 *************** *** 93,97 **** PyObject *outputobj = NULL, *errorcb = NULL, *exceptionobj = NULL; ! Py_UNICODE *swappedinput; int swapi; --- 93,97 ---- PyObject *outputobj = NULL, *errorcb = NULL, *exceptionobj = NULL; ! Py_UNICODE *swappedinput = NULL; int swapi; From tim_one@users.sourceforge.net Fri Jan 31 16:43:42 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 08:43:42 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.130,1.131 pickletools.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv21674/Lib Modified Files: pickle.py pickletools.py Log Message: It's Official: for LONG1/LONG4, a "byte count" of 0 is taken as a shortcut meaning 0L. This allows LONG1 to encode 0L in two bytes total. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.130 retrieving revision 1.131 diff -C2 -d -r1.130 -r1.131 *** pickle.py 31 Jan 2003 04:04:23 -0000 1.130 --- pickle.py 31 Jan 2003 16:43:39 -0000 1.131 *************** *** 1292,1295 **** --- 1292,1300 ---- def encode_long(x): r"""Encode a long to a two's complement little-endian binary string. + Note that 0L is a special case, returning an empty string, to save a + byte in the LONG1 pickling context. + + >>> encode_long(0L) + '' >>> encode_long(255L) '\xff\x00' *************** *** 1308,1312 **** if x == 0: ! return '\x00' if x > 0: ashex = hex(x) --- 1313,1317 ---- if x == 0: ! return '' if x > 0: ashex = hex(x) *************** *** 1317,1321 **** # need an even # of nibbles for unhexlify ashex = "0x0" + ashex[2:] ! elif ashex[2] >= '8': # "looks negative", so need a byte of sign bits ashex = "0x00" + ashex[2:] --- 1322,1326 ---- # need an even # of nibbles for unhexlify ashex = "0x0" + ashex[2:] ! elif int(ashex[2], 16) >= 8: # "looks negative", so need a byte of sign bits ashex = "0x00" + ashex[2:] *************** *** 1331,1339 **** # need an even # of nibbles for unhexlify nibbles += 1 ! nbytes = nibbles >> 1 ! x += 1L << (nbytes * 8) assert x > 0 ashex = hex(x) ! if x >> (nbytes * 8 - 1) == 0: # "looks positive", so need a byte of sign bits ashex = "0xff" + x[2:] --- 1336,1344 ---- # need an even # of nibbles for unhexlify nibbles += 1 ! nbits = nibbles * 4 ! x += 1L << nbits assert x > 0 ashex = hex(x) ! if x >> (nbits - 1) == 0: # "looks positive", so need a byte of sign bits ashex = "0xff" + x[2:] *************** *** 1349,1352 **** --- 1354,1360 ---- def decode_long(data): r"""Decode a long from a two's complement little-endian binary string. + + >>> decode_long('') + 0L >>> decode_long("\xff\x00") 255L *************** *** 1363,1370 **** """ ashex = _binascii.hexlify(data[::-1]) n = long(ashex, 16) if data[-1] >= '\x80': ! n -= 1L << (len(data) * 8) return n --- 1371,1381 ---- """ + nbytes = len(data) + if nbytes == 0: + return 0L ashex = _binascii.hexlify(data[::-1]) n = long(ashex, 16) if data[-1] >= '\x80': ! n -= 1L << (nbytes * 8) return n Index: pickletools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickletools.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** pickletools.py 30 Jan 2003 16:35:08 -0000 1.24 --- pickletools.py 31 Jan 2003 16:43:39 -0000 1.25 *************** *** 621,624 **** --- 621,626 ---- r""" >>> import StringIO + >>> read_long1(StringIO.StringIO("\x00")) + 0L >>> read_long1(StringIO.StringIO("\x02\xff\x00")) 255L *************** *** 629,633 **** >>> read_long1(StringIO.StringIO("\x02\x00\x80")) -32768L - >>> """ --- 631,634 ---- *************** *** 646,649 **** --- 647,651 ---- This first reads one byte as an unsigned size, then reads that many bytes and interprets them as a little-endian 2's-complement long. + If the size is 0, that's taken as a shortcut for the long 0L. """) *************** *** 659,663 **** >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\x80")) -32768L ! >>> """ --- 661,666 ---- >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\x80")) -32768L ! >>> read_long1(StringIO.StringIO("\x00\x00\x00\x00")) ! 0L """ *************** *** 678,682 **** This first reads four bytes as a signed size (but requires the size to be >= 0), then reads that many bytes and interprets them ! as a little-endian 2's-complement long. """) --- 681,687 ---- This first reads four bytes as a signed size (but requires the size to be >= 0), then reads that many bytes and interprets them ! as a little-endian 2's-complement long. If the size is 0, that's taken ! as a shortcut for the long 0L, although LONG1 should really be used ! then instead (and in any case where # of bytes < 256). """) From gvanrossum@users.sourceforge.net Fri Jan 31 16:51:49 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 08:51:49 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.131,1.132 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv25315 Modified Files: pickle.py Log Message: Add a magical feature to save_reduce so that __reduce__ can cause NEWOBJ to be generated. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.131 retrieving revision 1.132 diff -C2 -d -r1.131 -r1.132 *** pickle.py 31 Jan 2003 16:43:39 -0000 1.131 --- pickle.py 31 Jan 2003 16:51:45 -0000 1.132 *************** *** 366,372 **** write = self.write ! save(func) ! save(args) ! write(REDUCE) if state is not None: --- 366,409 ---- write = self.write ! # Protocol 2 special case: if func's name is __newobj__, use NEWOBJ ! if self.proto >= 2 and getattr(func, "__name__", "") == "__newobj__": ! # A __reduce__ implementation can direct protocol 2 to ! # use the more efficient NEWOBJ opcode, while still ! # allowing protocol 0 and 1 to work normally. For this to ! # work, the function returned by __reduce__ should be ! # called __newobj__, and its first argument should be a ! # new-style class. The implementation for __newobj__ ! # should be as follows, although pickle has no way to ! # verify this: ! # ! # def __newobj__(cls, *args): ! # return cls.__new__(cls, *args) ! # ! # Protocols 0 and 1 will pickle a reference to __newobj__, ! # while protocol 2 (and above) will pickle a reference to ! # cls, the remaining args tuple, and the NEWOBJ code, ! # which calls cls.__new__(cls, *args) at unpickling time ! # (see load_newobj below). If __reduce__ returns a ! # three-tuple, the state from the third tuple item will be ! # pickled regardless of the protocol, calling __setstate__ ! # at unpickling time (see load_build below). ! # ! # Note that no standard __newobj__ implementation exists; ! # you have to provide your own. This is to enforce ! # compatibility with Python 2.2 (pickles written using ! # protocol 0 or 1 in Python 2.3 should be unpicklable by ! # Python 2.2). ! cls = args[0] ! if not hasattr(cls, "__new__"): ! raise PicklingError( ! "args[0] from __newobj__ args has no __new__") ! args = args[1:] ! save(cls) ! save(args) ! write(NEWOBJ) ! else: ! save(func) ! save(args) ! write(REDUCE) if state is not None: *************** *** 376,380 **** def save_newobj(self, obj): # Save a new-style class instance, using protocol 2. - # XXX This is still experimental. assert self.proto >= 2 # This only works for protocol 2 t = type(obj) --- 413,416 ---- From gvanrossum@users.sourceforge.net Fri Jan 31 17:17:57 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 09:17:57 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.132,1.133 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv3262 Modified Files: pickle.py Log Message: Pass the object to save_reduce(), so the memoize() call can go into save_reduce(), before the state is pickled. This makes it possible for an object to be referenced from its own (mutable) state. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.132 retrieving revision 1.133 diff -C2 -d -r1.132 -r1.133 *** pickle.py 31 Jan 2003 16:51:45 -0000 1.132 --- pickle.py 31 Jan 2003 17:17:49 -0000 1.133 *************** *** 330,335 **** # Save the reduce() output and finally memoize the object ! self.save_reduce(func, args, state) ! self.memoize(obj) def persistent_id(self, obj): --- 330,334 ---- # Save the reduce() output and finally memoize the object ! self.save_reduce(func, args, state, obj) def persistent_id(self, obj): *************** *** 345,349 **** self.write(PERSID + str(pid) + '\n') ! def save_reduce(self, func, args, state=None): # This API is be called by some subclasses --- 344,348 ---- self.write(PERSID + str(pid) + '\n') ! def save_reduce(self, func, args, state=None, obj=None): # This API is be called by some subclasses *************** *** 398,401 **** --- 397,403 ---- raise PicklingError( "args[0] from __newobj__ args has no __new__") + if obj is not None and cls is not obj.__class__: + raise PicklingError( + "args[0] from __newobj__ args has the wrong class") args = args[1:] save(cls) *************** *** 406,409 **** --- 408,414 ---- save(args) write(REDUCE) + + if obj is not None: + self.memoize(obj) if state is not None: From doerwalter@users.sourceforge.net Fri Jan 31 17:19:40 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 31 Jan 2003 09:19:40 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libcodecs.tex,1.16,1.17 libfuncs.tex,1.127,1.128 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv3391/dist/src/Doc/lib Modified Files: libcodecs.tex libfuncs.tex Log Message: Change the treatment of positions returned by PEP293 error handers in the Unicode codecs: Negative positions are treated as being relative to the end of the input and out of bounds positions result in an IndexError. Also update the PEP and include an explanation of this in the documentation for codecs.register_error. Fixes a small bug in iconv_codecs: if the position from the callback is negative *add* it to the size instead of substracting it. >From SF patch #677429. Index: libcodecs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcodecs.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** libcodecs.tex 31 Dec 2002 12:39:07 -0000 1.16 --- libcodecs.tex 31 Jan 2003 17:19:04 -0000 1.17 *************** *** 104,112 **** name \var{name}. \var{error_handler} will be called during encoding and decoding in case of an error, when \var{name} is specified as the ! errors parameter. \var{error_handler} will be called with an ! \exception{UnicodeEncodeError}, \exception{UnicodeDecodeError} or ! \exception{UnicodeTranslateError} instance and must return a tuple ! with a replacement for the unencodable/undecodable part of the input ! and a position where encoding/decoding should continue. \end{funcdesc} --- 104,123 ---- name \var{name}. \var{error_handler} will be called during encoding and decoding in case of an error, when \var{name} is specified as the ! errors parameter. ! ! For encoding \var{error_handler} will be called with a ! \exception{UnicodeEncodeError} instance, which contains information about ! the location of the error. The error handler must either raise this or ! a different exception or return a tuple with a replacement for the ! unencodable part of the input and a position where encoding should ! continue. The encoder will encode the replacement and continue encoding ! the original input at the specified position. Negative position values ! will be treated as being relative to the end of the input string. If the ! resulting position is out of bound an IndexError will be raised. ! ! Decoding and translating works similar, except \exception{UnicodeDecodeError} ! or \exception{UnicodeTranslateError} will be passed to the handler and ! that the replacement from the error handler will be put into the output ! directly. \end{funcdesc} Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.127 retrieving revision 1.128 diff -C2 -d -r1.127 -r1.128 *** libfuncs.tex 4 Jan 2003 02:16:22 -0000 1.127 --- libfuncs.tex 31 Jan 2003 17:19:05 -0000 1.128 *************** *** 573,577 **** thereof. Also return true if \var{classinfo} is a type object and \var{object} is an object of that type. If \var{object} is not a ! class instance or a object of the given type, the function always returns false. If \var{classinfo} is neither a class object nor a type object, it may be a tuple of class or type objects, or may --- 573,577 ---- thereof. Also return true if \var{classinfo} is a type object and \var{object} is an object of that type. If \var{object} is not a ! class instance or an object of the given type, the function always returns false. If \var{classinfo} is neither a class object nor a type object, it may be a tuple of class or type objects, or may From doerwalter@users.sourceforge.net Fri Jan 31 17:19:40 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 31 Jan 2003 09:19:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_codeccallbacks.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv3391/dist/src/Lib/test Modified Files: test_codeccallbacks.py Log Message: Change the treatment of positions returned by PEP293 error handers in the Unicode codecs: Negative positions are treated as being relative to the end of the input and out of bounds positions result in an IndexError. Also update the PEP and include an explanation of this in the documentation for codecs.register_error. Fixes a small bug in iconv_codecs: if the position from the callback is negative *add* it to the size instead of substracting it. >From SF patch #677429. Index: test_codeccallbacks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codeccallbacks.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_codeccallbacks.py 20 Jan 2003 02:34:07 -0000 1.8 --- test_codeccallbacks.py 31 Jan 2003 17:19:07 -0000 1.9 *************** *** 2,5 **** --- 2,22 ---- import sys, codecs, htmlentitydefs, unicodedata + class PosReturn: + # this can be used for configurable callbacks + + def __init__(self): + self.pos = 0 + + def handle(self, exc): + oldpos = self.pos + realpos = oldpos + if realpos<0: + realpos = len(exc.object) + realpos + # if we don't advance this time, terminate on the next call + # otherwise we'd get an endless loop + if realpos <= exc.start: + self.pos = len(exc.object) + return (u"", oldpos) + class CodecCallbackTest(unittest.TestCase): *************** *** 544,559 **** self.assertRaises(TypeError, "\xff".decode, "ascii", "test.baddecodereturn2") ! pos = [-42] ! def negposreturn(exc): ! pos[0] += 1 # use list to work around scoping problem ! return (u"?", pos[0]) ! codecs.register_error("test.negposreturn", negposreturn) ! "\xff".decode("ascii", "test.negposreturn") ! def hugeposreturn(exc): ! return (u"?", 424242) ! codecs.register_error("test.hugeposreturn", hugeposreturn) ! "\xff".decode("ascii", "test.hugeposreturn") ! "\\uyyyy".decode("raw-unicode-escape", "test.hugeposreturn") class D(dict): --- 561,594 ---- self.assertRaises(TypeError, "\xff".decode, "ascii", "test.baddecodereturn2") ! handler = PosReturn() ! codecs.register_error("test.posreturn", handler.handle) ! # Valid negative position ! handler.pos = -1 ! self.assertEquals("\xff0".decode("ascii", "test.posreturn"), u"0") ! ! # Valid negative position ! handler.pos = -2 ! self.assertEquals("\xff0".decode("ascii", "test.posreturn"), u"") ! ! # Negative position out of bounds ! handler.pos = -3 ! self.assertRaises(IndexError, "\xff0".decode, "ascii", "test.posreturn") ! ! # Valid positive position ! handler.pos = 1 ! self.assertEquals("\xff0".decode("ascii", "test.posreturn"), u"0") ! ! # Largest valid positive position (one beyond end of input ! handler.pos = 2 ! self.assertEquals("\xff0".decode("ascii", "test.posreturn"), u"") ! ! # Invalid positive position ! handler.pos = 3 ! self.assertRaises(IndexError, "\xff0".decode, "ascii", "test.posreturn") ! ! # Restart at the "0" ! handler.pos = 6 ! self.assertEquals("\\uyyyy0".decode("raw-unicode-escape", "test.posreturn"), u"0") class D(dict): *************** *** 580,599 **** self.assertRaises(TypeError, u"\xff".encode, "ascii", "test.badencodereturn2") ! pos = [-42] ! def negposreturn(exc): ! pos[0] += 1 # use list to work around scoping problem ! return (u"?", pos[0]) ! codecs.register_error("test.negposreturn", negposreturn) ! u"\xff".encode("ascii", "test.negposreturn") ! def hugeposreturn(exc): ! return (u"?", 424242) ! codecs.register_error("test.hugeposreturn", hugeposreturn) ! u"\xff".encode("ascii", "test.hugeposreturn") class D(dict): def __getitem__(self, key): raise ValueError ! for err in ("strict", "replace", "xmlcharrefreplace", "backslashreplace", "test.hugeposreturn"): self.assertRaises(UnicodeError, codecs.charmap_encode, u"\xff", err, {0xff: None}) self.assertRaises(ValueError, codecs.charmap_encode, u"\xff", err, D()) --- 615,651 ---- self.assertRaises(TypeError, u"\xff".encode, "ascii", "test.badencodereturn2") ! handler = PosReturn() ! codecs.register_error("test.posreturn", handler.handle) ! # Valid negative position ! handler.pos = -1 ! self.assertEquals(u"\xff0".encode("ascii", "test.posreturn"), "0") ! ! # Valid negative position ! handler.pos = -2 ! self.assertEquals(u"\xff0".encode("ascii", "test.posreturn"), "") ! ! # Negative position out of bounds ! handler.pos = -3 ! self.assertRaises(IndexError, u"\xff0".encode, "ascii", "test.posreturn") ! ! # Valid positive position ! handler.pos = 1 ! self.assertEquals(u"\xff0".encode("ascii", "test.posreturn"), "0") ! ! # Largest valid positive position (one beyond end of input ! handler.pos = 2 ! self.assertEquals(u"\xff0".encode("ascii", "test.posreturn"), "") ! ! # Invalid positive position ! handler.pos = 3 ! self.assertRaises(IndexError, u"\xff0".encode, "ascii", "test.posreturn") ! ! handler.pos = 0 class D(dict): def __getitem__(self, key): raise ValueError ! for err in ("strict", "replace", "xmlcharrefreplace", "backslashreplace", "test.posreturn"): self.assertRaises(UnicodeError, codecs.charmap_encode, u"\xff", err, {0xff: None}) self.assertRaises(ValueError, codecs.charmap_encode, u"\xff", err, D()) From doerwalter@users.sourceforge.net Fri Jan 31 17:19:40 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 31 Jan 2003 09:19:40 -0800 Subject: [Python-checkins] python/dist/src/Modules _iconv_codec.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv3391/dist/src/Modules Modified Files: _iconv_codec.c Log Message: Change the treatment of positions returned by PEP293 error handers in the Unicode codecs: Negative positions are treated as being relative to the end of the input and out of bounds positions result in an IndexError. Also update the PEP and include an explanation of this in the documentation for codecs.register_error. Fixes a small bug in iconv_codecs: if the position from the callback is negative *add* it to the size instead of substracting it. >From SF patch #677429. Index: _iconv_codec.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** _iconv_codec.c 31 Jan 2003 16:26:50 -0000 1.6 --- _iconv_codec.c 31 Jan 2003 17:19:07 -0000 1.7 *************** *** 248,253 **** if (newpos < 0) ! newpos = inputlen - newpos; ! if (newpos < 0 || newpos >= inputlen) break; inp = inp_top + Py_UNICODE_SIZE * newpos; --- 248,258 ---- if (newpos < 0) ! newpos = inputlen + newpos; ! if (newpos < 0 || newpos > inputlen) { ! PyErr_Format(PyExc_IndexError, "position %ld from error handler" ! " out of bounds", newpos); ! goto errorexit; ! } ! if (newpos == inputlen) break; inp = inp_top + Py_UNICODE_SIZE * newpos; *************** *** 472,477 **** if (newpos < 0) ! newpos = inplen_total - newpos; ! if (newpos < 0 || newpos >= inplen_total) break; inp = inp_top + newpos; --- 477,487 ---- if (newpos < 0) ! newpos = inplen_total + newpos; ! if (newpos < 0 || newpos > inplen_total) { ! PyErr_Format(PyExc_IndexError, "position %ld from error handler" ! " out of bounds", newpos); ! goto errorexit; ! } ! if (newpos == inplen_total) break; inp = inp_top + newpos; From doerwalter@users.sourceforge.net Fri Jan 31 17:19:41 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 31 Jan 2003 09:19:41 -0800 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c,2.179,2.180 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv3391/dist/src/Objects Modified Files: unicodeobject.c Log Message: Change the treatment of positions returned by PEP293 error handers in the Unicode codecs: Negative positions are treated as being relative to the end of the input and out of bounds positions result in an IndexError. Also update the PEP and include an explanation of this in the documentation for codecs.register_error. Fixes a small bug in iconv_codecs: if the position from the callback is negative *add* it to the size instead of substracting it. >From SF patch #677429. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.179 retrieving revision 2.180 diff -C2 -d -r2.179 -r2.180 *** unicodeobject.c 29 Jan 2003 17:58:45 -0000 2.179 --- unicodeobject.c 31 Jan 2003 17:19:08 -0000 2.180 *************** *** 729,735 **** goto onError; if (newpos<0) ! newpos = 0; ! else if (newpos>insize) ! newpos = insize; /* need more space? (at least enough for what we --- 729,737 ---- goto onError; if (newpos<0) ! newpos = insize+newpos; ! if (newpos<0 || newpos>insize) { ! PyErr_Format(PyExc_IndexError, "position %d from error handler out of bounds", newpos); ! goto onError; ! } /* need more space? (at least enough for what we *************** *** 2247,2253 **** } if (*newpos<0) ! *newpos = 0; ! else if (*newpos>size) ! *newpos = size; Py_INCREF(resunicode); Py_DECREF(restuple); --- 2249,2258 ---- } if (*newpos<0) ! *newpos = size+*newpos; ! if (*newpos<0 || *newpos>size) { ! PyErr_Format(PyExc_IndexError, "position %d from error handler out of bounds", *newpos); ! Py_DECREF(restuple); ! return NULL; ! } Py_INCREF(resunicode); Py_DECREF(restuple); *************** *** 3085,3091 **** } if (*newpos<0) ! *newpos = 0; ! else if (*newpos>size) ! *newpos = size; Py_INCREF(resunicode); Py_DECREF(restuple); --- 3090,3099 ---- } if (*newpos<0) ! *newpos = size+*newpos; ! if (*newpos<0 || *newpos>size) { ! PyErr_Format(PyExc_IndexError, "position %d from error handler out of bounds", *newpos); ! Py_DECREF(restuple); ! return NULL; ! } Py_INCREF(resunicode); Py_DECREF(restuple); From doerwalter@users.sourceforge.net Fri Jan 31 17:19:42 2003 From: doerwalter@users.sourceforge.net (doerwalter@users.sourceforge.net) Date: Fri, 31 Jan 2003 09:19:42 -0800 Subject: [Python-checkins] python/nondist/peps pep-0293.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv3391/nondist/peps Modified Files: pep-0293.txt Log Message: Change the treatment of positions returned by PEP293 error handers in the Unicode codecs: Negative positions are treated as being relative to the end of the input and out of bounds positions result in an IndexError. Also update the PEP and include an explanation of this in the documentation for codecs.register_error. Fixes a small bug in iconv_codecs: if the position from the callback is negative *add* it to the size instead of substracting it. >From SF patch #677429. Index: pep-0293.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0293.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0293.txt 3 Sep 2002 15:58:43 -0000 1.6 --- pep-0293.txt 31 Jan 2003 17:19:09 -0000 1.7 *************** *** 105,108 **** --- 105,112 ---- replacement) the encoder will continue encoding. + Negative values for newpos are treated as being relative to + end of object. If newpos is out of bounds the encoder will raise + an IndexError. + If the replacement string itself contains an unencodable character the encoder raises the exception object (but may set a different From montanaro@users.sourceforge.net Fri Jan 31 17:28:15 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 31 Jan 2003 09:28:15 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv7906 Modified Files: pep-0304.txt Log Message: various tweaks testing the current patch turned up a shortcoming. When the bytecode base is defined, it's not safe to delete the source code. The bytecode file generated won't be found. Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pep-0304.txt 29 Jan 2003 22:49:04 -0000 1.9 --- pep-0304.txt 31 Jan 2003 17:28:11 -0000 1.10 *************** *** 30,55 **** Add a new environment variable, PYTHONBYTECODEBASE, to the mix of ! environment variables which Python understands. Its interpretation ! is: ! - If not present Python bytecode is generated in exactly the same way ! as is currently done. sys.bytecodebase is set to the root ! directory (either / on Unix or the root directory of the startup ! drive -- typically ``C:\`` -- on Windows). ! - If present and it refers to an existing directory, ! sys.bytecodebase is set to that directory and bytecode files ! are written into a directory structure rooted at that location. ! - If present but empty, sys.bytecodebase is set to None and generation of bytecode files is suppressed altogether. ! - If present and it does not refer to an existing directory, a warning ! is displayed, sys.bytecodebase is set to None and generation ! of bytecode files is suppressed altogether. ! After startup, all runtime references are to sys.bytecodebase, ! not the PYTHONBYTECODEBASE environment variable. sys.path is not ! modified. Note that this PEP is explicitly *not* about providing --- 30,79 ---- Add a new environment variable, PYTHONBYTECODEBASE, to the mix of ! environment variables which Python understands. PYTHONBYTECODEBASE is ! interpreted as follows: ! - If not defined, Python bytecode is generated in exactly the same way ! as is currently done. sys.bytecodebase is set to the root directory ! (either / on Unix or the root directory of the startup drive -- ! typically ``C:\`` -- on Windows). ! - If defined and it refers to an existing directory to which the user ! has write permission, sys.bytecodebase is set to that directory and ! bytecode files are written into a directory structure rooted at that ! location. ! - If defined but empty, sys.bytecodebase is set to None and generation ! of bytecode files is suppressed altogether. ! ! - If defined and one of the following is true:: ! ! * it does not refer to a directory, ! ! * it refers to a directory, but not one for which the user has write ! permission ! ! a warning is displayed, sys.bytecodebase is set to None and generation of bytecode files is suppressed altogether. ! After startup initialization, all runtime references are to ! sys.bytecodebase, not the PYTHONBYTECODEBASE environment variable. ! sys.path is not modified. ! From the above, we see sys.bytecodebase can only take on two valid ! types of values: None or a string referring to a valid directory on ! the system. ! ! During import, this extension works as follows: ! ! - The normal search for a module is conducted. The search order is ! roughly: dynamically loaded extension module, Python source file, ! Python bytecode file. The only time this mechanism comes into play ! is if a Python source file is found. ! ! - Once we've found a source module, an attempt to read a byte-compiled ! file in the same directory is made. (This is the same as before.) ! ! - If no byte-compiled file is found, an attempt to read a ! byte-compiled file from the augmented directory is made. Note that this PEP is explicitly *not* about providing *************** *** 200,203 **** --- 224,235 ---- considered yet. In fact, the best way to implement this idea might be as an import hook. See PEP 302. [5]_ + + - In the current (pre-PEP 304) environment, it is safe to delete a + source file after the corresponding bytecode file has been created, + since they reside in the same directory. With PEP 304 as currently + defined, this is not the case. A bytecode file in the augmented + directory is only considered when the source file is present and it + thus never considered when looking for module files ending in + ".pyc". I think this behavior may have to change. From mwh@users.sourceforge.net Fri Jan 31 17:48:33 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Fri, 31 Jan 2003 09:48:33 -0800 Subject: [Python-checkins] python/dist/src/Lib pdb.py,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv20779 Modified Files: pdb.py Log Message: I believe this fixes [ 669692 ] pdb user_call breakage What an odd interface! I guess I should have read the docstring, though. Index: pdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pdb.py,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** pdb.py 13 Jan 2003 21:13:55 -0000 1.60 --- pdb.py 31 Jan 2003 17:48:29 -0000 1.61 *************** *** 118,123 **** """This method is called when there is the remote possibility that we ever need to stop in this function.""" ! print '--Call--' ! self.interaction(frame, None) def user_line(self, frame): --- 118,124 ---- """This method is called when there is the remote possibility that we ever need to stop in this function.""" ! if self.stop_here(frame): ! print '--Call--' ! self.interaction(frame, None) def user_line(self, frame): From gvanrossum@users.sourceforge.net Fri Jan 31 18:16:14 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:16:14 -0800 Subject: [Python-checkins] python/dist/src/Modules socketmodule.c,1.251,1.252 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7196 Modified Files: socketmodule.c Log Message: SF patch #678257 by Geoff Talvola. In sendall(), do an internal select before each send() call, instead of only for the first one. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.251 retrieving revision 1.252 diff -C2 -d -r1.251 -r1.252 *** socketmodule.c 6 Jan 2003 12:41:26 -0000 1.251 --- socketmodule.c 31 Jan 2003 18:15:58 -0000 1.252 *************** *** 1849,1854 **** Py_BEGIN_ALLOW_THREADS - internal_select(s, 1); do { n = send(s->sock_fd, buf, len, flags); if (n < 0) --- 1849,1854 ---- Py_BEGIN_ALLOW_THREADS do { + internal_select(s, 1); n = send(s->sock_fd, buf, len, flags); if (n < 0) From jhylton@users.sourceforge.net Fri Jan 31 18:33:19 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:33:19 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.133,1.134 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv18557/Lib Modified Files: pickle.py Log Message: Provide __module__ attributes for functions defined in C and Python. __module__ is the string name of the module the function was defined in, just like __module__ of classes. In some cases, particularly for C functions, the __module__ may be None. Change PyCFunction_New() from a function to a macro, but keep an unused copy of the function around so that we don't change the binary API. Change pickle's save_global() to use whichmodule() if __module__ is None, but add the __module__ logic to whichmodule() since it might be used outside of pickle. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.133 retrieving revision 1.134 diff -C2 -d -r1.133 -r1.134 *** pickle.py 31 Jan 2003 17:17:49 -0000 1.133 --- pickle.py 31 Jan 2003 18:33:16 -0000 1.134 *************** *** 788,794 **** name = obj.__name__ ! try: ! module = obj.__module__ ! except AttributeError: module = whichmodule(obj, name) --- 788,793 ---- name = obj.__name__ ! module = getattr(obj, "__module__", None) ! if module is None: module = whichmodule(obj, name) *************** *** 877,880 **** --- 876,883 ---- If the function cannot be found, return "__main__". """ + # Python functions should always get an __module__ from their globals. + mod = getattr(func, "__module__", None) + if mod is not None: + return mod if func in classmap: return classmap[func] From jhylton@users.sourceforge.net Fri Jan 31 18:33:19 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:33:19 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_funcattrs.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv18557/Lib/test Modified Files: test_funcattrs.py Log Message: Provide __module__ attributes for functions defined in C and Python. __module__ is the string name of the module the function was defined in, just like __module__ of classes. In some cases, particularly for C functions, the __module__ may be None. Change PyCFunction_New() from a function to a macro, but keep an unused copy of the function around so that we don't change the binary API. Change pickle's save_global() to use whichmodule() if __module__ is None, but add the __module__ logic to whichmodule() since it might be used outside of pickle. Index: test_funcattrs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_funcattrs.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_funcattrs.py 30 Jul 2002 23:26:01 -0000 1.12 --- test_funcattrs.py 31 Jan 2003 18:33:17 -0000 1.13 *************** *** 10,13 **** --- 10,17 ---- pass + # __module__ is a special attribute + verify(b.__module__ == __name__) + verify(verify.__module__ == "test.test_support") + # setting attributes on functions try: From jhylton@users.sourceforge.net Fri Jan 31 18:33:20 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:33:20 -0800 Subject: [Python-checkins] python/dist/src/Objects funcobject.c,2.57,2.58 methodobject.c,2.44,2.45 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv18557/Objects Modified Files: funcobject.c methodobject.c Log Message: Provide __module__ attributes for functions defined in C and Python. __module__ is the string name of the module the function was defined in, just like __module__ of classes. In some cases, particularly for C functions, the __module__ may be None. Change PyCFunction_New() from a function to a macro, but keep an unused copy of the function around so that we don't change the binary API. Change pickle's save_global() to use whichmodule() if __module__ is None, but add the __module__ logic to whichmodule() since it might be used outside of pickle. Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** funcobject.c 29 Dec 2002 16:33:11 -0000 2.57 --- funcobject.c 31 Jan 2003 18:33:17 -0000 2.58 *************** *** 15,18 **** --- 15,19 ---- PyObject *doc; PyObject *consts; + PyObject *module; op->func_weakreflist = NULL; Py_INCREF(code); *************** *** 35,38 **** --- 36,49 ---- op->func_doc = doc; op->func_dict = NULL; + op->func_module = NULL; + + /* __module__: If module name is in globals, use it. + Otherwise, use None. + */ + module = PyDict_GetItemString(globals, "__name__"); + if (module) { + Py_INCREF(module); + op->func_module = module; + } } else *************** *** 63,66 **** --- 74,87 ---- PyObject * + PyFunction_GetModule(PyObject *op) + { + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_module; + } + + PyObject * PyFunction_GetDefaults(PyObject *op) { *************** *** 139,142 **** --- 160,164 ---- {"func_name", T_OBJECT, OFF(func_name), READONLY}, {"__name__", T_OBJECT, OFF(func_name), READONLY}, + {"__module__", T_OBJECT, OFF(func_module), READONLY}, {NULL} /* Sentinel */ }; *************** *** 374,377 **** --- 396,400 ---- Py_DECREF(op->func_code); Py_DECREF(op->func_globals); + Py_XDECREF(op->func_module); Py_DECREF(op->func_name); Py_XDECREF(op->func_defaults); *************** *** 403,406 **** --- 426,434 ---- if (f->func_globals) { err = visit(f->func_globals, arg); + if (err) + return err; + } + if (f->func_module) { + err = visit(f->func_module, arg); if (err) return err; Index: methodobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v retrieving revision 2.44 retrieving revision 2.45 diff -C2 -d -r2.44 -r2.45 *** methodobject.c 5 Jan 2003 07:22:44 -0000 2.44 --- methodobject.c 31 Jan 2003 18:33:17 -0000 2.45 *************** *** 3,11 **** #include "Python.h" static PyCFunctionObject *free_list = NULL; PyObject * ! PyCFunction_New(PyMethodDef *ml, PyObject *self) { PyCFunctionObject *op; --- 3,12 ---- #include "Python.h" + #include "structmember.h" static PyCFunctionObject *free_list = NULL; PyObject * ! PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) { PyCFunctionObject *op; *************** *** 23,26 **** --- 24,29 ---- Py_XINCREF(self); op->m_self = self; + Py_XINCREF(module); + op->m_module = module; _PyObject_GC_TRACK(op); return (PyObject *)op; *************** *** 122,125 **** --- 125,129 ---- _PyObject_GC_UNTRACK(m); Py_XDECREF(m->m_self); + Py_XDECREF(m->m_module); m->m_self = (PyObject *)free_list; free_list = m; *************** *** 146,153 **** meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) { ! if (m->m_self != NULL) ! return visit(m->m_self, arg); ! else ! return 0; } --- 150,165 ---- meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) { ! int err; ! if (m->m_self != NULL) { ! err = visit(m->m_self, arg); ! if (err) ! return err; ! } ! if (m->m_module != NULL) { ! err = visit(m->m_module, arg); ! if (err) ! return err; ! } ! return 0; } *************** *** 175,178 **** --- 187,197 ---- }; + #define OFF(x) offsetof(PyCFunctionObject, x) + + static PyMemberDef meth_members[] = { + {"__module__", T_OBJECT, OFF(m_module), READONLY}, + {NULL} + }; + static PyObject * meth_repr(PyCFunctionObject *m) *************** *** 251,255 **** 0, /* tp_iternext */ 0, /* tp_methods */ ! 0, /* tp_members */ meth_getsets, /* tp_getset */ 0, /* tp_base */ --- 270,274 ---- 0, /* tp_iternext */ 0, /* tp_methods */ ! meth_members, /* tp_members */ meth_getsets, /* tp_getset */ 0, /* tp_base */ *************** *** 309,312 **** --- 328,332 ---- if (name[0] == ml->ml_name[0] && strcmp(name+1, ml->ml_name+1) == 0) + /* XXX */ return PyCFunction_New(ml, self); } *************** *** 338,340 **** --- 358,374 ---- PyObject_GC_Del(v); } + } + + /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(), + but it's part of the API so we need to keep a function around that + existing C extensions can call. + */ + + #undef PyCFunction_New + PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *); + + PyObject * + PyCFunction_New(PyMethodDef *ml, PyObject *self) + { + return PyCFunction_NewEx(ml, self, NULL); } From jhylton@users.sourceforge.net Fri Jan 31 18:33:20 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:33:20 -0800 Subject: [Python-checkins] python/dist/src/Python exceptions.c,1.42,1.43 modsupport.c,2.64,2.65 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv18557/Python Modified Files: exceptions.c modsupport.c Log Message: Provide __module__ attributes for functions defined in C and Python. __module__ is the string name of the module the function was defined in, just like __module__ of classes. In some cases, particularly for C functions, the __module__ may be None. Change PyCFunction_New() from a function to a macro, but keep an unused copy of the function around so that we don't change the binary API. Change pickle's save_global() to use whichmodule() if __module__ is None, but add the __module__ logic to whichmodule() since it might be used outside of pickle. Index: exceptions.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/exceptions.c,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** exceptions.c 6 Dec 2002 12:48:53 -0000 1.42 --- exceptions.c 31 Jan 2003 18:33:18 -0000 1.43 *************** *** 127,146 **** populate_methods(PyObject *klass, PyObject *dict, PyMethodDef *methods) { if (!methods) return 0; while (methods->ml_name) { /* get a wrapper for the built-in function */ ! PyObject *func = PyCFunction_New(methods, NULL); PyObject *meth; - int status; if (!func) ! return -1; /* turn the function into an unbound method */ if (!(meth = PyMethod_New(func, NULL, klass))) { Py_DECREF(func); ! return -1; } --- 127,151 ---- populate_methods(PyObject *klass, PyObject *dict, PyMethodDef *methods) { + PyObject *module; + int status = -1; + if (!methods) return 0; + module = PyString_FromString("exceptions"); + if (!module) + return 0; while (methods->ml_name) { /* get a wrapper for the built-in function */ ! PyObject *func = PyCFunction_NewEx(methods, NULL, module); PyObject *meth; if (!func) ! goto status; /* turn the function into an unbound method */ if (!(meth = PyMethod_New(func, NULL, klass))) { Py_DECREF(func); ! goto status; } *************** *** 152,160 **** /* stop now if an error occurred, otherwise do the next method */ if (status) ! return status; methods++; } ! return 0; } --- 157,168 ---- /* stop now if an error occurred, otherwise do the next method */ if (status) ! goto status; methods++; } ! status = 0; ! status: ! Py_DECREF(module); ! return status; } Index: modsupport.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/modsupport.c,v retrieving revision 2.64 retrieving revision 2.65 diff -C2 -d -r2.64 -r2.65 *** modsupport.c 30 Jan 2003 15:08:25 -0000 2.64 --- modsupport.c 31 Jan 2003 18:33:18 -0000 2.65 *************** *** 34,38 **** PyObject *passthrough, int module_api_version) { ! PyObject *m, *d, *v; PyMethodDef *ml; if (!Py_IsInitialized()) --- 34,38 ---- PyObject *passthrough, int module_api_version) { ! PyObject *m, *d, *v, *n; PyMethodDef *ml; if (!Py_IsInitialized()) *************** *** 47,50 **** --- 47,59 ---- return NULL; } + /* Make sure name is fully qualified. + + This is a bit of a hack: when the shared library is loaded, + the module name is "package.module", but the module calls + Py_InitModule*() with just "module" for the name. The shared + library loader squirrels away the true name of the module in + _Py_PackageContext, and Py_InitModule*() will substitute this + (if the name actually matches). + */ if (_Py_PackageContext != NULL) { char *p = strrchr(_Py_PackageContext, '.'); *************** *** 58,61 **** --- 67,73 ---- d = PyModule_GetDict(m); if (methods != NULL) { + n = PyString_FromString(name); + if (n == NULL) + return NULL; for (ml = methods; ml->ml_name != NULL; ml++) { if ((ml->ml_flags & METH_CLASS) || *************** *** 66,70 **** return NULL; } ! v = PyCFunction_New(ml, passthrough); if (v == NULL) return NULL; --- 78,82 ---- return NULL; } ! v = PyCFunction_NewEx(ml, passthrough, n); if (v == NULL) return NULL; From jhylton@users.sourceforge.net Fri Jan 31 18:33:49 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:33:49 -0800 Subject: [Python-checkins] python/dist/src/Include funcobject.h,2.25,2.26 methodobject.h,2.25,2.26 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv18557/Include Modified Files: funcobject.h methodobject.h Log Message: Provide __module__ attributes for functions defined in C and Python. __module__ is the string name of the module the function was defined in, just like __module__ of classes. In some cases, particularly for C functions, the __module__ may be None. Change PyCFunction_New() from a function to a macro, but keep an unused copy of the function around so that we don't change the binary API. Change pickle's save_global() to use whichmodule() if __module__ is None, but add the __module__ logic to whichmodule() since it might be used outside of pickle. Index: funcobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/funcobject.h,v retrieving revision 2.25 retrieving revision 2.26 diff -C2 -d -r2.25 -r2.26 *** funcobject.h 12 Aug 2002 07:21:56 -0000 2.25 --- funcobject.h 31 Jan 2003 18:33:15 -0000 2.26 *************** *** 18,21 **** --- 18,22 ---- PyObject *func_dict; PyObject *func_weakreflist; + PyObject *func_module; } PyFunctionObject; *************** *** 27,30 **** --- 28,32 ---- PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); + PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); *************** *** 38,41 **** --- 40,45 ---- #define PyFunction_GET_GLOBALS(func) \ (((PyFunctionObject *)func) -> func_globals) + #define PyFunction_GET_MODULE(func) \ + (((PyFunctionObject *)func) -> func_module) #define PyFunction_GET_DEFAULTS(func) \ (((PyFunctionObject *)func) -> func_defaults) Index: methodobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/methodobject.h,v retrieving revision 2.25 retrieving revision 2.26 diff -C2 -d -r2.25 -r2.26 *** methodobject.h 12 Aug 2002 07:21:57 -0000 2.25 --- methodobject.h 31 Jan 2003 18:33:15 -0000 2.26 *************** *** 41,45 **** PyAPI_FUNC(PyObject *) Py_FindMethod(PyMethodDef[], PyObject *, char *); ! PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *); /* Flag passed to newmethodobject */ --- 41,47 ---- PyAPI_FUNC(PyObject *) Py_FindMethod(PyMethodDef[], PyObject *, char *); ! #define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) ! PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, ! PyObject *); /* Flag passed to newmethodobject */ *************** *** 69,72 **** --- 71,75 ---- PyMethodDef *m_ml; PyObject *m_self; + PyObject *m_module; } PyCFunctionObject; From jhylton@users.sourceforge.net Fri Jan 31 18:52:49 2003 From: jhylton@users.sourceforge.net (jhylton@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:52:49 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref3.tex,1.98,1.99 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv31777 Modified Files: ref3.tex Log Message: Document __module__. Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -d -r1.98 -r1.99 *** ref3.tex 19 Jan 2003 14:57:12 -0000 1.98 --- ref3.tex 31 Jan 2003 18:52:45 -0000 1.99 *************** *** 437,442 **** Special attributes: \member{func_doc} or \member{__doc__} is the ! function's documentation string, or None if unavailable; \member{func_name} or \member{__name__} is the function's name; \member{func_defaults} is a tuple containing default argument values for those arguments that have defaults, or \code{None} if no arguments --- 437,444 ---- Special attributes: \member{func_doc} or \member{__doc__} is the ! function's documentation string, or \code{None} if unavailable; \member{func_name} or \member{__name__} is the function's name; + \member{__module__} is the name of the module the function was defined + in, or \code{None} if unavailable; \member{func_defaults} is a tuple containing default argument values for those arguments that have defaults, or \code{None} if no arguments *************** *** 461,464 **** --- 463,467 ---- \ttindex{__doc__} \ttindex{__name__} + \ttindex{__module__} \ttindex{__dict__} \ttindex{func_defaults} *************** *** 483,490 **** \member{__doc__} is the method's documentation (same as \code{im_func.__doc__}); \member{__name__} is the method name (same as ! \code{im_func.__name__}). \versionchanged[\member{im_self} used to refer to the class that defined the method]{2.2} \withsubitem{(method attribute)}{ \ttindex{im_func} \ttindex{im_self}} --- 486,497 ---- \member{__doc__} is the method's documentation (same as \code{im_func.__doc__}); \member{__name__} is the method name (same as ! \code{im_func.__name__}); \member{__module__} is the name of the ! module the method was defined in, or \code{None} if unavailable. \versionchanged[\member{im_self} used to refer to the class that defined the method]{2.2} \withsubitem{(method attribute)}{ + \ttindex{__doc__} + \ttindex{__name__} + \ttindex{__module__} \ttindex{im_func} \ttindex{im_self}} *************** *** 556,560 **** documentation string, or \code{None} if unavailable; \member{__name__} is the function's name; \member{__self__} is set to \code{None} (but see ! the next item). \obindex{built-in function} \obindex{function} --- 563,568 ---- documentation string, or \code{None} if unavailable; \member{__name__} is the function's name; \member{__self__} is set to \code{None} (but see ! the next item); \member{__module__} is the name of the module the ! function was defined in or \code{None} if unavailable. \obindex{built-in function} \obindex{function} From gvanrossum@users.sourceforge.net Fri Jan 31 18:53:30 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:53:30 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.134,1.135 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv32128 Modified Files: pickle.py Log Message: Another extension to reduce(). It can return a 4- or 5-tuple now. The 4th item can be None or an iterator yielding list items, which are used to append() or extend() the object. The 5th item can be None or an iterator yielding a dict's (key, value) pairs, which are stuffed into the object using __setitem__. Also (as a separate, though related, feature) add "batching" for list and dict items. If you pickled a dict or list with a million items in the past, it would push a million items onto the stack. It now pushes only 1000 items at a time on the stack, using repeated APPENDS or SETITEMS opcodes. (For lists, I hope that using many short extend() calls doesn't exhibit quadratic behavior.) Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.134 retrieving revision 1.135 diff -C2 -d -r1.134 -r1.135 *** pickle.py 31 Jan 2003 18:33:16 -0000 1.134 --- pickle.py 31 Jan 2003 18:53:21 -0000 1.135 *************** *** 318,334 **** raise PicklingError("%s must return string or tuple" % reduce) ! # Assert that it returned a 2-tuple or 3-tuple, and unpack it l = len(rv) ! if l == 2: ! func, args = rv ! state = None ! elif l == 3: ! func, args, state = rv ! else: raise PicklingError("Tuple returned by %s must have " ! "exactly two or three elements" % reduce) # Save the reduce() output and finally memoize the object ! self.save_reduce(func, args, state, obj) def persistent_id(self, obj): --- 318,329 ---- raise PicklingError("%s must return string or tuple" % reduce) ! # Assert that it returned an appropriately sized tuple l = len(rv) ! if not (2 <= l <= 5): raise PicklingError("Tuple returned by %s must have " ! "two to five elements" % reduce) # Save the reduce() output and finally memoize the object ! self.save_reduce(obj=obj, *rv) def persistent_id(self, obj): *************** *** 344,348 **** self.write(PERSID + str(pid) + '\n') ! def save_reduce(self, func, args, state=None, obj=None): # This API is be called by some subclasses --- 339,344 ---- self.write(PERSID + str(pid) + '\n') ! def save_reduce(self, func, args, state=None, ! listitems=None, dictitems=None, obj=None): # This API is be called by some subclasses *************** *** 412,415 **** --- 408,422 ---- self.memoize(obj) + # More new special cases (that work with older protocols as + # well): when __reduce__ returns a tuple with 4 or 5 items, + # the 4th and 5th item should be iterators that provide list + # items and dict items (as (key, value) tuples), or None. + + if listitems is not None: + self._batch_appends(listitems) + + if dictitems is not None: + self._batch_setitems(dictitems) + if state is not None: save(state) *************** *** 435,460 **** if isinstance(obj, list): ! n = len(obj) ! if n > 1: ! write(MARK) ! for x in obj: ! save(x) ! write(APPENDS) ! elif n == 1: ! save(obj[0]) ! write(APPEND) elif isinstance(obj, dict): ! n = len(obj) ! if n > 1: ! write(MARK) ! for k, v in obj.iteritems(): ! save(k) ! save(v) ! write(SETITEMS) ! elif n == 1: ! k, v = obj.items()[0] ! save(k) ! save(v) ! write(SETITEM) getstate = getattr(obj, "__getstate__", None) --- 442,448 ---- if isinstance(obj, list): ! self._batch_appends(iter(obj)) elif isinstance(obj, dict): ! self._batch_setitems(obj.iteritems()) getstate = getattr(obj, "__getstate__", None) *************** *** 684,743 **** def save_list(self, obj): write = self.write - save = self.save if self.bin: write(EMPTY_LIST) ! self.memoize(obj) ! n = len(obj) if n > 1: write(MARK) ! for element in obj: ! save(element) write(APPENDS) elif n: ! assert n == 1 ! save(obj[0]) ! write(APPEND) ! # else the list is empty, and we're already done ! ! else: # proto 0 -- can't use EMPTY_LIST or APPENDS ! write(MARK + LIST) ! self.memoize(obj) ! for element in obj: ! save(element) write(APPEND) ! ! dispatch[ListType] = save_list def save_dict(self, obj): write = self.write - save = self.save - items = obj.iteritems() if self.bin: write(EMPTY_DICT) ! self.memoize(obj) ! if len(obj) > 1: ! write(MARK) ! for key, value in items: ! save(key) ! save(value) ! write(SETITEMS) ! return ! # else (dict is empty or a singleton), fall through to the ! # SETITEM code at the end ! else: # proto 0 -- can't use EMPTY_DICT or SETITEMS write(MARK + DICT) - self.memoize(obj) ! # proto 0 or len(obj) < 2 ! for key, value in items: ! save(key) ! save(value) ! write(SETITEM) dispatch[DictionaryType] = save_dict if not PyStringMap is None: dispatch[PyStringMap] = save_dict def save_inst(self, obj): --- 672,768 ---- def save_list(self, obj): write = self.write if self.bin: write(EMPTY_LIST) ! else: # proto 0 -- can't use EMPTY_LIST ! write(MARK + LIST) ! ! self.memoize(obj) ! self._batch_appends(iter(obj)) ! ! dispatch[ListType] = save_list ! ! _BATCHSIZE = 1000 ! ! def _batch_appends(self, items): ! # Helper to batch up APPENDS sequences ! save = self.save ! write = self.write ! ! if not self.bin: ! for x in items: ! save(x) ! write(APPEND) ! return ! ! r = xrange(self._BATCHSIZE) ! while items is not None: ! tmp = [] ! for i in r: ! try: ! tmp.append(items.next()) ! except StopIteration: ! items = None ! break ! n = len(tmp) if n > 1: write(MARK) ! for x in tmp: ! save(x) write(APPENDS) elif n: ! save(tmp[0]) write(APPEND) ! # else tmp is empty, and we're done def save_dict(self, obj): write = self.write if self.bin: write(EMPTY_DICT) ! else: # proto 0 -- can't use EMPTY_DICT write(MARK + DICT) ! self.memoize(obj) ! self._batch_setitems(obj.iteritems()) dispatch[DictionaryType] = save_dict if not PyStringMap is None: dispatch[PyStringMap] = save_dict + + def _batch_setitems(self, items): + # Helper to batch up SETITEMS sequences; proto >= 1 only + save = self.save + write = self.write + + if not self.bin: + for k, v in items: + save(k) + save(v) + write(SETITEM) + return + + r = xrange(self._BATCHSIZE) + while items is not None: + tmp = [] + for i in r: + try: + tmp.append(items.next()) + except StopIteration: + items = None + break + n = len(tmp) + if n > 1: + write(MARK) + for k, v in tmp: + save(k) + save(v) + write(SETITEMS) + elif n: + k, v = tmp[0] + save(k) + save(v) + write(SETITEM) + # else tmp is empty, and we're done def save_inst(self, obj): From gvanrossum@users.sourceforge.net Fri Jan 31 18:13:21 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 10:13:21 -0800 Subject: [Python-checkins] python/dist/src/Modules _ssl.c,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv5789 Modified Files: _ssl.c Log Message: SF patch 676472 by Geoff Talvola, reviewed by Ben Laurie. Geoff writes: This is yet another patch to _ssl.c that sets the underlying BIO to non-blocking if the socket being wrapped is non-blocking. It also correctly loops when SSL_connect, SSL_write, or SSL_read indicates that it needs to read or write more bytes. This seems to fix bug #673797 which was not fixed by my previous patch. Index: _ssl.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_ssl.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** _ssl.c 27 Jan 2003 22:19:21 -0000 1.9 --- _ssl.c 31 Jan 2003 18:13:18 -0000 1.10 *************** *** 169,172 **** --- 169,174 ---- char *errstr = NULL; int ret; + int err; + int timedout; self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */ *************** *** 221,232 **** Py_END_ALLOW_THREADS SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */ Py_BEGIN_ALLOW_THREADS SSL_set_connect_state(self->ssl); ! /* Actually negotiate SSL connection */ /* XXX If SSL_connect() returns 0, it's also a failure. */ ! ret = SSL_connect(self->ssl); ! Py_END_ALLOW_THREADS if (ret <= 0) { PySSL_SetError(self, ret); --- 223,258 ---- Py_END_ALLOW_THREADS SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */ + + /* If the socket is is non-blocking mode or timeout mode, set the BIO + * to non-blocking mode (blocking is the default) + */ + if (Sock->sock_timeout >= 0.0) { + /* Set both the read and write BIO's to non-blocking mode */ + BIO_set_nbio(SSL_get_rbio(self->ssl), 1); + BIO_set_nbio(SSL_get_wbio(self->ssl), 1); + } + Py_BEGIN_ALLOW_THREADS SSL_set_connect_state(self->ssl); ! Py_END_ALLOW_THREADS /* Actually negotiate SSL connection */ /* XXX If SSL_connect() returns 0, it's also a failure. */ ! timedout = 0; ! do { ! Py_BEGIN_ALLOW_THREADS ! ret = SSL_connect(self->ssl); ! err = SSL_get_error(self->ssl, ret); ! Py_END_ALLOW_THREADS ! if (err == SSL_ERROR_WANT_READ) { ! timedout = wait_for_timeout(Sock, 0); ! } else if (err == SSL_ERROR_WANT_WRITE) { ! timedout = wait_for_timeout(Sock, 1); ! } ! if (timedout) { ! PyErr_SetString(PySSLErrorObject, "The connect operation timed out"); ! return NULL; ! } ! } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); if (ret <= 0) { PySSL_SetError(self, ret); *************** *** 329,336 **** --- 355,364 ---- /* See if the socket is ready */ + Py_BEGIN_ALLOW_THREADS if (writing) rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv); else rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv); + Py_END_ALLOW_THREADS /* Return 1 on timeout, 0 otherwise */ *************** *** 343,360 **** int len; int timedout; if (!PyArg_ParseTuple(args, "s#:write", &data, &len)) return NULL; - Py_BEGIN_ALLOW_THREADS timedout = wait_for_timeout(self->Socket, 1); - Py_END_ALLOW_THREADS if (timedout) { PyErr_SetString(PySSLErrorObject, "The write operation timed out"); return NULL; } ! Py_BEGIN_ALLOW_THREADS ! len = SSL_write(self->ssl, data, len); ! Py_END_ALLOW_THREADS if (len > 0) return PyInt_FromLong(len); --- 371,400 ---- int len; int timedout; + int err; if (!PyArg_ParseTuple(args, "s#:write", &data, &len)) return NULL; timedout = wait_for_timeout(self->Socket, 1); if (timedout) { PyErr_SetString(PySSLErrorObject, "The write operation timed out"); return NULL; } ! do { ! err = 0; ! Py_BEGIN_ALLOW_THREADS ! len = SSL_write(self->ssl, data, len); ! err = SSL_get_error(self->ssl, len); ! Py_END_ALLOW_THREADS ! if (err == SSL_ERROR_WANT_READ) { ! timedout = wait_for_timeout(self->Socket, 0); ! } else if (err == SSL_ERROR_WANT_WRITE) { ! timedout = wait_for_timeout(self->Socket, 1); ! } ! if (timedout) { ! PyErr_SetString(PySSLErrorObject, "The write operation timed out"); ! return NULL; ! } ! } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); if (len > 0) return PyInt_FromLong(len); *************** *** 375,378 **** --- 415,419 ---- int len = 1024; int timedout; + int err; if (!PyArg_ParseTuple(args, "|i:read", &len)) *************** *** 382,395 **** return NULL; - Py_BEGIN_ALLOW_THREADS timedout = wait_for_timeout(self->Socket, 0); - Py_END_ALLOW_THREADS if (timedout) { PyErr_SetString(PySSLErrorObject, "The read operation timed out"); return NULL; } ! Py_BEGIN_ALLOW_THREADS ! count = SSL_read(self->ssl, PyString_AsString(buf), len); ! Py_END_ALLOW_THREADS if (count <= 0) { Py_DECREF(buf); --- 423,447 ---- return NULL; timedout = wait_for_timeout(self->Socket, 0); if (timedout) { PyErr_SetString(PySSLErrorObject, "The read operation timed out"); return NULL; } ! do { ! err = 0; ! Py_BEGIN_ALLOW_THREADS ! count = SSL_read(self->ssl, PyString_AsString(buf), len); ! err = SSL_get_error(self->ssl, count); ! Py_END_ALLOW_THREADS ! if (err == SSL_ERROR_WANT_READ) { ! timedout = wait_for_timeout(self->Socket, 0); ! } else if (err == SSL_ERROR_WANT_WRITE) { ! timedout = wait_for_timeout(self->Socket, 1); ! } ! if (timedout) { ! PyErr_SetString(PySSLErrorObject, "The read operation timed out"); ! return NULL; ! } ! } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); if (count <= 0) { Py_DECREF(buf); From gvanrossum@users.sourceforge.net Fri Jan 31 19:12:56 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 11:12:56 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,NONE,1.1 pep-0000.txt,1.226,1.227 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv13017a Modified Files: pep-0000.txt Added Files: pep-0307.txt Log Message: Claim PEP 307 for extensions to the pickle protocol. --- NEW FILE: pep-0307.txt --- PEP: 307 Title: Extensions to the pickle protocol Version: $Revision: 1.1 $ Last-Modified: $Date: 2003/01/31 19:12:53 $ Author: Guido van Rossum, Tim Peters Status: Active Type: Standards Track Content-Type: text/plain Created: 31-Jan-2003 Post-History: None Introduction Pickling new-style objects in Python 2.2 is done somewhat clumsily and causes pickle size to bloat compared to classic class instances. This PEP documents a new pickle protocol that takes care of this and many other pickling issues. (XXX The rest of this PEP is TBD.) 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.226 retrieving revision 1.227 diff -C2 -d -r1.226 -r1.227 *** pep-0000.txt 29 Jan 2003 15:07:58 -0000 1.226 --- pep-0000.txt 31 Jan 2003 19:12:52 -0000 1.227 *************** *** 109,112 **** --- 109,113 ---- I 305 CSV File API Montanaro, et al I 306 How to Change Python's Grammar Hudson + S 307 Extensions to the pickle protocol GvR, Peters Finished PEPs (done, implemented in CVS) *************** *** 305,308 **** --- 306,310 ---- I 305 CSV File API Montanaro, et al I 306 How to Change Python's Grammar Hudson + S 307 Extensions to the pickle protocol GvR, Peters SR 666 Reject Foolish Indentation Creighton From gvanrossum@users.sourceforge.net Fri Jan 31 19:42:35 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 11:42:35 -0800 Subject: [Python-checkins] python/dist/src/Lib pickle.py,1.135,1.136 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv2775 Modified Files: pickle.py Log Message: Change the default protocol back to 0. Add a feature suggested by Tim: a negative protocol value means to use the largest protocol value supported. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.135 retrieving revision 1.136 diff -C2 -d -r1.135 -r1.136 *** pickle.py 31 Jan 2003 18:53:21 -0000 1.135 --- pickle.py 31 Jan 2003 19:42:31 -0000 1.136 *************** *** 168,183 **** class Pickler: ! def __init__(self, file, proto=1): """This takes a file-like object for writing a pickle data stream. The optional proto argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2. The default ! protocol is 1 (in previous Python versions the default was 0). Protocol 1 is more efficient than protocol 0; protocol 2 is ! more efficient than protocol 1. Protocol 2 is not the default ! because it is not supported by older Python versions. ! XXX Protocol 2 is not yet implemented. The file parameter must have a write() method that accepts a single --- 168,185 ---- class Pickler: ! def __init__(self, file, proto=0): """This takes a file-like object for writing a pickle data stream. The optional proto argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2. The default ! protocol is 0, to be backwards compatible. (Protocol 0 is the ! only protocol that can be written to a file opened in text ! mode and read back successfully.) Protocol 1 is more efficient than protocol 0; protocol 2 is ! more efficient than protocol 1. ! Specifying a negative protocol version selects the highest ! protocol version supported. The file parameter must have a write() method that accepts a single *************** *** 186,190 **** """ ! if proto not in (0, 1, 2): raise ValueError, "pickle protocol must be 0, 1 or 2" self.write = file.write --- 188,194 ---- """ ! if proto < 0: ! proto = 2 ! elif proto not in (0, 1, 2): raise ValueError, "pickle protocol must be 0, 1 or 2" self.write = file.write *************** *** 1456,1463 **** from StringIO import StringIO ! def dump(obj, file, proto=1): Pickler(file, proto).dump(obj) ! def dumps(obj, proto=1): file = StringIO() Pickler(file, proto).dump(obj) --- 1460,1467 ---- from StringIO import StringIO ! def dump(obj, file, proto=0): Pickler(file, proto).dump(obj) ! def dumps(obj, proto=0): file = StringIO() Pickler(file, proto).dump(obj) From gvanrossum@users.sourceforge.net Fri Jan 31 19:56:36 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 11:56:36 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv13603 Modified Files: pep-0307.txt Log Message: Extend intro; add motivation and a section on protocol versions. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep-0307.txt 31 Jan 2003 19:12:53 -0000 1.1 --- pep-0307.txt 31 Jan 2003 19:56:32 -0000 1.2 *************** *** 16,22 **** and causes pickle size to bloat compared to classic class instances. This PEP documents a new pickle protocol that takes ! care of this and many other pickling issues. ! (XXX The rest of this PEP is TBD.) --- 16,81 ---- and causes pickle size to bloat compared to classic class instances. This PEP documents a new pickle protocol that takes ! care of this and many other pickle issues. ! There are two sides to specifying a new pickle protocol: the byte ! stream constituting pickled data must be specified, and the ! interface between objects and the pickling and unpickling engines ! must be specified. This PEP focuses on API issues, although it ! may occasionally touch on byte stream format details to motivate a ! choice. The pickle byte stream format is documented formally by ! the standard library module pickletools.py (already checked into ! CVS for Python 2.3). ! ! ! Motivation ! ! Pickling new-style objects causes serious pickle bloat. For ! example, the binary pickle for a classic object with one instance ! variable takes up 33 bytes; a new-style object with one instance ! variable takes up 86 bytes. This was measured as follows: ! ! class C(object): # Omit "(object)" for classic class ! pass ! x = C() ! x.foo = 42 ! print len(pickle.dumps(x, 1)) ! ! The reasons for the bloat are complex, but are mostly caused by ! the fact that new-style objects use __reduce__ in order to be ! picklable at all. After ample consideration we've concluded that ! the only way to reduce pickle sizes for new-style objects is to ! add new opcodes to the pickle protocol. The net result is that ! with the new protocol, the pickle size in the above example is 35 ! (two extra bytes are used at the start to indicate the protocol ! version, although this isn't strictly necessary). ! ! ! Protocol versions ! ! Previously, pickling (but not unpickling) has distinguished ! between text mode and binary mode. By design, text mode is a ! subset of binary mode, and unpicklers don't need to know in ! advance whether an incoming pickle uses text mode or binary mode. ! The virtual machine used for unpickling is the same regardless of ! the mode; certain opcode simply aren't used in text mode. ! ! Retroactively, text mode is called protocol 0, and binary mode is ! called protocol 1. The new protocol is called protocol 2. In the ! tradition of pickling protocols, protocol 2 is a superset of ! protocol 1. But just so that future pickling protocols aren't ! required to be supersets of the oldest protocols, a new opcode is ! inserted at the start of a protocol 2 pickle indicating that it is ! using protocol 2. ! ! Several functions, methods and constructors used for pickling used ! to take a positional argument named 'bin' which was a flag, ! defaulting to 0, indicating binary mode. This argument is renamed ! to 'proto' and now gives the protocol number, defaulting to 0. ! ! It so happens that passing 2 for the 'bin' argument in previous ! Python versions had the same effect as passing 1. Nevertheless, a ! special case is added here: passing a negative number selects the ! highest protocol version supported by a particular ! implementation. This works in previous Python versions, too. From gvanrossum@users.sourceforge.net Fri Jan 31 20:01:03 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 12:01:03 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.19,1.20 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv16695 Modified Files: itertools.c Log Message: Fix some overly-long lines (one by shortening a docstring sentence). Remove an unused variable. Add PSF copyright. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** itertools.c 31 Jan 2003 09:14:38 -0000 1.19 --- itertools.c 31 Jan 2003 20:00:56 -0000 1.20 *************** *** 4,10 **** /* Itertools module written and maintained by Raymond D. Hettinger */ ! /* dropwhile object ************************************************************/ typedef struct { --- 4,12 ---- /* Itertools module written and maintained by Raymond D. Hettinger + Copyright (c) 2003 Python Software Foundation. + All rights reserved. */ ! /* dropwhile object **********************************************************/ typedef struct { *************** *** 160,164 **** ! /* takewhile object ************************************************************/ typedef struct { --- 162,166 ---- ! /* takewhile object **********************************************************/ typedef struct { *************** *** 722,726 **** { PyObject *val; ! PyObject *iters=lz->iters, *argtuple=lz->argtuple; int numargs, i; --- 724,728 ---- { PyObject *val; ! PyObject *argtuple=lz->argtuple; int numargs, i; *************** *** 1001,1005 **** } else { PyObject *good; ! good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); --- 1003,1008 ---- } else { PyObject *good; ! good = PyObject_CallFunctionObjArgs(lz->func, ! item, NULL); if (good == NULL) { Py_DECREF(item); *************** *** 1436,1440 **** PyDoc_STRVAR(module_doc, ! "Module implements a set of functional tools for creating and using iterators.\n\ \n\ Infinite iterators:\n\ --- 1439,1443 ---- PyDoc_STRVAR(module_doc, ! "Functional tools for creating and using iterators.\n\ \n\ Infinite iterators:\n\ From gvanrossum@users.sourceforge.net Fri Jan 31 20:34:10 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 12:34:10 -0800 Subject: [Python-checkins] python/dist/src/Lib copy_reg.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv6216 Modified Files: copy_reg.py Log Message: Add extension management to __all__. Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** copy_reg.py 29 Jan 2003 06:14:11 -0000 1.11 --- copy_reg.py 31 Jan 2003 20:34:07 -0000 1.12 *************** *** 7,11 **** from types import ClassType as _ClassType ! __all__ = ["pickle","constructor"] dispatch_table = {} --- 7,12 ---- from types import ClassType as _ClassType ! __all__ = ["pickle", "constructor", ! "add_extension", "remove_extension", "clear_extension_cache"] dispatch_table = {} From theller@users.sourceforge.net Fri Jan 31 20:40:20 2003 From: theller@users.sourceforge.net (theller@users.sourceforge.net) Date: Fri, 31 Jan 2003 12:40:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils msvccompiler.py,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory sc8-pr-cvs1:/tmp/cvs-serv10013 Modified Files: msvccompiler.py Log Message: Pass the preprocessor options also to the resource compiler when compiling .RC files. >From Robin Dunn, fixes SF # 669198. Index: msvccompiler.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/msvccompiler.py,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** msvccompiler.py 19 Nov 2002 13:12:27 -0000 1.52 --- msvccompiler.py 31 Jan 2003 20:40:15 -0000 1.53 *************** *** 311,315 **** output_opt = "/fo" + obj try: ! self.spawn ([self.rc] + [output_opt] + [input_opt]) except DistutilsExecError, msg: --- 311,315 ---- output_opt = "/fo" + obj try: ! self.spawn ([self.rc] + pp_opts + [output_opt] + [input_opt]) except DistutilsExecError, msg: From theller@users.sourceforge.net Fri Jan 31 20:45:46 2003 From: theller@users.sourceforge.net (theller@users.sourceforge.net) Date: Fri, 31 Jan 2003 12:45:46 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.631,1.632 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv13538 Modified Files: NEWS Log Message: Patch #669198: Add cflags to RC compile. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.631 retrieving revision 1.632 diff -C2 -d -r1.631 -r1.632 *** NEWS 28 Jan 2003 19:21:12 -0000 1.631 --- NEWS 31 Jan 2003 20:45:41 -0000 1.632 *************** *** 212,215 **** --- 212,218 ---- ------- + - distutils' msvccompiler class now passes the preprocessor options to + the resource compiler. See SF patch #669198. + - The bsddb module now ships with Sleepycat's 4.1.25.NC, the latest release without strong cryptography. From montanaro@users.sourceforge.net Fri Jan 31 20:50:53 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 31 Jan 2003 12:50:53 -0800 Subject: [Python-checkins] python/nondist/peps pep-0304.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv16430 Modified Files: pep-0304.txt Log Message: update Post-History Index: pep-0304.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0304.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** pep-0304.txt 31 Jan 2003 17:28:11 -0000 1.10 --- pep-0304.txt 31 Jan 2003 20:50:46 -0000 1.11 *************** *** 8,12 **** Content-Type: text/x-rst Created: 22-Jan-2003 ! Post-History: 27-Jan-2003 --- 8,12 ---- Content-Type: text/x-rst Created: 22-Jan-2003 ! Post-History: 27-Jan-2003, 31-Jan-2003 From rhettinger@users.sourceforge.net Fri Jan 31 21:08:09 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:08:09 -0800 Subject: [Python-checkins] python/nondist/sandbox/itertools itertools.c,1.20,1.21 libitertools.tex,1.19,1.20 test_itertools.py,1.12,1.13 todo.txt,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/itertools In directory sc8-pr-cvs1:/tmp/cvs-serv24320 Modified Files: itertools.c libitertools.tex test_itertools.py todo.txt Log Message: Incorporate suggestion from Skip and GvR to have times() take an optional argument. Index: itertools.c =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** itertools.c 31 Jan 2003 20:00:56 -0000 1.20 --- itertools.c 31 Jan 2003 21:08:06 -0000 1.21 *************** *** 820,823 **** --- 820,824 ---- typedef struct { PyObject_HEAD + PyObject *obj; long cnt; } timesobject; *************** *** 829,835 **** { timesobject *lz; long cnt; ! if (!PyArg_ParseTuple(args, "l:times", &cnt)) return NULL; --- 830,837 ---- { timesobject *lz; + PyObject *obj = Py_None; long cnt; ! if (!PyArg_ParseTuple(args, "l|O:times", &cnt, &obj)) return NULL; *************** *** 841,859 **** /* create timesobject structure */ ! lz = (timesobject *)PyObject_New(timesobject, ×_type); if (lz == NULL) return NULL; lz->cnt = cnt; return (PyObject *)lz; } static PyObject * times_next(timesobject *lz) { if (lz->cnt > 0) { lz->cnt--; ! Py_INCREF(Py_None); ! return Py_None; } return NULL; --- 843,873 ---- /* create timesobject structure */ ! lz = (timesobject *)type->tp_alloc(type, 0); if (lz == NULL) return NULL; lz->cnt = cnt; + Py_INCREF(obj); + lz->obj = obj; return (PyObject *)lz; } + static void + times_dealloc(timesobject *lz) + { + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->obj); + lz->ob_type->tp_free(lz); + } + static PyObject * times_next(timesobject *lz) { + PyObject *obj = lz->obj; + if (lz->cnt > 0) { lz->cnt--; ! Py_INCREF(obj); ! return obj; } return NULL; *************** *** 868,875 **** PyDoc_STRVAR(times_doc, ! "times(n) --> times object\n\ \n\ Return a times object whose .next() method returns n consecutive\n\ ! instance of None."); PyTypeObject times_type = { --- 882,889 ---- PyDoc_STRVAR(times_doc, ! "times(n [,obj]) --> times object\n\ \n\ Return a times object whose .next() method returns n consecutive\n\ ! instances of obj (default is None)."); PyTypeObject times_type = { *************** *** 880,884 **** 0, /* tp_itemsize */ /* methods */ ! (destructor)PyObject_Del, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ --- 894,898 ---- 0, /* tp_itemsize */ /* methods */ ! (destructor)times_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ *************** *** 895,899 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ times_doc, /* tp_doc */ 0, /* tp_traverse */ --- 909,914 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | ! Py_TPFLAGS_BASETYPE, /* tp_flags */ times_doc, /* tp_doc */ 0, /* tp_traverse */ *************** *** 914,917 **** --- 929,933 ---- PyType_GenericAlloc, /* tp_alloc */ times_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ }; *************** *** 1453,1457 **** imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\ starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ ! times(n) --> None, None, ... for n times.\n\ takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ --- 1469,1473 ---- imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\ starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ ! times(n, [obj]) --> obj, obj, ... for n times. obj defaults to None\n\ takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ Index: libitertools.tex =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/libitertools.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** libitertools.tex 30 Jan 2003 17:07:59 -0000 1.19 --- libitertools.tex 31 Jan 2003 21:08:07 -0000 1.20 *************** *** 245,258 **** \end{funcdesc} ! \begin{funcdesc}{times}{n} ! Make an iterator that returns None \var{n} times. ! Used for looping a specific number of times without creating a number ! object on each pass. Equivalent to: \begin{verbatim} ! def times(n): ! if n<0: raise ValueError for i in xrange(n): ! yield None \end{verbatim} \end{funcdesc} --- 245,259 ---- \end{funcdesc} ! \begin{funcdesc}{times}{n, \optional{object}} ! Make an iterator that returns \var{object} \var{n} times. ! \var{object} defaults to \code{None}. Used for looping a specific ! number of times without creating a number object on each pass. ! Equivalent to: \begin{verbatim} ! def times(n, object=None): ! if n<0 : raise ValueError for i in xrange(n): ! yield object \end{verbatim} \end{funcdesc} Index: test_itertools.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_itertools.py 31 Jan 2003 08:53:15 -0000 1.12 --- test_itertools.py 31 Jan 2003 21:08:07 -0000 1.13 *************** *** 32,35 **** --- 32,36 ---- def test_times(self): self.assertEqual(list(times(3)), [None]*3) + self.assertEqual(list(times(3, True)), [True]*3) self.assertRaises(ValueError, times, -1) Index: todo.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** todo.txt 31 Jan 2003 07:20:49 -0000 1.15 --- todo.txt 31 Jan 2003 21:08:07 -0000 1.16 *************** *** 1,5 **** - Comments from Skip and Jack: - ? add default arg to times() - Add: iapply(func) ?? what did this do in SML --- 1,2 ---- From montanaro@users.sourceforge.net Fri Jan 31 21:08:53 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:08:53 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv24881 Modified Files: csv.py Log Message: add fieldnames argument to writer.__init__ (don't use it yet) correct the spelling of OCcsv (we're writing a file parser, not a software repository ;-) Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** csv.py 31 Jan 2003 06:25:08 -0000 1.6 --- csv.py 31 Jan 2003 21:08:50 -0000 1.7 *************** *** 27,31 **** pass ! class OCcvs: def __init__(self, dialect, **options): if isinstance(dialect, Dialect): --- 27,31 ---- pass ! class OCcsv: def __init__(self, dialect, **options): if isinstance(dialect, Dialect): *************** *** 47,54 **** raise CSVError(e) ! class reader(OCcvs): def __init__(self, iterobj, dialect = 'excel', **options): self.iterobj = iter(iterobj) ! OCcvs.__init__(self, dialect, **options) def __iter__(self): --- 47,54 ---- raise CSVError(e) ! class reader(OCcsv): def __init__(self, iterobj, dialect = 'excel', **options): self.iterobj = iter(iterobj) ! OCcsv.__init__(self, dialect, **options) def __iter__(self): *************** *** 61,68 **** return fields ! class writer(OCcvs): ! def __init__(self, fileobj, dialect='excel', **options): self.fileobj = fileobj ! OCcvs.__init__(self, dialect, **options) def write(self, fields): --- 61,69 ---- return fields ! class writer(OCcsv): ! def __init__(self, fileobj, dialect='excel', fieldnames=None, **options): self.fileobj = fileobj ! self.fieldnames = fieldnames or [] ! OCcsv.__init__(self, dialect, **options) def write(self, fields): From gvanrossum@users.sourceforge.net Fri Jan 31 21:10:40 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:10:40 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.99,2.100 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv25596 Modified Files: cPickle.c Log Message: Ignore the state returned by __reduce__ if it is Py_None. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.99 retrieving revision 2.100 diff -C2 -d -r2.99 -r2.100 *** cPickle.c 6 Jan 2003 12:41:25 -0000 2.99 --- cPickle.c 31 Jan 2003 21:10:31 -0000 2.100 *************** *** 2087,2090 **** --- 2087,2092 ---- if (size > 2) { state = PyTuple_GET_ITEM(t, 2); + if (state == Py_None) + state = NULL; } From gvanrossum@users.sourceforge.net Fri Jan 31 21:13:23 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:13:23 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv26545 Modified Files: pep-0307.txt Log Message: Security issues. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pep-0307.txt 31 Jan 2003 19:56:32 -0000 1.2 --- pep-0307.txt 31 Jan 2003 21:13:18 -0000 1.3 *************** *** 76,81 **** Python versions had the same effect as passing 1. Nevertheless, a special case is added here: passing a negative number selects the ! highest protocol version supported by a particular ! implementation. This works in previous Python versions, too. --- 76,108 ---- Python versions had the same effect as passing 1. Nevertheless, a special case is added here: passing a negative number selects the ! highest protocol version supported by a particular implementation. ! This works in previous Python versions, too. ! ! ! Security issues ! ! In previous versions of Python, unpickling would do a "safety ! check" on certain operations, refusing to call functions or ! constructors that weren't marked as "safe for unpickling" by ! either having an attribute __safe_for_unpickling__ set to 1, or by ! being registered in a global registry, copy_reg.safe_constructors. ! ! This feature gives a false sense of security: nobody has ever done ! the necessary, extensive, code audit to prove that unpickling ! untrusted pickles cannot invoke unwanted code, and in fact bugs in ! the Python 2.2 pickle.py module make it easy to circumvent these ! security measures. ! ! We firmly believe that, on the Internet, it is better to know that ! you are using an insecure protocol than to trust a protocol to be ! secure whose implementation hasn't been thoroughly checked. Even ! high quality implementations of widely used protocols are ! routinely found flawed; Python's pickle implementation simply ! cannot make such guarantees without a much larger time investment. ! Therefore, as of Python 2.3, all safety checks on unpickling are ! officially removed, and replaced with this warning: ! ! *** Do not unpickle data received from an untrusted or ! unauthenticated source *** From montanaro@users.sourceforge.net Fri Jan 31 21:30:24 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:30:24 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv1195 Modified Files: csv.py Log Message: * export _csv.Error as CSVError from this module instead of defining our own * writer.write: process dict fields Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** csv.py 31 Jan 2003 21:08:50 -0000 1.7 --- csv.py 31 Jan 2003 21:30:20 -0000 1.8 *************** *** 1,3 **** --- 1,4 ---- import _csv + from _csv import Error as CSVError QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC = range(3) *************** *** 24,30 **** } - class CSVError(Exception): - pass - class OCcsv: def __init__(self, dialect, **options): --- 25,28 ---- *************** *** 42,49 **** parser_options[attr] = getattr(dialect_obj, attr) parser_options.update(options) ! try: ! self.parser = _csv.parser(**parser_options) ! except _csv.Error, e: ! raise CSVError(e) class reader(OCcsv): --- 40,44 ---- parser_options[attr] = getattr(dialect_obj, attr) parser_options.update(options) ! self.parser = _csv.parser(**parser_options) class reader(OCcsv): *************** *** 64,71 **** def __init__(self, fileobj, dialect='excel', fieldnames=None, **options): self.fileobj = fileobj ! self.fieldnames = fieldnames or [] OCcsv.__init__(self, dialect, **options) def write(self, fields): self.fileobj.write(self.parser.join(fields) + '\n') --- 59,76 ---- def __init__(self, fileobj, dialect='excel', fieldnames=None, **options): self.fileobj = fileobj ! self.fieldnames = fieldnames OCcsv.__init__(self, dialect, **options) def write(self, fields): + # if fields is a dict, we need a valid fieldnames list + # if self.fieldnames is None we'll get a TypeError in the for stmt + # if fields is not a dict we'll get an AttributeError on .get() + try: + flist = [] + for k in self.fieldnames: + flist.append(fields.get(k, "")) + fields = flist + except (TypeError, AttributeError): + pass self.fileobj.write(self.parser.join(fields) + '\n') From montanaro@users.sourceforge.net Fri Jan 31 21:30:50 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:30:50 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv1386 Modified Files: test_csv.py Log Message: add a couple dict tests Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_csv.py 31 Jan 2003 04:53:49 -0000 1.2 --- test_csv.py 31 Jan 2003 21:30:43 -0000 1.3 *************** *** 112,115 **** --- 112,128 ---- self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\n') + class TestDictFields(unittest.TestCase): + def test_simple_dict(self): + fileobj = StringIO() + writer = csv.writer(fileobj, dialect="excel", + fieldnames = ["f1", "f2", "f3"]) + writer.write({"f1": 10, "f3": "abc"}) + self.assertEqual(fileobj.getvalue(), "10,,abc\n") + + def test_no_fields(self): + fileobj = StringIO() + writer = csv.writer(fileobj, dialect="excel") + self.assertRaises(csv.CSVError, writer.write, {"f1": 10, "f3": "abc"}) + def _testclasses(): mod = sys.modules[__name__] From tim_one@users.sourceforge.net Fri Jan 31 21:45:16 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:45:16 -0800 Subject: [Python-checkins] python/dist/src/Objects longobject.c,1.149,1.150 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv7596/Objects Modified Files: longobject.c Log Message: Squash compiler wng about signed/unsigned comparison mismatch. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.149 retrieving revision 1.150 diff -C2 -d -r1.149 -r1.150 *** longobject.c 31 Jan 2003 15:52:05 -0000 1.149 --- longobject.c 31 Jan 2003 21:45:13 -0000 1.150 *************** *** 288,292 **** result = (ndigits - 1) * SHIFT; ! if (result / SHIFT != ndigits - 1) goto Overflow; do { --- 288,292 ---- result = (ndigits - 1) * SHIFT; ! if (result / SHIFT != (size_t)ndigits - 1) goto Overflow; do { From montanaro@users.sourceforge.net Fri Jan 31 21:49:35 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:49:35 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv9751 Modified Files: pep-0305.txt Log Message: various cleanups expanded Rationale a tad added Post-History date (announcing it in a moment) added pointer to sandbox implementation mentioned implementation in the (massive ;-) Testing section Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pep-0305.txt 30 Jan 2003 13:34:29 -0000 1.7 --- pep-0305.txt 31 Jan 2003 21:49:32 -0000 1.8 *************** *** 12,16 **** Content-Type: text/x-rst Created: 26-Jan-2003 ! Post-History: --- 12,16 ---- Content-Type: text/x-rst Created: 26-Jan-2003 ! Post-History: 31-Jan-2003 *************** *** 25,29 **** PEP defines an API for reading and writing CSV files which should make it possible for programmers to select a CSV module which meets their ! requirements. --- 25,30 ---- PEP defines an API for reading and writing CSV files which should make it possible for programmers to select a CSV module which meets their ! requirements. It is accompanied by a corresponding module which ! implements the API. *************** *** 47,55 **** CSV files: ! - Object Craft's CSV module [1]_ ! - Cliff Wells's Python-DSV module [2]_ ! - Laurence Tratt's ASV module [3]_ Each has a different API, making it somewhat difficult for programmers --- 48,56 ---- CSV files: ! - Object Craft's CSV module [2]_ ! - Cliff Wells' Python-DSV module [3]_ ! - Laurence Tratt's ASV module [4]_ Each has a different API, making it somewhat difficult for programmers *************** *** 70,73 **** --- 71,89 ---- distribution. + CSV formats are not well-defined and different implementations have a + number of subtle corner cases. It has been suggested that the "V" in + the acronym stands for "Vague" instead of "Values". Different + delimiters and quoting characters are just the start. Some programs + generate whitespace after the delimiter. Others quote embedded + quoting characters by doubling them or prefixing them with an escape + character. The list of weird ways to do things seems nearly endless. + + Unfortunately, all this variability and subtlety means it is difficult + for programmers to reliably parse CSV files from many sources or + generate CSV files designed to be fed to specific external programs + without deep knowledge of those sources and programs. This PEP and + the software which accompany it attempt to make the process less + fragile. + Module Interface *************** *** 77,81 **** writing. The basic reading interface is:: ! reader(fileobj [, dialect='excel2000'] [optional keyword args]) A reader object is an iterable which takes a file-like object opened --- 93,98 ---- writing. The basic reading interface is:: ! obj = reader(fileobj [, dialect='excel2000'] ! [optional keyword args]) A reader object is an iterable which takes a file-like object opened *************** *** 92,102 **** The writing interface is similar:: ! writer(fileobj [, dialect='excel2000'], [, fieldnames=list] ! [optional keyword args]) A writer object is a wrapper around a file-like object opened for writing. It accepts the same optional keyword parameters as the reader constructor. In addition, it accepts an optional fieldnames ! argument. This is a list which defines the order of fields in the output file. It allows the write() method to accept mapping objects as well as sequence objects. --- 109,119 ---- The writing interface is similar:: ! obj = writer(fileobj [, dialect='excel2000'], [, fieldnames=seq] ! [optional keyword args]) A writer object is a wrapper around a file-like object opened for writing. It accepts the same optional keyword parameters as the reader constructor. In addition, it accepts an optional fieldnames ! argument. This is a sequence that defines the order of fields in the output file. It allows the write() method to accept mapping objects as well as sequence objects. *************** *** 116,119 **** --- 133,138 ---- csvwriter.write(row) + or arrange for it to be the first row in the iterable being written. + Dialects *************** *** 123,141 **** convenient handle on a group of lower level parameters. ! When dialect is a string it identifies one of the dialect which is known to the module, otherwise it is processed as a dialect class as described below. ! Dialects will generally be named after applications or organizations which define specific sets of format constraints. The initial dialect ! is excel2000, which describes the format constraints of Excel 2000's ! CSV format. Another possible dialect (used here only as an example) ! might be "gnumeric". ! Dialects are implemented as attribute only classes to enable user to ! construct variant dialects by subclassing. The excel2000 dialect is implemented as follows:: ! class excel2000: quotechar = '"' delimiter = ',' --- 142,160 ---- convenient handle on a group of lower level parameters. ! When dialect is a string it identifies one of the dialects which is known to the module, otherwise it is processed as a dialect class as described below. ! Dialects will generally be named after applications or organizations which define specific sets of format constraints. The initial dialect ! is "excel", which describes the format constraints of Excel 97 and ! Excel 2000 regarding CSV input and output. Another possible dialect ! (used here only as an example) might be "gnumeric". ! Dialects are implemented as attribute only classes to enable users to ! construct variant dialects by subclassing. The "excel" dialect is implemented as follows:: ! class excel: quotechar = '"' delimiter = ',' *************** *** 151,161 **** delimiter = '\t' ! Two functions are defined in the API to set and retrieve dialects:: set_dialect(name, dialect) dialect = get_dialect(name) The dialect parameter is a class or instance whose attributes are the ! formatting parameters defined in the next section. --- 170,184 ---- delimiter = '\t' ! Three functions are defined in the API to set, get and list dialects:: set_dialect(name, dialect) dialect = get_dialect(name) + known_dialects = list_dialects() The dialect parameter is a class or instance whose attributes are the ! formatting parameters defined in the next section. The ! list_dialects() function returns all the registered dialect names as ! given in previous set_dialect() calls (both predefined and ! user-defined). *************** *** 168,209 **** for the set_dialect() and get_dialect() module functions. ! - quotechar specifies a one-character string to use as the quoting character. It defaults to '"'. ! - delimiter specifies a one-character string to use as the field separator. It defaults to ','. ! - escapechar specifies a one character string used to escape the delimiter when quotechar is set to None. ! - skipinitialspace specifies how to interpret whitespace which immediately follows a delimiter. It defaults to False, which means ! that whitespace immediate following a delimiter is part of the following field. ! - lineterminator specifies the character sequence which should terminate rows. ! - quoting controls when quotes should be generated by the ! writer. ! "minimal" means only when required, for example, when a field ! contains either the quotechar or the delimiter ! "always" means that quotes are always placed around fields. ! "nonnumeric" means that quotes are always placed around fields ! which contain characters other than [+-0-9.]. ! ... XXX More to come XXX ... When processing a dialect setting and one or more of the other optional parameters, the dialect parameter is processed first, then the others are processed. This makes it easy to choose a dialect, ! then override one or more of the settings. For example, if a CSV file ! was generated by Excel 2000 using single quotes as the quote ! character and TAB as the delimiter, you could create a reader like:: ! csvreader = csv.reader(file("some.csv"), dialect="excel2000", quotechar="'", delimiter='\t') --- 191,235 ---- for the set_dialect() and get_dialect() module functions. ! - ``quotechar`` specifies a one-character string to use as the quoting character. It defaults to '"'. ! - ``delimiter`` specifies a one-character string to use as the field separator. It defaults to ','. ! - ``escapechar`` specifies a one character string used to escape the delimiter when quotechar is set to None. ! - ``skipinitialspace`` specifies how to interpret whitespace which immediately follows a delimiter. It defaults to False, which means ! that whitespace immediately following a delimiter is part of the following field. ! - ``lineterminator`` specifies the character sequence which should terminate rows. ! - ``quoting`` controls when quotes should be generated by the ! writer. It can take on any of the following module constants:: ! csv.QUOTE_MINIMAL means only when required, for example, when a ! field contains either the quotechar or the delimiter ! csv.QUOTE_ALL means that quotes are always placed around fields. ! csv.QUOTE_NONNUMERIC means that quotes are always placed around ! fields which contain characters other than [+-0-9.]. ! - ``doublequote`` (tbd) ! ! - are there more to come? When processing a dialect setting and one or more of the other optional parameters, the dialect parameter is processed first, then the others are processed. This makes it easy to choose a dialect, ! then override one or more of the settings without defining a new ! dialect class. For example, if a CSV file was generated by Excel 2000 ! using single quotes as the quote character and TAB as the delimiter, ! you could create a reader like:: ! csvreader = csv.reader(file("some.csv"), dialect="excel", quotechar="'", delimiter='\t') *************** *** 212,219 **** Testing ======= ! TBD. --- 238,253 ---- + Implementation + ============== + + There is a sample implementation available. [1]_ The goal is for it + to efficiently implement the API described in the PEP. It is heavily + based on the Object Craft csv module. [2]_ + + Testing ======= ! The sample implementation [1]_ includes a set of test cases. *************** *** 284,294 **** ========== ! .. [1] csv module, Object Craft ! (http://www.object-craft.com.au/projects/csv) ! .. [2] Python-DSV module, Wells ! (http://sourceforge.net/projects/python-dsv/) ! .. [3] ASV module, Tratt (http://tratt.net/laurie/python/asv/) --- 318,331 ---- ========== ! .. [1] csv module, Python Sandbox ! (http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/python/nondist/sandbox/csv/) ! .. [2] csv module, Object Craft ! (http://www.object-craft.com.au/projects/csv) ! .. [3] Python-DSV module, Wells ! (http://sourceforge.net/projects/python-dsv/) ! ! .. [4] ASV module, Tratt (http://tratt.net/laurie/python/asv/) From tim_one@users.sourceforge.net Fri Jan 31 21:52:17 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:52:17 -0800 Subject: [Python-checkins] python/nondist/sandbox/datetime datetime.py,1.155,1.156 test_datetime.py,1.108,1.109 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv10623 Modified Files: datetime.py test_datetime.py Log Message: __setstate__() no longer needs to be public, and shoudn't be public because all datetime objects are immutable. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.155 retrieving revision 1.156 diff -C2 -d -r1.155 -r1.156 *** datetime.py 30 Jan 2003 22:01:30 -0000 1.155 --- datetime.py 31 Jan 2003 21:52:15 -0000 1.156 *************** *** 618,624 **** return (self.__days, self.__seconds, self.__microseconds) - def __setstate__(self, tup): - self.__days, self.__seconds, self.__microseconds = tup - def __reduce__(self): return (self.__class__, self.__getstate__()) --- 618,621 ---- *************** *** 668,672 **** # Pickle support self = object.__new__(cls) ! self.__setstate__((year,)) return self _check_date_fields(year, month, day) --- 665,669 ---- # Pickle support self = object.__new__(cls) ! self.__setstate((year,)) return self _check_date_fields(year, month, day) *************** *** 860,864 **** return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) ! def __setstate__(self, t): assert isinstance(t, tuple) and len(t) == 1, `t` string = t[0] --- 857,861 ---- return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) ! def __setstate(self, t): assert isinstance(t, tuple) and len(t) == 1, `t` string = t[0] *************** *** 986,990 **** if isinstance(hour, str): # Pickle support ! self.__setstate__((hour, minute or None)) return self _check_tzinfo_arg(tzinfo) --- 983,987 ---- if isinstance(hour, str): # Pickle support ! self.__setstate((hour, minute or None)) return self _check_tzinfo_arg(tzinfo) *************** *** 1190,1199 **** return (basestate, self._tzinfo) ! def __setstate__(self, state): ! if not isinstance(state, tuple): ! raise TypeError("time.__setstate__() requires a tuple arg") ! if not 1 <= len(state) <= 2: ! raise TypeError("time.__setstate__() requires a 1-tuple or " ! "2-tuple argument") string = state[0] assert len(string) == 6 --- 1187,1193 ---- return (basestate, self._tzinfo) ! def __setstate(self, state): ! assert isinstance(state, tuple) ! assert 1 <= len(state) <= 2 string = state[0] assert len(string) == 6 *************** *** 1225,1229 **** # Pickle support self = date.__new__(cls, 1, 1, 1) ! self.__setstate__((year, month)) return self _check_tzinfo_arg(tzinfo) --- 1219,1223 ---- # Pickle support self = date.__new__(cls, 1, 1, 1) ! self.__setstate((year, month)) return self _check_tzinfo_arg(tzinfo) *************** *** 1588,1597 **** return (basestate, self._tzinfo) ! def __setstate__(self, state): ! if not isinstance(state, tuple): ! raise TypeError("datetime.__setstate__() requires a tuple arg") ! if not 1 <= len(state) <= 2: ! raise TypeError("datetime.__setstate__() requires a 1-tuple or " ! "2-tuple argument") string = state[0] assert len(string) == 10 --- 1582,1588 ---- return (basestate, self._tzinfo) ! def __setstate(self, state): ! assert isinstance(state, tuple) ! assert 1 <= len(state) <= 2 string = state[0] assert len(string) == 10 Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.108 retrieving revision 1.109 diff -C2 -d -r1.108 -r1.109 *** test_datetime.py 30 Jan 2003 22:01:39 -0000 1.108 --- test_datetime.py 31 Jan 2003 21:52:15 -0000 1.109 *************** *** 279,289 **** state = orig.__getstate__() self.assertEqual(args, state) - derived = timedelta() - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_compare(self): --- 279,286 ---- state = orig.__getstate__() self.assertEqual(args, state) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_compare(self): *************** *** 836,846 **** state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass) - derived = self.theclass(1, 1, 1) - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_compare(self): --- 833,840 ---- state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_compare(self): *************** *** 1193,1203 **** state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) - derived = self.theclass(1, 1, 1) - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_more_compare(self): --- 1187,1194 ---- state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_more_compare(self): *************** *** 1577,1587 **** state = orig.__getstate__() self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) - derived = self.theclass() - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_bool(self): --- 1568,1575 ---- state = orig.__getstate__() self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_bool(self): *************** *** 1890,1920 **** state = orig.__getstate__() self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) - derived = self.theclass() - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) # Try one with a tzinfo. tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(5, 6, 7, tzinfo=tinfo) - state = orig.__getstate__() - derived = self.theclass(tzinfo=FixedOffset(0, "UTC", 0)) - derived.__setstate__(state) - self.assertEqual(orig, derived) - self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) - self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) - self.assertEqual(derived.tzname(), 'cookie') - for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, ! PicklableFixedOffset)) ! self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) ! self.assertEqual(derived.tzname(), 'cookie') def test_more_bool(self): --- 1878,1896 ---- state = orig.__getstate__() self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) # Try one with a tzinfo. tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(5, 6, 7, tzinfo=tinfo) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) ! self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) ! self.assertEqual(derived.tzname(), 'cookie') def test_more_bool(self): *************** *** 2105,2135 **** state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) - derived = self.theclass(1, 1, 1) - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) # Try one with a tzinfo. tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(*args, **{'tzinfo': tinfo}) - state = orig.__getstate__() derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0)) - derived.__setstate__(state) - self.assertEqual(orig, derived) - self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) - self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) - self.assertEqual(derived.tzname(), 'cookie') - for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, ! PicklableFixedOffset)) ! self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) ! self.assertEqual(derived.tzname(), 'cookie') def test_extreme_hashes(self): --- 2081,2101 ---- state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) # Try one with a tzinfo. tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(*args, **{'tzinfo': tinfo}) derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, ! PicklableFixedOffset)) ! self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) ! self.assertEqual(derived.tzname(), 'cookie') def test_extreme_hashes(self): From gvanrossum@users.sourceforge.net Fri Jan 31 21:58:36 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:58:36 -0800 Subject: [Python-checkins] python/nondist/peps pep-0307.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv13121 Modified Files: pep-0307.txt Log Message: Document extended __reduce__ API. Index: pep-0307.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0307.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pep-0307.txt 31 Jan 2003 21:13:18 -0000 1.3 --- pep-0307.txt 31 Jan 2003 21:58:34 -0000 1.4 *************** *** 107,110 **** --- 107,188 ---- + Extended __reduce__ API + + There are several APIs that a class can use to control pickling. + Perhaps the most popular of these are __getstate__ and + __setstate__; but the most powerful one is __reduce__. (There's + also __getinitargs__, and we're adding __getnewargs__ below.) + + There are two ways to provide __reduce__ functionality: a class + can implement a __reduce__ method, or a reduce function can be + declared in copy_reg (copy_reg.dispatch_table maps classes to + functions). The return values are interpreted exactly the same, + though, and we'll refer to these collectively as __reduce__. + + __reduce__ must return either a string or a tuple. If it returns + a string, this is an object whose state is not to be pickled, but + instead a reference to an equivalent object referenced by name. + Surprisingly, the string returned by __reduce__ should be the + object's local name (relative to its module); the pickle module + searches the module namespace to determine the object's module. + + The rest of this section is concerned with the tuple returned by + __reduce__. It is a variable length tuple. Only the first two + items (function and arguments) are required. The remaining items + may be None or left off from the end. The last two items are new + in this PEP. The items are, in order: + + function A callable object (not necessarily a function) called + to create the initial version of the object; state may + be added to the object later to fully reconstruct the + pickled state. This function must itself be + picklable. + + arguments A tuple giving the argument list for the function. + As a special case, designed for Zope 2's + ExtensionClass, this may be None; in that case, + function should be a class or type, and + function.__basicnew__() is called to create the + initial version of the object. This exception is + deprecated. + + state Additional state. If this is not None, the state is + pickled, and obj.__setstate__(state) will called when + unpickling. If no __setstate__ method is defined, a + default implementation is provided, which assumes + that state is a dictionary mapping instance variable + names to their values, and calls + obj.__dict__.update(state) or "for k, v in + state.items(): obj[k] = v", if update() call fails. + + listitems New in this PEP. If this is not None, it should be + an iterator (not a sequence!) yielding successive + list items. These list items will be pickled, and + appended to the object using either obj.append(item) + or obj.extend(list_of_items). This is primarily used + for list subclasses, but may be used by other classes + as long as they have append() and extend() methods + with the appropriate signature. (Whether append() or + extend() is used depend on which pickle protocol + version is used as well as the number of items to + append, so both must be supported.) + + dictitems New in this PEP. If this is not None, it should be + an iterator (not a sequence!) yielding successive + dictionary items, which should be tuples of the form + (key, value). These items will be pickled, and + stored to the object using obj[key] = value. This is + primarily used for dict subclasses, but may be used + by other classes as long as they implement + __settitem__. + + Note: in Python 2.2 and before, when using cPickle, state would be + pickled if present even if it is None; the only safe way to avoid + the __setstate__ call was to return a two-tuple from __reduce__. + (But pickle.py would not pickle state if it was None.) In Python + 2.3, __setstate__ will never be called when __reduce__ returns a + state with value None. + + Copyright From montanaro@users.sourceforge.net Fri Jan 31 21:55:42 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:55:42 -0800 Subject: [Python-checkins] python/nondist/peps pep-0305.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv12075 Modified Files: pep-0305.txt Log Message: remove authors' emails, add Discussion-To: to try and encourage feedback to go to the mailing list. Index: pep-0305.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0305.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pep-0305.txt 31 Jan 2003 21:49:32 -0000 1.8 --- pep-0305.txt 31 Jan 2003 21:55:38 -0000 1.9 *************** *** 3,11 **** Version: $Revision$ Last-Modified: $Date$ ! Author: Skip Montanaro , ! Kevin Altis , ! Cliff Wells , ! Dave Cole , ! Andrew McNamara Status: Draft Type: Standards Track --- 3,8 ---- Version: $Revision$ Last-Modified: $Date$ ! Author: Kevin Altis, Dave Cole, Andrew McNamara, Skip Montanaro, Cliff Wells ! Discussions-To: Status: Draft Type: Standards Track From tim_one@users.sourceforge.net Fri Jan 31 21:55:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 13:55:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_datetime.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv11764/Lib/test Modified Files: test_datetime.py Log Message: Changed the tests to stop using __setstate__(). __setstate__() no longer needs to be public, and shoudn't be public because all datetime objects are immutable. The Python implementation has changed accordingly, but still need to change the C implementation. Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_datetime.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** test_datetime.py 30 Jan 2003 22:06:23 -0000 1.31 --- test_datetime.py 31 Jan 2003 21:55:33 -0000 1.32 *************** *** 281,291 **** state = orig.__getstate__() self.assertEqual(args, state) - derived = timedelta() - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_compare(self): --- 281,288 ---- state = orig.__getstate__() self.assertEqual(args, state) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_compare(self): *************** *** 838,848 **** state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass) - derived = self.theclass(1, 1, 1) - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_compare(self): --- 835,842 ---- state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_compare(self): *************** *** 1195,1205 **** state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) - derived = self.theclass(1, 1, 1) - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_more_compare(self): --- 1189,1196 ---- state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_more_compare(self): *************** *** 1579,1589 **** state = orig.__getstate__() self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) - derived = self.theclass() - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_bool(self): --- 1570,1577 ---- state = orig.__getstate__() self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) def test_bool(self): *************** *** 1892,1922 **** state = orig.__getstate__() self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) - derived = self.theclass() - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) # Try one with a tzinfo. tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(5, 6, 7, tzinfo=tinfo) - state = orig.__getstate__() - derived = self.theclass(tzinfo=FixedOffset(0, "UTC", 0)) - derived.__setstate__(state) - self.assertEqual(orig, derived) - self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) - self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) - self.assertEqual(derived.tzname(), 'cookie') - for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, ! PicklableFixedOffset)) ! self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) ! self.assertEqual(derived.tzname(), 'cookie') def test_more_bool(self): --- 1880,1898 ---- state = orig.__getstate__() self.assertEqual(state, ('\x14\x3b\x10\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) # Try one with a tzinfo. tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(5, 6, 7, tzinfo=tinfo) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) ! self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) ! self.assertEqual(derived.tzname(), 'cookie') def test_more_bool(self): *************** *** 2107,2137 **** state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) - derived = self.theclass(1, 1, 1) - derived.__setstate__(state) - self.assertEqual(orig, derived) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) # Try one with a tzinfo. tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(*args, **{'tzinfo': tinfo}) - state = orig.__getstate__() derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0)) - derived.__setstate__(state) - self.assertEqual(orig, derived) - self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) - self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) - self.assertEqual(derived.tzname(), 'cookie') - for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, ! PicklableFixedOffset)) ! self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) ! self.assertEqual(derived.tzname(), 'cookie') def test_extreme_hashes(self): --- 2083,2103 ---- state = orig.__getstate__() self.assertEqual(state, ('\x00\x06\x07\x17\x14\x3b\x01\x00\x10\x00',)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) # Try one with a tzinfo. tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(*args, **{'tzinfo': tinfo}) derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0)) for pickler, unpickler, proto in pickle_choices: ! green = pickler.dumps(orig, proto) ! derived = unpickler.loads(green) ! self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, ! PicklableFixedOffset)) ! self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) ! self.assertEqual(derived.tzname(), 'cookie') def test_extreme_hashes(self): From tim_one@users.sourceforge.net Fri Jan 31 22:27:19 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 14:27:19 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.632,1.633 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv23124/Misc Modified Files: NEWS Log Message: The various datetime object __setstate__() methods are no longer public (pickling no longer needs them, and immutable objects shouldn't have visible __setstate__() methods regardless). Rearranged the code to put the internal setstate functions in the constructor sections. Repaired the timedelta reduce() method, which was still producing stuff that required a public timedelta.__setstate__() when unpickling. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.632 retrieving revision 1.633 diff -C2 -d -r1.632 -r1.633 *** NEWS 31 Jan 2003 20:45:41 -0000 1.632 --- NEWS 31 Jan 2003 22:27:15 -0000 1.633 *************** *** 25,29 **** - Fixed an invalid RuntimeWarning and an undetected error when trying ! to convert a long integer into a float which couldn't fit. See SF bug #676155. --- 25,29 ---- - Fixed an invalid RuntimeWarning and an undetected error when trying ! to convert a long integer into a float which couldn't fit. See SF bug #676155. *************** *** 126,129 **** --- 126,134 ---- possible to have timestamps that differ by a second, yet where datetimes constructed from them are equal. + + The pickle format of date, time and datetime objects has changed + completely. The undocumented pickler and unpickler functions no + longer exist. The undocumented __setstate__() methods no longer + exist either. Library From tim_one@users.sourceforge.net Fri Jan 31 22:27:20 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 31 Jan 2003 14:27:20 -0800 Subject: [Python-checkins] python/dist/src/Modules datetimemodule.c,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv23124/Modules Modified Files: datetimemodule.c Log Message: The various datetime object __setstate__() methods are no longer public (pickling no longer needs them, and immutable objects shouldn't have visible __setstate__() methods regardless). Rearranged the code to put the internal setstate functions in the constructor sections. Repaired the timedelta reduce() method, which was still producing stuff that required a public timedelta.__setstate__() when unpickling. Index: datetimemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** datetimemodule.c 31 Jan 2003 01:37:35 -0000 1.50 --- datetimemodule.c 31 Jan 2003 22:27:17 -0000 1.51 *************** *** 1960,1963 **** --- 1960,1964 ---- } + /* __setstate__ isn't exposed. */ static PyObject * delta_setstate(PyDateTime_Delta *self, PyObject *state) *************** *** 1989,1993 **** * tuple as the 2nd component of the result 3-tuple. */ ! result = Py_BuildValue("O()O", self->ob_type, state); Py_DECREF(state); } --- 1990,1998 ---- * tuple as the 2nd component of the result 3-tuple. */ ! result = Py_BuildValue("O(iii)", ! self->ob_type, ! self->days, ! self->seconds, ! self->microseconds); Py_DECREF(state); } *************** *** 2011,2018 **** static PyMethodDef delta_methods[] = { - - {"__setstate__", (PyCFunction)delta_setstate, METH_O, - PyDoc_STR("__setstate__(state)")}, - {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS, PyDoc_STR("__getstate__() -> state")}, --- 2016,2019 ---- *************** *** 2146,2150 **** static char *date_kws[] = {"year", "month", "day", NULL}; ! static PyObject *date_setstate(PyDateTime_Date *self, PyObject *arg); static PyObject * --- 2147,2179 ---- static char *date_kws[] = {"year", "month", "day", NULL}; ! /* __setstate__ isn't exposed. */ ! static PyObject * ! date_setstate(PyDateTime_Date *self, PyObject *arg) ! { ! PyObject *state; ! int len; ! unsigned char *pdata; ! ! if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1) ! goto error; ! state = PyTuple_GET_ITEM(arg, 0); ! if (!PyString_Check(state)) ! goto error; ! ! len = PyString_Size(state); ! if (len != _PyDateTime_DATE_DATASIZE) ! goto error; ! ! pdata = (unsigned char*)PyString_AsString(state); ! memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE); ! self->hashcode = -1; ! ! Py_INCREF(Py_None); ! return Py_None; ! error: ! PyErr_SetString(PyExc_TypeError, ! "bad argument to date.__setstate__"); ! return NULL; ! } static PyObject * *************** *** 2543,2575 **** static PyObject * - date_setstate(PyDateTime_Date *self, PyObject *arg) - { - PyObject *state; - int len; - unsigned char *pdata; - - if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1) - goto error; - state = PyTuple_GET_ITEM(arg, 0); - if (!PyString_Check(state)) - goto error; - - len = PyString_Size(state); - if (len != _PyDateTime_DATE_DATASIZE) - goto error; - - pdata = (unsigned char*)PyString_AsString(state); - memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE); - self->hashcode = -1; - - Py_INCREF(Py_None); - return Py_None; - error: - PyErr_SetString(PyExc_TypeError, - "bad argument to date.__setstate__"); - return NULL; - } - - static PyObject * date_reduce(PyDateTime_Date *self, PyObject *arg) { --- 2572,2575 ---- *************** *** 2628,2634 **** PyDoc_STR("Return date with new specified fields.")}, - {"__setstate__", (PyCFunction)date_setstate, METH_O, - PyDoc_STR("__setstate__(state)")}, - {"__getstate__", (PyCFunction)date_getstate, METH_NOARGS, PyDoc_STR("__getstate__() -> state")}, --- 2628,2631 ---- *************** *** 3013,3017 **** "tzinfo", NULL}; ! static PyObject *time_setstate(PyDateTime_Time *self, PyObject *state); static PyObject * --- 3010,3048 ---- "tzinfo", NULL}; ! /* __setstate__ isn't exposed. */ ! static PyObject * ! time_setstate(PyDateTime_Time *self, PyObject *state) ! { ! PyObject *basestate; ! PyObject *tzinfo = Py_None; ! ! if (! PyArg_ParseTuple(state, "O!|O:__setstate__", ! &PyString_Type, &basestate, ! &tzinfo)) ! return NULL; ! if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE || ! check_tzinfo_subclass(tzinfo) < 0) { ! PyErr_SetString(PyExc_TypeError, ! "bad argument to time.__setstate__"); ! return NULL; ! } ! if (tzinfo != Py_None && ! HASTZINFO(self)) { ! PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't " ! "add a non-None tzinfo to a time object that " ! "doesn't have one already"); ! return NULL; ! } ! memcpy((char *)self->data, ! PyString_AsString(basestate), ! _PyDateTime_TIME_DATASIZE); ! self->hashcode = -1; ! if (HASTZINFO(self)) { ! Py_INCREF(tzinfo); ! Py_XDECREF(self->tzinfo); ! self->tzinfo = tzinfo; ! } ! Py_INCREF(Py_None); ! return Py_None; ! } static PyObject * *************** *** 3368,3406 **** static PyObject * - time_setstate(PyDateTime_Time *self, PyObject *state) - { - PyObject *basestate; - PyObject *tzinfo = Py_None; - - if (! PyArg_ParseTuple(state, "O!|O:__setstate__", - &PyString_Type, &basestate, - &tzinfo)) - return NULL; - if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE || - check_tzinfo_subclass(tzinfo) < 0) { - PyErr_SetString(PyExc_TypeError, - "bad argument to time.__setstate__"); - return NULL; - } - if (tzinfo != Py_None && ! HASTZINFO(self)) { - PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't " - "add a non-None tzinfo to a time object that " - "doesn't have one already"); - return NULL; - } - memcpy((char *)self->data, - PyString_AsString(basestate), - _PyDateTime_TIME_DATASIZE); - self->hashcode = -1; - if (HASTZINFO(self)) { - Py_INCREF(tzinfo); - Py_XDECREF(self->tzinfo); - self->tzinfo = tzinfo; - } - Py_INCREF(Py_None); - return Py_None; - } - - static PyObject * time_reduce(PyDateTime_Time *self, PyObject *arg) { --- 3399,3402 ---- *************** *** 3429,3435 **** PyDoc_STR("Return time with new specified fields.")}, - {"__setstate__", (PyCFunction)time_setstate, METH_O, - PyDoc_STR("__setstate__(state)")}, - {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS, PyDoc_STR("__getstate__() -> state")}, --- 3425,3428 ---- *************** *** 3560,3564 **** }; ! static PyObject *datetime_setstate(PyDateTime_DateTime *self, PyObject *state); static PyObject * --- 3553,3591 ---- }; ! /* __setstate__ isn't exposed. */ ! static PyObject * ! datetime_setstate(PyDateTime_DateTime *self, PyObject *state) ! { ! PyObject *basestate; ! PyObject *tzinfo = Py_None; ! ! if (! PyArg_ParseTuple(state, "O!|O:__setstate__", ! &PyString_Type, &basestate, ! &tzinfo)) ! return NULL; ! if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE || ! check_tzinfo_subclass(tzinfo) < 0) { ! PyErr_SetString(PyExc_TypeError, ! "bad argument to datetime.__setstate__"); ! return NULL; ! } ! if (tzinfo != Py_None && ! HASTZINFO(self)) { ! PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ " ! "can't add a non-None tzinfo to a datetime " ! "object that doesn't have one already"); ! return NULL; ! } ! memcpy((char *)self->data, ! PyString_AsString(basestate), ! _PyDateTime_DATETIME_DATASIZE); ! self->hashcode = -1; ! if (HASTZINFO(self)) { ! Py_INCREF(tzinfo); ! Py_XDECREF(self->tzinfo); ! self->tzinfo = tzinfo; ! } ! Py_INCREF(Py_None); ! return Py_None; ! } static PyObject * *************** *** 4372,4410 **** static PyObject * - datetime_setstate(PyDateTime_DateTime *self, PyObject *state) - { - PyObject *basestate; - PyObject *tzinfo = Py_None; - - if (! PyArg_ParseTuple(state, "O!|O:__setstate__", - &PyString_Type, &basestate, - &tzinfo)) - return NULL; - if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE || - check_tzinfo_subclass(tzinfo) < 0) { - PyErr_SetString(PyExc_TypeError, - "bad argument to datetime.__setstate__"); - return NULL; - } - if (tzinfo != Py_None && ! HASTZINFO(self)) { - PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ " - "can't add a non-None tzinfo to a datetime " - "object that doesn't have one already"); - return NULL; - } - memcpy((char *)self->data, - PyString_AsString(basestate), - _PyDateTime_DATETIME_DATASIZE); - self->hashcode = -1; - if (HASTZINFO(self)) { - Py_INCREF(tzinfo); - Py_XDECREF(self->tzinfo); - self->tzinfo = tzinfo; - } - Py_INCREF(Py_None); - return Py_None; - } - - static PyObject * datetime_reduce(PyDateTime_DateTime *self, PyObject *arg) { --- 4399,4402 ---- *************** *** 4477,4483 **** {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS, PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, - - {"__setstate__", (PyCFunction)datetime_setstate, METH_O, - PyDoc_STR("__setstate__(state)")}, {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS, --- 4469,4472 ----